OpenEnergyMonitor Community

Simple CT Circuit 15% over reading


In advance of buying some ‘proper’ hardware like the emonTX, I’ve put together a basic circuit similar to the one at

This posts to a Emoncms instance I’ve setup on a RaspberryPi. Comparing the ‘Power to kWh’ feed in emoncms, to the increase reported on the electricity meter, I’m seeing the CT overreading by 13-16% which feels rather high. With my basic setup / calibration below, can anyone see anything I might have done wrong?

I’ve used a NodeMCU ESP8266, as I had a spare one, and a YHDC SCT-013-000 CT.

As the ESP8266 has 3.3v, I’ve used a 22 Ohm burden resistor.

Within my code, I setup with:
emon1.current(0, 90.90); // calculated as (100 ÷ 0.050) ÷ 22

Then loop as:
double Irms = emon1.calcIrms(5580); // also tried 1480
double AI = Irms * 237.0; // 237.0 from a 3-pin plug-in energy monitor
String url = “http:///input/post?node=nodemcu&fulljson={“power1”:” + String(AI) + “}&apikey=”

The code posts to emoncms after every reading, without any sleep. I’ve set my feed to be PHPFINA with 5s interval.

It’s a standard single phase supply (in London).

I’ve attached a 24 hour graph, the lowest power reading is around 250W.

I’ve come across a few different number of samples to use with calcIrms, even trying a few of these doesn’t seem to make a noticable difference to the over-reading value.

Any suggestions would be much appreciated.

Welcome, Jeff, to the OEM forum.

Unfortunately, the ESP8266 has a particularly bad reputation for ADC accuracy. I’m not familiar with it, and I don’t know the sample rate so I can’t comment on the optimum number of samples.

So there’s not a lot more that I can say, other than what you’ve done should work, all things being equal. But they’re not. Our tutorials and ‘production’ sketches are all tailored for the Atmel ATMega 328P (as in the Arduino Uno), so I’d expect some differences anyway even though the ADCs are outwardly similar.

I think I can safely say that there are very few users who have successfully used an ESP8266 for energy monitoring directly, without help from an external ADC.

You could try measuring the current with your plug-in meter and comparing that against the Irms you get from the software. You can of course multiply the current by passing the wire several times through the c.t., so a 1.5 kW kettle would read 6 A on your meter and 30 A with 5 turns through the c.t.
Then tweak the current calibration constant to suit.

I wouldn’t be surprised to find the results are somewhat non-linear.

To the best of my recollection, that number has actually been zero. (on the OEM forum)
I remember reading about how crappy the ESP8266’s ADC is. As in really bad.

Thanks for the replies.

Hmmm, OK. It’s clearly working ‘reasonably’ well to be around 15% over-reading. It’s very obvious when the kettle / other high draw appliances are turned on and I’m able to distinguish the frequent patterns of things like the aquarium heater - so I wouldn’t say (from my sample size of 1) that it’s really bad.

I’m guessing it would be a similar comment for any of the ESP family (e.g. ESP-32)?

Right, so I was presuming that the rate and number of samples was related to the frequency of the energy being monitored rather than the processor on the energy monitor :see_no_evil:

Is there an ‘easy’ way to do some tests or calculate what a good number of samples to pass to calcIrms would be?

That will be the next thing, I think. I can see the increase when turning on the kettle over the background usage so can work with that. There is no easy way for me to get the CT onto just the kettle circuit.

If I can work out how much it over/under reads at some key power values it looks like I could adjust for this with some extra processes on the input.


