A place users can post their projects. If you have a small project and would like your own dedicated place to post and have others chat about it then this is your spot.

User avatar
By martin_g
#75009 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);
}
You do not have the required permissions to view the files attached to this post.
User avatar
By martin_g
#75019 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.
User avatar
By schufti
#75028 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 ...
User avatar
By martin_g
#75031 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
You do not have the required permissions to view the files attached to this post.