OpenEnergyMonitor Community

Esp8266 sct 013 20a


I want to use a SCT013 20A/1V with an ESP8266.
the wirering is illustrated here:

my problem is, if I attach the sensor to a powerline (of course only one of the three wires) which has a momentary load of 35W I got as an result 80W.
If I disconnect the wire to the sensor, it drops to 0. So the wirering itself should be ok.
If I raise the load the 80W increases too.

So, what could be wrong?

#include <SPI.h>

#include <EmonLib.h> 
#define ANALOG_INPUT_SENSOR A0  // The digital input you attached your SCT sensor.  (Only 2 and 3 generates interrupt!)
//#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)

EnergyMonitor emon1;

long wattsum = 0;
double kwh = 0;
double wh = 0;
long lastmillis = 0;
int minutes = 0;

void setup()  
  emon1.current(ANALOG_INPUT_SENSOR, 25);             // Current: input pin, calibration.


void loop()     
  if (millis()-lastmillis > 5000) {
    double Irms = emon1.calcIrms(1480);  // Calculate Irms only
    if (Irms < 0.3) Irms = 0;
    long watt = Irms*240.0;
    wattsum = wattsum+watt;
    minutes = minutes + 1;
    lastmillis = millis();
    Serial.print(watt);         // Apparent power
    Serial.print(" ");
    Serial.println(Irms);          // Irms
  if (minutes == 10) {
    wh = wh + wattsum/10;
    kwh = wh/1000;
    wattsum = 0;
    minutes = 0;


Of course, I am new to this stuff :wink:

It’s wrong because emonLib was designed for the Atmel ATMega328P, which has a different ADC input range. The input range of the '328P is 0 to the supply voltage, which is 3.3 V for the emonTx, 5 V for a standard Arduino, and the calibration constant is the current that gives 1 V at the ADC input. The scale factor for the ADC is 1024 counts ≡ 3.3 V, or 5.5 V, and emonLib must also be told the correct supply voltage.

In your case (and I don’t use the ESP8266 so I can only work from the rather scarce and imprecise published data that I can find), I think both your resistor values and those numbers are wrong.

From what I read (and this might well be wrong - check the data sheet for your device), the input range of your ESP8266 is 0 - 1 V. If that is true, you need to change R1 & R2 so that their junction is at 0.5 V d.c - in the middle of the input range of the ADC (with no current flowing in the c.t.). If pin Vin is 3.3 V, this means R2 needs to be 82 kΩ (the nearest standard value) if you keep R1 as 15 kΩ. Or you can change both resistors to suit what you have - values for R1 should not be too much less than 330 Ω, alternatively R2 should not be much greater than 330 kΩ. The maths of course is Vin * R1 / (R1 + R2) = 0.5 You will not achieve that with standard values, just choose convenient values that get you as close as possible to 0.5.

You can test this before you make the change to see if I am correct by printing the analogue value that the input pin reads - without emonLib. You want the raw number from analogRead( ). If, with your input circuit and the c.t. not measuring current, you read a number around 512, I’m wrong. If however the input range is 0 - 1 V, your input will sit at 1.65 V and you will read 1023 (or close).
When the input circuit is working correctly, the value you read will sit at 512 or thereabouts - few either way won’t matter.

When you have that part right, you can change your calibration constant (“25” in emon1.current(ANALOG_INPUT_SENSOR, 25) ) to give the correct power. You can either compare your reading to your other meter and adjust the number to make the readings the same, or you can work through the maths in emonLib and calculate it - which might still not be exactly the same because the accuracy of the c.t. is only ±3%, from 10% to full load, and your voltage will not necessarily be exactly 240.0 V either.

(Note: Apparent power - Scheinleistung - is not measured in watts, it is volt-amperes - VA.)

thank you so much for that very detailed reply. I changed following:

ESP8266 → ESP32
Resistors both 100k, results in 495 analogread
emon1.current(ADC_INPUT, 20)

Now it works very well for larger loads like an electric heater. It shows me ~1000W and ~2000W if I put it in switch position 1 or 2. That’s the same value like I can read on my other meter. So that’s absolutly correct.
Unfortunately if I disconnect the sct013, it still shows 100-120W. So it never drops below that reading/value.
Maybe this kind of sensor is not suitable for sensing lower currents? Could that be the case?

This is probably due to the input circuit picking up electrical noise. It could be coming from the power supply that you are using for the ESP32, or it could be generated by the digital circuits and processing within the ESP32.

You could try a small plastic film capacitor - say 100 nF - in parallel with C1, and the same between Vin & GND - i.e. across the power supply to the ESP32.
You could also try a different power supply, if you have one available.

I should also say that there are well-known problems with the analogue input of the ESP32:
ESP32 Analogue input [TW#12287] ESP32 ADC accuracy · Issue #164 · espressif/esp-idf · GitHub and the comments that follow, and many users prefer to have a separate ADC instead of using the one inside the ESP32.

The SCT range of c.t’s have an accuracy of ±3% from 10% to 120% of rated current. Outside that range, no accuracy is specified. However, that does not mean that you should expect to. read 100 - 120 W ( ~ 0.5 A).