Open Energy Monitor mit dem ESP32
Inhaltsverzeichnis
Einleitung
In dieser Anleitung wird beschrieben wie mit Hilfe einer ESP32 Platine ein Strom Sensor für 3 Phasen Wechselstrom aufgebaut werden kann. Der Spannungsteiler aus den 10kOhm Widerständen erzeugt 1,6V für die SCT-013-030 Strom Sensoren. Die Stromsensoren werden mit den ADC Pin's des ESP32 verbunden. Natürlich sind die Messungen nicht sonderlich genau, da die Phasenverschiebung und Spannung nicht berücksichtigt wird. Auch das wäre durch zusätzliche Transformatoren möglich die dann auf die ADC Pin's geführt werden. Da ich damit nur meinen ungefähren Stromverbrauch zuhause messen möchte ist die Schaltung völlig ausreichend. Die Kosten für die einzelnen Komponenten sollten 30€ nicht übersteigen.
Folgende Bauteile werden benötigt:
-Board: DOIT ESP32 DEVKIT V1 (ca. 10€) -Strom Sensor SCT-013-30 (30A) oder SCT-013-100 (100A) siehe: http://openenergymonitor.org/emon/node/156 -6x 10kOhm Widerstände 1/4W -3x Elko 10 uF -Universalplatine -evtl. USB Netzteil oder anderes Netzteil für die Spannungsversorgung -Pfosten Stecker Rastermaß: 2.54mm -3 x 3,5 mm Audio Anschluss -Optional: 1000uF / 10V Kondensator zur Stabilisierung
Pinbelegung des DOIT ESP32 DEVKIT V1 Board:
https://github.com/playelek/pinout-doit-32devkitv1
Grundlagen
Auf der Seite von Open Energy Monitor finden sich genügend Informationen über die Grundlagen der Leistungsberechnung. Das Prinzip lässt sich 1:1 vom Aufbau eines Arduinos übernehmen. Der ESP32 verkraftet jedoch maximal 3,3V am Analog Eingang.
https://learn.openenergymonitor.org/electricity-monitoring/ct-sensors/interface-with-arduino
Aufbau
Auf die Lochrasterplatine müssen nur wenige Bauteile. Die Teile lassen sich relativ einfach einlöten. Für den Aufbau werden nur wenige PIN's des ESP32 benötigt. Bei meinem Aufbau gibt es am obersten Sensor Anschluss noch einen zusätzlichen Burden Widerstand von 200 Ohm. Das liegt daran das der SCT-013-030 Sensor schon einige Jahre alt ist. Bei den neuen Sensoren sind keine Burden Widerstände nötig, da diese schon einen 62 Ohm Burden eingebaut haben. Ein 1000uF Kondensator zwischen 5V und GND ist empfehlenswert, da je nach 5V Netzteil die Messwerte stark schwanken.
Software
Ich verwende zum programmieren immer die Arduino Gui. Es sind zuerst einige Anpassungen nötig damit das DOIT ESP32 Board von der Arduino Software erkannt wird. Hierzu muss diese Anleitung umgesetzt werden:
https://github.com/espressif/arduino-esp32
Nach dem Neustart der Arduino Software kann dann das passende ESP32 Board ausgewählt werden. In meinem Beispiel ist es ein DOIT V1 Board.
Spezielle Hinweise für den ESP32
Bei der Programmierung des ESP32 gibt es ein paar Dinge zu beachten. Auf den Boards ist meist ein passender Spannungsregler für 3,3V und ein passender FTDI Chip aufgelötet. Somit entfällt eine weitere Schaltung zur Spannungsversorgung. Zudem wird das Board vom FTDI Chip durch die Arduino Software automatisch in den "Upload Modus" versetzt. Man muss also nicht wie beim ESP8266 bestimmte Taster drücken (Flash und Reset) um das Board in den "Upload Modus" zu bringen.
Ich habe öfters die WifiManager Library für das WLAN verwendet. Auf Dauer hatte ich damit jedoch immer wieder Probleme, so das ich meine WLAN Daten mit Absicht "fest" in das Programm einbaue. Zudem ergibt sich beim WLAN noch ein Problem wenn auf einmal die WLAN Verbindung unterbrochen wird, z.B. wenn der Router neu gestartet wird. Danach verbindet sich der ESP32 nämlich nicht mehr automatisch mit dem WLAN. Um das zu verhindern habe ich folgende Funktion in den Code eingebaut. Die Funktion WifiEvent startet den ESP32 neu wenn keine Verbindung mehr zum WLAN besteht. Leider funktioniert jeder andere Weg im Moment nicht zuverlässig.
#include <Arduino.h> #include <WiFi.h> //WiFi const char* ssid = "AccessPoint"; const char* password = "pass"; //WiFi void WIFI_Connect() { digitalWrite(2,1); WiFi.disconnect(); Serial.println("Booting Sketch..."); WiFi.mode(WIFI_AP_STA); WiFi.begin(ssid, password); // Wait for connection for (int i = 0; i < 25; i++) { if ( WiFi.status() != WL_CONNECTED ) { delay ( 250 ); digitalWrite(2,0); Serial.print ( "." ); delay ( 250 ); digitalWrite(2,1); } } digitalWrite(2,0); } void setup() { Serial.begin(115200); delay(500); //WiFi Part WIFI_Connect(); } void loop() { //Wifi WatchDog WiFi.onEvent(WiFiEvent); //Check if WiFi is here //Automatically reconnect the ESP32 if the WiFi Router is not there... if (WiFi.status() != WL_CONNECTED) { WiFi.onEvent(WiFiEvent); WIFI_Connect(); } else { //Do something if the WiFi is available } } //Wifi Watchdog void WiFiEvent(WiFiEvent_t event) { Serial.printf("[WiFi-event] event: %d - ", event); switch(event) { case SYSTEM_EVENT_STA_GOT_IP: Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); break; case SYSTEM_EVENT_STA_DISCONNECTED: Serial.println("WiFi lost connection"); WiFi.begin(); // <<<<<<<<<<< added <<<<<<<<<<<<<<< ESP.restart(); break; case SYSTEM_EVENT_STA_START: Serial.println("ESP32 station start"); break; case SYSTEM_EVENT_STA_CONNECTED: Serial.println("ESP32 station connected to AP"); break; case SYSTEM_EVENT_STA_LOST_IP: Serial.println("ESP32 Lost IP"); WiFi.begin(); // <<<<<<<<<<< added <<<<<<<<<<<<<<< ESP.restart(); break; } }
Kalibrierung
Als nächstes müssen die Stromsensoren kalibriert werden. Dazu sollten folgende Variablen angepasst werden. Die Kalibrierung habe ich mit einer 100W Lampe und einem Wasserkocher 1800W durchgeführt. Eine genaue Stromzange oder eine Wattmeter sind sehr nützliche Hilfsmittel. In meinem Fall kann der SCT-013-030 als kleinste Einheit 100mA Strom erkennen. Die Sensoren haben 1800 Wicklungen und einen 62 Ohm Burden Widerstand. Der Offset Wert sollte nicht am PC USB Port sondern an einem separaten 5V Netzteil kalibriert werden. Denn die meisten PC USB Anschlüsse liefern bei 200mA nur noch eine Spannung von 4,5V.
ICAL = Kalibrierung
filteredI = 0.9989 * (lastFilteredI+sampleI-lastSampleI); //Kalibrierung
Irms1 = (I_RATIO * sqrt(sumI / numberOfSamples)) - 0.06;//Offset
#include <Arduino.h> #include <WiFi.h> void setup() { Serial.begin(115200); delay(500); } //Setup variables int numberOfSamples = 4000; double ICAL = 1.08; //Set Voltage and current input pins int inPinI1 = 34; // CT: Voltage depends on current, burden resistor, and turns #define CT_BURDEN_RESISTOR 62 #define CT_TURNS 1800 #define VOLTAGE 225 // Initial gueses for ratios, modified by VCAL/ICAL tweaks double I_RATIO = (long double)CT_TURNS / CT_BURDEN_RESISTOR * 3.3 / 4096 * ICAL; //Filter variables 1 double lastFilteredI, filteredI; double sqI,sumI; //Sample variables int lastSampleI,sampleI; double Irms1; unsigned long timer; void loop() { timer = millis(); //************************************************************************** //Phase1 for (int n=0; n<numberOfSamples; n++) { //Used for offset removal lastSampleI=sampleI; //Read in voltage and current samples. sampleI = analogRead(inPinI1); //Used for offset removal lastFilteredI = filteredI; //Digital high pass filters to remove 1.6V DC offset. filteredI = 0.9989 * (lastFilteredI+sampleI-lastSampleI); //Root-mean-square method current //1) square current values sqI = filteredI * filteredI; //2) sum sumI += sqI; delay(0.0002); } //Calculation of the root of the mean of the voltage and current squared (rms) //Calibration coeficients applied. Irms1 = (I_RATIO * sqrt(sumI / numberOfSamples)) - 0.06; if (Irms1 < 0){ Irms1 = 0; }; //Set negative Current to zero sumI = 0; Serial.println("Irms1:"+String(Irms1)); }
Download Arduino Sketch
Achtung: Ihr müsst das Programm noch an Eure WLAN und EMON Server Parameter anpassen.
Download Arduino Sketch: Emon ESP32
Emoncms
In Emoncms kann nun ein schönes Dashboard erstellt werden. Dazu gibt es bereits bei den Inputs die Funktionen "Power to kWh und Power to kWh/d".
Die Werte können nun alle im Dashboard angezeigt werden.