ESP32 - Stable ADC value, but peaks in Irms value

Tags: #<Tag:0x00007f8de4929a68>

Hello guys,

I am experimenting with EmonTX on an ESP-WROOM-32 dev kit/board.
Everything is connected exactly like on the Wiki page here

Quite often I get that the Irms value has a short peak/spike while the ADC value of the ESP32 stays perfectely stable.
Here I plotted the raw ADC value (red) and the calculated Irms value (blue), together with the code on the left.

Is there something I can do to prevent this?

No it doesn’t. I can see noise on that “perfectely stable” [sic] line - what is the amplitude of the noise?

Is it pure chance that the places where the amplitude is larger coincide with the steps in the calculated rms current? I’m inclined to think not.

How big are those steps in relation to the maximum current your setup is capable of?

When we know that, in other words we know what your calibration actually means, it becomes possible to sensibly evaluate what you’re seeing. Until then, it isn’t.

Removing the source of the noise is likely to help.

Hello @Robert.Wall, thank you for your fast response.

I wasn’t aware that a small amount of noise can result in such peaks in the output value of the software.
I am using an SCT-013-030 current transformer (1VAC/30A) with internal burnden resistor in the following schematic

In the signal I plotted earlier, I have an Irms of 0.08A, with the noise occurs on the input pin I see a jump to about 0.20A.

Right now I have everything wired up on a breadboard. Maybe moving everything over to a dedicated PCB with sufficient decoupling capacitance would get rid of the noise ?

Looking later at your example code, even that isn’t telling the whole story. What you are plotting is the rms current averaged over 1480 samples (I’ve no idea what time that represents on your ESP32 - you should evaluate the sample rate and make the number of samples fit as closely as possible to an integer number of mains cycles), but the red “perfectely stable” is a single sample taken at the end of those 1480 samples. So it’s hardly representative of what emonLib is measuring.

Anecdotally, the greater proportion of cases of noise (non-zero readings) have always come for breadboarded construction. If your c.t. is 1 V at 30 A, then 200 mA is 6.6 mV.
While this isn’t particularly small in absolute terms, it’s at the sort of level where quite a lot of care is needed. So a custom p.c.b. that has been carefully laid out with attention given to the advice in the application notes should give you an improvement.

Thank you for this valueable explanation Robert. I learned a lot with this information.

Today I did a little test with the ESP32. I measured the time it takes for the ESP32 to take 1480 samples and 10 000 samples with calcIrms().

1480 samples takes 18ms = 82,2ns/sample
10 000 samples takes 123ms = 81,3ns/sample
-> So let’s say 81,75ns/sample on average

I live in a 50Hz mains power area, and let’s say I would like to measure 10 mains cycles per ‘measurement’:
((1/mains frequency)*amount of mains cycles)/time per samle
((1/50)*10)/0,00008175 = 2446

So together with a nicely designed PCB and an ESP32 running emon1.calcIrms(2246), I should have nice results, right?

Hope I can also help some others with this conversation and information.

What sum are you doing there to get 81 - 82 ns/sample? I think your maths are way out. I make it a little over 12 μs per sample, which is much more believable.

1480 samples in 18ms is 82222 samples per second. That is where your 82.2 came from: 82.2 k samples per second.

The reason for the difference is probably the time to start and stop the measurement, which will be constant. So I suspect the calculation should be: it takes (123 - 18) ms to measure (10000 - 1480) samples, so 12.32 μs per sample. You want to sample for 200 ms, so that’s 16234 samples.

I messed up my time units and maths there. Sorry for this rookie mistake

I started a hardware timer right before executing the calcIrms() command, and stopped it right after.

For 1480 samples I got 18ms -> 0,018/1480=0,0000121s/sample -> 82222 samples/second
For 10000 samples I got 123ms -> 0,123/10000=0,0000123s/sample -> 81300 samples/second

So yes indeed on average 12.32us/sample.
Is it recommended to sample for 200ms? Or should a shorter or longer time period give better results?

Thank you very much for your help. I really appreciate it.

I think the 200 ms sampling period came from the need (or desire) to be able to operate the emonTx from batteries. Clearly, working for 0.2 s and then putting the processor to sleep for 9.8 s significantly extended battery life. And over time, that approach can be surprisingly accurate.

However, if you have a rapidly switched load, an induction cooker for example, then if the cooker cycles at (or a sub-multiple of) the 10 s sample rate, then you’re likely to always be sampling during an ‘on’ period or an ‘off’ period, so a large error might result. emonLibCM adopts a completely different approach and samples continuously, so removing that problem.

If you have mains power to your ESP32, there’s no need to take discrete samples once every 10 s. The longer the sampling period, the better the accuracy is likely to be. Sampling only current, you aren’t able to synchronise to the mains wave, and to get an accurate average, you really need to measure over an exact number of complete cycle, although where you start on the cycle doesn’t matter. Because you are sampling a lot faster than the '328P, you can afford to sample fewer cycles. You could sample 1 cycle (1623 samples) if you wanted, because one 1623rd part of a cycle error will make no real difference to the reading.

Now you know your sample rate, it’s clear why 1480 samples was a bad idea - you were not even measuring over 1 cycle of mains, you were missing about 10% of the cycle each time you measured.