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 |
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 |