Zum Inhalt

Arduino / ESP32

Der WattWächter TTL ist ein reiner IR-Lesekopf: Er gibt den Datenstrom deines Zählers 1:1 als TTL-Seriensignal aus. Auf einem Mikrocontroller wie dem ESP32 musst du diesen Datenstrom nur an einer UART-Schnittstelle einlesen und auswerten.

Die meisten modernen Zähler (eHZ, Smart Meter Gateway) senden ihre Daten im SML-Format (Smart Message Language) mit 9600 Baud, 8N1. Für diese Anleitung verwenden wir die fertige Bibliothek SML-Parser, die den Datenstrom byteweise dekodiert und die CRC-Prüfsumme automatisch kontrolliert.

So funktioniert die Kommunikation

Die meisten Zähler senden ihr Telegramm von sich aus zyklisch (Push) – bei ihnen genügt zum Auslesen die Empfangsleitung (grün / RXD). Die gelbe TX-Leitung ist nur für die übrigen Zähler nötig, die erst per Befehl zum Senden aufgefordert werden müssen.

Voraussetzungen am Zähler

Damit der Zähler die vollständigen Momentanwerte (Leistung, Phasen) sendet, muss am Zähler meist die PIN deaktiviert und der erweiterte Infomodus (Inf → On) aktiviert sein. Die PIN erhältst du bei deinem Netzbetreiber.


Verkabelung

Die vier Adern des WattWächter TTL werden 1:1 mit dem ESP32 verbunden (die Kreuzung von RX/TX erfolgt bereits auf der Platine des Lesekopfs).

Kabel (TTL) Funktion ESP32-Pin
Braun VCC (3–5 V) 3V3
Grün RXD (Daten) GPIO16 (RX2)
Gelb TXD GPIO17 (TX2) — optional
Weiß GND GND

Verkabelung WattWächter TTL an ESP32

Die Adernfarben sind im Schaltbild dargestellt: braun → VCC, grün → RXD, gelb → TXD (gestrichelt = optional), weiß → GND.

ESP8266 / D1 Mini

Auf dem ESP8266 ist nur eine vollwertige Hardware-UART vorhanden, die mit dem USB-Seriell-Wandler geteilt wird. Lies die Zählerdaten dort über Serial (RX = GPIO3) ein und gib Debug-Ausgaben über Serial1 (TX = GPIO2) aus. SoftwareSerial ist bei 9600 Baud meist zu langsam und führt zu Empfangsfehlern.


Variante A — Arduino-Sketch (SML-Parser)

Diese Variante liest die wichtigsten Werte direkt im Arduino-Framework aus – ideal als Baustein für eigene Projekte.

Bibliothek installieren

Werkzeuge → Bibliotheken verwalten… öffnen und nach SML-Parser (von olliiiver) suchen und installieren.

In der platformio.ini:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    olliiiver/SML Parser@^0.29

Sketch

#include <Arduino.h>
#include "sml.h"   // Bibliothek "SML-Parser" von olliiiver

// --- UART zum WattWächter TTL ----------------------------------------------
// ESP32 Hardware-UART2: RX2 = GPIO16, TX2 = GPIO17
#define TTL_RX_PIN 16   // -> grünes Kabel (RXD) des WattWächter TTL
#define TTL_TX_PIN 17   // -> gelbes Kabel (TXD), nur für anfragende Zähler nötig
#define TTL_BAUD   9600

HardwareSerial MeterSerial(2);  // UART2

// --- Werte, die wir aus jedem SML-Telegramm lesen wollen -------------------
double importWh = -1;   // 1-0:1.8.0   Bezug aus dem Netz        (Wh)
double exportWh = -1;   // 1-0:2.8.0   Einspeisung ins Netz      (Wh)
double powerW   = -1;   // 1-0:16.7.0  aktuelle Wirkleistung     (W)

void handleImport() { smlOBISWh(importWh); }
void handleExport() { smlOBISWh(exportWh); }
void handlePower()  { smlOBISW(powerW); }

// OBIS-Code (6 Byte) -> zugehörige Auswertefunktion
typedef struct {
  const unsigned char OBIS[6];
  void (*Handler)();
} OBISHandler;