Fairly easy - time it!
What you need to do is (and I presume you can have a millisecond timer in the ESP like we can in the '328P) record the time and call the calcIrms( ) function with a smallish number of samples, then immediately it returns record the time again. The difference obviously is the time to get those samples plus all the overheads of calling, processing the result, etc. Now repeat with (say) 1000 more samples, then the difference between the two is the genuine time - as near as we can get - for the 1000 samples.

I’m hoping that it will come to at least 800 samples per second (i.e. 16 samples per cycle); in theory that would mean a moderately faithful recording of the current up to the 7th harmonic, which is where most of the power will be. By contrast, had you run your sketch on an Arduino or an emonTx, you’d have had something over 110 samples per cycle.

If you have a spare plug and extension socket, then connect them using 3 single-core wires (purely as a test rig - dismantle it afterwards as it’s not safe for general use).

Here’s an old sketch.

// EmonLibrary examples, Licence GNU GPL V3

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance

void setup()
  emon1.current(1, 111.1);             // Current: input pin, calibration.

void loop()
  unsigned long timethen = millis();
  double Irms = emon1.calcIrms(1172);  // Calculate Irms only
  Serial.print("Time ");Serial.print(millis() - timethen);Serial.print(" ");
  Serial.print(Irms*230.0);	       // Apparent power
  Serial.print(" ");
  Serial.println(Irms);		       // Irms

on an emonTx V3.2, it records 190 or 191 ms for 1172 samples (why 1172? I’ve no idea now), and 1794 - 1799 for 11172 samples, so 1.6 s per 10000, or 6250 samples per second - but with nothing to measure, so it might be going a bit faster than it would doing real sums.

That one is in one of the forum posts:

Now that’s the post I think I must have had in mind when I referred to an external ADC + ESP.

Another “gotcha” with the 8266’s ADC:

modem sleep is recommended when you are running sampling applications. Otherwise network stack tasks will disturb your sampling process in between at times.


Thanks! Quite a lot of food for thought. I’ll try and do some testing this week and see just ‘how bad’ the 8266 actually is.

I also need to work out why I want to measure (currently, it sounds like an interesting thing to do). Any info (even out by 15%) is a lot more visibility than I currently get.

Most people want to measure real power, not have an estimate of apparent power. Because it’s real power that you get charged for. And for that you need two channels so that you can sample the voltage and multiply the two samples together, which is what calcVI( ) does.

I thought I ought to mention that.

Finally found a little time to test this out … 10,000 samples took 1164ms, so 8590 samples/second (171 samples/cycle)

void setup()
  emon1.current(0, 90.90);
  unsigned long timethen = millis();
  double Irms = emon1.calcIrms(1172);
  Serial.print("Time for 1172:");Serial.print(millis() - timethen);Serial.println("");
  timethen = millis();
  Irms = emon1.calcIrms(11172);
  Serial.print("Time for 11172:");Serial.print(millis() - timethen);Serial.println("");

Gives output:

Time for 1172:137
Time for 11172:1301

Which seems higher than you’d expect, and similar to the emonTx.

With these figures, is there any optimisation that can be done for the number of samples calcIrms call? I read that it should be a whole number of cycles, and if my emoncms feed is PHPFINA at 5s interval would it not make sense to calculate over a 3 or 4 seconds ? For 4 seconds, that would be 4×50×171 = 34200 samples (which is a lot higher than any sample codes I’ve seen).

Still trying to find the bits to test this out.

[Edited maths for clarity - RW]

In the “old” emonTx sketches, sampling is done for 300 ms every 10 s. For the present emonPi, its every 5 s.

The worry is “end effect” - our name for having an incomplete cycle, which throws the maths out, so the idea is to have enough so that even if you do get a non-integer number of cycles by a small amount, the additional contribution won’t matter, even if it happens at the peak. But the complication is, a cycle isn’t 20 ms long, it varies by about 0.2% (the limit is 1%) according to the time of day and load on the system. So the best you can do is aim for a whole number of cycles and hope. Unfortunately, when measuring current, it’s not possible to reliably detect zero crossings, as we do when the voltage is available.

You can obviously do the maths and see which is the lesser evil - how much the sample count varies between a “fast” cycle and a “slow” cycle is your starting point. With that sort of sample count, I’d go for a similar or even shorter time around the 10 - 15 cycles area.