WiFi Energy Monitor

WiFi Energy Monitor

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

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

AC Prototyping AC Prototyping2 AC Sensor

Prototype in use

EMon Prototype 1 EMon Prototype 2 EMon Prototype 3

EMon Prototype 4 EMon Prototype 5

 

 

Results

emon v2 A emon v2 B emon v2 C

Simple google php with google chart api result:
Emon result 1

My favorite Grafana graph from data stored in influxdb

 
Daily survey of power consumption:
emon-dailly
 
Example of 1 hour chart of power consumption:
emon-hour1 emon-hour2

  • 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:
Emon result 2 emon-hour3

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 );
?>

2 thoughts on “WiFi Energy Monitor

  1. Maulik Solanki

    user_interface.h: No such file or directory

    how can i resolve this ..
    thank you

  2. Marco Polet

    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

Leave a Reply

Your email address will not be published. Required fields are marked *