OBISHandler handlers[] = {
  {{ 0x01, 0x00, 0x01, 0x08, 0x00, 0xff }, &handleImport}, // 1-0:1.8.0   Bezug (Wh)
  {{ 0x01, 0x00, 0x02, 0x08, 0x00, 0xff }, &handleExport}, // 1-0:2.8.0   Einspeisung (Wh)
  {{ 0x01, 0x00, 0x10, 0x07, 0x00, 0xff }, &handlePower},  // 1-0:16.7.0  Wirkleistung (W, vorzeichenbehaftet)
  {{ 0x01, 0x00, 0x0f, 0x07, 0x00, 0xff }, &handlePower},  // 1-0:15.7.0  Wirkleistung (Betrag) – Fallback
  {{ 0, 0 }}
};

void setup() {
  Serial.begin(115200);
  MeterSerial.begin(TTL_BAUD, SERIAL_8N1, TTL_RX_PIN, TTL_TX_PIN);
  Serial.println(F("WattWaechter TTL Reader gestartet"));
}

void loop() {
  while (MeterSerial.available() > 0) {
    unsigned char c = MeterSerial.read();
    sml_states_t state = smlState(c);

    // Eine Liste innerhalb des Telegramms wurde fertig gelesen:
    // Prüfen, ob sie einen der gesuchten OBIS-Werte enthält.
    if (state == SML_LISTEND) {
      for (uint8_t i = 0; handlers[i].Handler != 0; i++) {
        if (smlOBISCheck(handlers[i].OBIS)) {
          handlers[i].Handler();
          break;
        }
      }
    }

    // Vollständiges Telegramm empfangen und CRC geprüft -> Werte ausgeben.
    if (state == SML_FINAL) {
      Serial.printf("Bezug:        %.3f kWh\n", importWh / 1000.0);
      Serial.printf("Einspeisung:  %.3f kWh\n", exportWh / 1000.0);
      Serial.printf("Leistung:     %.0f W\n\n", powerW);
    }
  }
}

Weitere Werte auslesen

Ergänze die handlers-Tabelle einfach um weitere OBIS-Codes. Die Konvenienzfunktionen smlOBISW() (Watt), smlOBISVolt(), smlOBISAmpere() und smlOBISHertz() liefern den Wert bereits korrekt skaliert. Beispiele für gängige OBIS-Codes findest du unter Weitere OBIS-Kennzahlen.


Variante B — ESPHome (empfohlen für Home Assistant)

Wenn der ESP32 ohnehin in Home Assistant eingebunden werden soll, ist ESPHome der schnellste Weg: Die SML-Auswertung ist als Komponente bereits integriert, du musst keinen Code schreiben.

uart:
  id: uart_meter
  rx_pin: GPIO16          # grünes Kabel (RXD) des WattWächter TTL
  baud_rate: 9600
  data_bits: 8
  parity: NONE
  stop_bits: 1

sml:
  id: meter_sml
  uart_id: uart_meter

sensor:
  - platform: sml
    name: "Bezug gesamt"
    sml_id: meter_sml
    obis_code: "1-0:1.8.0"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.0001   # Skalierung je nach Zähler anpassen (siehe Logs)
  - platform: sml
    name: "Einspeisung gesamt"
    sml_id: meter_sml
    obis_code: "1-0:2.8.0"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.0001
  - platform: sml
    name: "Aktuelle Leistung"
    sml_id: meter_sml
    obis_code: "1-0:16.7.0"
    unit_of_measurement: W
    accuracy_decimals: 0
    device_class: power
    state_class: measurement

Skalierungsfaktor prüfen

Die ESPHome-sml-Komponente liefert den Rohwert des Telegramms. Der nötige multiply-Faktor hängt vom Zähler ab. Aktiviere kurzzeitig logger: level: VERY_VERBOSE, vergleiche den ausgegebenen Wert mit der Anzeige am Zähler und passe den Faktor an.


Fehlerbehebung

Problem Mögliche Ursache / Lösung
Keine Daten empfangen Lesekopf nicht korrekt über der IR-Diode positioniert; grünes Kabel (RXD) nicht an den RX-Pin angeschlossen
Nur Energiezähler, keine Leistung/Phasen Am Zähler PIN deaktivieren und Inf → On setzen
Checksum error / Unexpected byte Falsche Baudrate/Parität – 9600 8N1 prüfen; bei ESP8266 Hardware-UART statt SoftwareSerial verwenden
Werte um Faktor 10/100 falsch Skalierung (Scaler) nicht berücksichtigt – bei ESPHome multiply anpassen