My new project consists of HW with cost under 20€. It is able to accurately measure electric power consumption and sends data via WiFi. Great source of knowledge is openenergymonitor.org which includes also Arduino library.
It is very helpful to read the following pages to understand this project :
My max mains power supply current is 25A and via the tool, the calculated burden resistor is 141Ω. If I use 25A withou peak-current (multiplying by √2) the value would be 200Ω. I used 150Ω (that is max 33.3A peak in AC waveform which 23.6Arms and that is 5.66kW in case of 240V).
The calculation without the peak current is:
25A / 2000 = 0.0125A 5V/2 = 2.5V (I used Arduino 5V) 2.5V/0.0125A = 200Ω
Do not use CT sensor without the burden resistor. I have connected the 150Ω burden resistor directly on 3.5mm Jack Breakout.
Hardware
- Arduino Pro Mini 5V or any other 5V Arduino
- 3.5mm Jack Breakout
- SCT-013-000 Non-invasive AC Current Sensor 100A also known as CT (Current transformer) sensor
- ESP8266 Serial WIFI
- Resistors – 1×150Ω and 2×100Ω
- Capacitor 1uF
- 3.3 Step Down for ESP-01
- Spare 12V DC Power supply (any of 8-12V can be used to have stable 5V in Arduino)
The clean power supply is essential for the 5V readings. When I used 5V power supply, readings were spread up to 100W with AC sensor not even connected.
Reminder: I have connected my 5V Arduino TX directly to 3.3V ESP-01 RX. It works well, but you find many notices NOT to do it directly but via voltage divider (2 resistors). Since it works for a month now, I do not bother 😎
Prototyping
Prototype in use
Results
Simple google php with google chart api result:
My favorite Grafana graph from data stored in influxdb
Daily survey of power consumption:
Example of 1 hour chart of power consumption:
- 8:00 – Making coffee
- 8:20 – Washing-machine (heating water)
- 8:32 – Dish-washer (heating water)
- 8:43 – Boiling water
- 8:44 – Washing-machine or dish-washer stopped heating
- 8:44 – Washing-machine and dish-washer are doing their job..
Another Grafana and Influxdb chart example:
Arduino Source code
Download: EmonLib
// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3 #include "EmonLib.h" // Include Emon Library EnergyMonitor emon1; // Create an instance void setup() { Serial.begin(9600); emon1.current(0, 13.33); // Current: input pin, calibration. (100 ÷ 0.050) ÷ 150 Ohm = 13.33 } void loop() { unsigned long previousMillis = millis(); int count = 0; double Irms = 0; while ((millis() - previousMillis) < 5000) { Irms += emon1.calcIrms(1480); // Calculate Irms only count++; } Irms = Irms/count; Serial.println(Irms * 241.0); // Apparent power }
ESP-01 Source code
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <Wire.h> const char* ssid = "SSID"; const char* password = "PASSWORD"; WiFiClient client; byte server[] = { 192, 168, 1, 11 }; // http server String serverStr = "192.168.1.11"; // http server // Update these with values suitable for your network. IPAddress ip(192, 168, 1, 211); //Node static IP IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); extern "C" { #include "user_interface.h" } void setup() { Serial.begin(9600); Serial.println(); Serial.println("wifi connect:"); } String readSerial() { while (Serial.available() < 1) delay(100); char inData[20] = "xxxxxxxxxxxxxxxxxxx"; // Allocate some space for the string inData[0] = '\0'; char inChar = -1; // Where to store the character read byte index = 0; // Index into array; where to store the character delay(100); // to get all data in one shot while (Serial.available() > 0) // Don't read unless there you know there is data { if (index >= 20) // One less than the size of the array break; inChar = Serial.read(); // Read a character if (inChar == '\r') // is \r\n break; inData[index] = inChar; // Store it index++; // Increment where to write next inData[index] = '\0'; // Null terminate the string //Serial.println(inChar); } while (Serial.available() > 0) // Don't read unless there you know there is data Serial.read(); String resp = String(inData); resp.trim(); Serial.println(resp); return resp; } void loop(void) { //Serial.println("Loop..."); unsigned long previousMillis = millis(); delay(10); // Get Values String fromSerial = readSerial(); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); WiFi.config(ip, gateway, subnet); // Set static IP (2,7s) or 8.6s with DHCP + 2s on battery // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(100); //Serial.print("."); } if (client.connect(server, 80)) { client.print("GET /SensorWriteToFile.php?serial="); client.print(fromSerial); client.print("&milis="); client.print(String((millis() - previousMillis))); client.println(" HTTP/1.1"); client.print("Host: "); client.println(serverStr); //client.print(":");client.println(String(port)); // watch for ln ! client.println("User-Agent: Mihi IoT 11"); client.println(); // empty line for apache server //Wait up to 10 seconds for server to respond then read response int i = 0; while ((!client.available()) && (i < 1000)) { delay(10); i++; } /* while (client.available()) { String Line = client.readStringUntil('\r'); } */ client.stop(); } else { //Serial.println("connection failed"); } //WiFi.disconnect(); // Disconnect from the network wifi_set_sleep_type(LIGHT_SLEEP_T); delay(100); }
PHP Source code
Simple code to store data to file. File: SensorWriteToFile.php
format('Y-m-d H:i:s'); $data = $_REQUEST; $data += array("datetime" => $dateTimeStamp ); $data += array("user_agent" => $_SERVER['HTTP_USER_AGENT'] ); $data += array("epoch" => time() ); $req_dump = json_encode( $data ) . "\n"; $fp = file_put_contents( '/var/www/test3_request.log', $req_dump, FILE_APPEND ); ?>
user_interface.h: No such file or directory
how can i resolve this ..
thank you
Nice article!
Why did you use the separate Arduino? Would it be possible to use an ESP with analog input? E.g. the Wemos D1 mini boards?
Regards,
Marco