-->
Page 1 of 2

Mains Power/Energy Measurement with an ACS712

PostPosted: Fri Mar 30, 2018 6:25 am
by martin_g
Let me share some code from my project with you: the ACS712 is a hall effect current sensor that converts current values into voltage. Together with the ADC of the ESP8266 this can be used to build a power-meter for mains sockets.

I build this intermediate socket using an old remote switch case and an ACS712 sensor:
IMG_20180330_121804_780.jpg

(Caution: Mains power here when connected, but the ACS712 has a galvanic separation of the measured current and the sensor voltage!)

The ACS712 has to be powered with 5V and its output is in the range from 0-5V (with a 0 offset of 2.5V, i.e. if there is no current, the output is 2.5V). Before feeding it into the ESP's ADC it has to be divided with two resistors (or a trim pots) to either 1:2 to 3.3V (for a modul like the Wemos that accepts 3.3V as max for the ADC) or 1:4 for a basic ESP that only accepts 1V.

If you are using WiFi (and on an ESP8266 you probably will do that), make sure to set wifi_set_sleep_type(NONE_SLEEP_T), otherwise the ADC will produce some more random noise - see this issue.

Now we are ready to measure: the sketch below will do the job for a ACS712 with max current of 5A and 230V. It computes the effective voltage by integrating over a multiple of the period and computes the current and the power consumption since the start of the sketch.

Expect a noise of about 1-2 Watts and a max range up to 2kW.

Code: Select all#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}

#define SUM_MAX 600
#define ADC_MAX 1024

int count = 0;
int adc_avr = 0;
uint16_t vals[ADC_MAX+1];
unsigned long time_m;
unsigned long time_mn;
float Ieff;
float P;
float W;

void setup() {

  // initialize serial communication:
  Serial.begin(115200);
  //WiFi.mode(WIFI_OFF);
 
  wifi_set_sleep_type(NONE_SLEEP_T);

  Serial.println();
  Serial.println();

  delay(500);

  time_m = millis();
}

void do_measurements(int n) {
  uint16_t last_adc_read;
 
  for (;n > 0; n--) {
    count++;
    if (count >= SUM_MAX) {
      float U, Ueff;
      float Sum_U_Square= 0.0;
 
      count = 0;
      adc_avr = adc_avr/SUM_MAX;
 
      for (int i = 0; i < ADC_MAX+1; i++) {
        if (vals[i] != 0) {
          //Serial.print(i);Serial.print(": ");
          //Serial.print(vals[i]);Serial.println(" ");

          if (abs(i-adc_avr) > 2) {
            U = ((float)(i - adc_avr))/1024 *5000;
            Sum_U_Square += U*U*vals[i];
          }
          vals[i] = 0;
        }
      }
      Ueff = sqrt(Sum_U_Square/SUM_MAX);
      Ieff = Ueff/185.0;
      P = Ieff*230;
      time_mn = millis();
      W += P * (time_mn - time_m)/3600000.0;
      time_m = time_mn;

      Serial.print(String(adc_avr)+"  ");
      Serial.print(String(Ueff)+"mV  ");
      Serial.print(String(Ieff)+"A  ");
      Serial.print(String(P)+"W ");
      Serial.println(String(W)+"Wh");
 
      adc_avr = 0;
    }

    last_adc_read = analogRead(A0);
    if (last_adc_read > ADC_MAX) {
      Serial.println("ADC error");
      continue;
    }
    vals[last_adc_read]++;
    adc_avr += last_adc_read;
    delay(2);
  }
}

void loop() {
  do_measurements(50);
}

Re: Mains Power/Energy Measurement with an ACS712

PostPosted: Fri Mar 30, 2018 4:02 pm
by martin_g
Combined that with a WiFi Socket based on an ESP8266. Now it is really smart: not only remote controlled on/off, but also smart enough to report the power consumption of the connected device via MQTT - all in a self contained socket case. I know, you can buy this somewhere - but not for around 12€ with custom firmware...

You can find the code here.

Re: Mains Power/Energy Measurement with an ACS712

PostPosted: Sat Mar 31, 2018 2:49 am
by schufti
Hi,
nice idea but without reference to the actual voltage the result is only "numbers", except for ideal resistive loads. Unfortunately most everyday devices are everything but ideal ...

A coarse estimation would at least require to measure the time from zerocrossing of voltage to maximum of current to get cos-phi (provided current is still undistorted sine shape). This could be done with additional optocoupler.

True energy metering would need measurment of current and voltage over at least one period and summing up ...

Re: Mains Power/Energy Measurement with an ACS712

PostPosted: Sat Mar 31, 2018 5:52 am
by martin_g
Of cause it is not an accurate measurement device and assumes only resitive loads and doesn't account for reactive power, but it gives you a fairly reasonable estimation for many devices. At least for lights (even with a phase dimmer), all kinds of heating devices like coffee mashine, dish washer, toaster etc. it gives good results.

Together with a chart tool it can easily provide interesting power profiles (here an example from my fridge):
Kühlschrank.jpg