STM32duino+emonlib - strange behavior


I’m trying to migrate Emon from arduino platform to STM32. I’m not an expert in STM32 therefore I’m using STM32duino (STM32F103C8). Seems that scatch could be easily adopted to new platform with minor modifications. However I’ve faced strange behavior, which I’ve never seen before on arduino

Scheme is following:


Scetch is following:

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

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

void loop()
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.print(Irms*230.0);         // Apparent power
  Serial.print(" ");
  Serial.println(Irms);          // Irms

Result without CT sensor:

39.11 0.17
40.06 0.17
37.59 0.16
36.00 0.16
38.37 0.17
36.08 0.16
35.81 0.16
37.38 0.16
39.01 0.17
38.71 0.17
40.66 0.18
35.73 0.16

With CT sensor result is following:

263.82 1.15
280.37 1.22
258.48 1.12
292.80 1.27
263.18 1.14
300.24 1.31
264.31 1.15
273.10 1.19
273.41 1.19
270.87 1.18
271.70 1.18

This behavior makes me crazy. Maybe, somebody saw such behavior and can support me. Is it hardware or software problem?


My first thought is it’s noise pickup. That’s hardware. Either the bias supply is noisy, or the noise could be getting in via the ADC reference input from the power supply. A small (0.1 μF) non-electrolytic capacitor in parallel with the 10 μF will answer the first, changing your power source or heavily smoothing the 3.3 V / 5 V (or both) power rails should show whether it is noise on the supply.

My second thought is, as emonLib was intended for a 16-bit processor with a 10-bit ADC, have you got the correct scaling factors? That is, if you have a 1 V rms signal measured across R3, does it read your “calibration factor” current of 111.1 A?

Thanks for recommendation. I think that capacitor will help to have smooth and stable results. I will check it in the evening.
Regarding your second suggestion, for me it is not really clear how to adjust emonlib to 32bit processor and 12bit ADC. I tried to add analogReadResolution(12) but it does not work with my board. Than I found in the internet that for STM32 processors 12bit is a default value and there is no need to define it in the scatch. Could you help me with the direction of where to look for the correct scaling factor?

Regarding calibration value, you are completely right! In my arduino projects I’m using 60.6. Here I took simple example.

Seems that burden resistor should be around 3.3/0.1414 = 22-24 Ohm
This means that calibration value should be 2000/22=90.9 in case of usage 22 Ohm.

But any way even if I’m using 33 Ohm burden resistor without load it should give around 0.
I’m confused :confused:

1 Like

Yes, you are looking at two different - but related - things. If the scale factors are wrong, then the current you see will be wrong. That could mean that the ~1.2 A that you measure is not the actual noise. If (say) you are dividing by 1024 where you should be dividing by 4096, then your 1.2 A is only 0.3 A, and that is the sort of number we can see. Here’s how to check:
If ADC_BITS is set properly by the compiler, then emonLib should get the scaling for the 12-bit ADC correct. Have you looked in emonlib.h, have you set __arm__, or has your choice of board automatically set it? Try printing ADC_BITS - it should be 12 for you,

22 Ω is the burden we use in the 3.3 V emonTx and emonPi, for 100 A with a 100 A : 50 mA c.t. With a 33 Ω burden, your maximum current will be ~ 66.7 A.

But whatever the problem is, you are right, it should read zero with no current flowing - or with no c.t. connected. The reality is, it always will read a small current, because the real world is not perfect.

I received the first of my SCT-013-000’s today and it might be another week before the Arduino shield and EmonTx V3 arrives. So I built the circuit as per the docs, firstly for a Nano and then a Leonardo.

I used a 99 Ohm and 47 Ohm resistor in parallel for the burden resistor as I don’t have anything close to 33 Ohm. Online calcs show this should be 31.7 Ohm and I measured it at 31.9 so pretty close. I am using 470K bias pair and not using the OEM adaptor yet but will add that later.

Used the calibration as shown above by @mel from the docs and the results without the CT connected and 5V from the Arduino:

Nano: approx 12 amps !!!
Leonardo: approx 6 amps!!!

Any idea where I am going wrong?

That looks better:

11.75 0.05
11.30 0.05
10.65 0.04
9.23 0.04
9.02 0.04
9.58 0.04
13.37 0.06
12.56 0.05
9.22 0.04
10.84 0.05
9.02 0.04
10.83 0.05
11.81 0.05
11.46 0.05
9.79 0.04
9.79 0.04
7.22 0.03
10.65 0.04
7.27 0.03
7.26 0.03

Note to self: don’t forget what hacks you did in the library.

Do you have an actual current draw of around 1.2A?

You should never need to change anything inside the library. It should be possible to adjust everything that you must to cater for most normal situations by using the ‘setter’ methods.

Yes, 30 - 50 mA is the sort of number we usually see with ‘breadboard’ builds. The emonTx can get a bit lower, due to a careful pcb layout.

I thought @mel said he had no input connected.
He could have a ‘noisy’ electrolytic capacitor - unlikely, but they’re not unknown.

I did some crazy stuff when I was using the library just for OEM AC - AC and random numbers for current.

I don’t think he has indicated either way, just CT connected and not connected.

Actually my results are not as good as they appeared in Serial Monitor. I was hooked up to 3.3V, 5.0V gives me 150mA. Bad procedure somewhere by me?

Or a bad power supply.

OK I’ll hook up the OEM AC - AC tomorrow, thanks.

@GeorgeB & @mel

See ARCHIVE: : Not all USB power supplies are created the same
Noise in Arduino based builds. | Archived Forum

1 Like

@Robert.Wall I think I read somewhere that 3.3V from the Arduino is more stable than the 5.0V so I might check the calibration for that.

I’m running from a laptop and I think the USB is pretty stable.

Failing that at 5V can I add a further calibration as:

Irms = Irms - 0.135;

Guys, I found where was part of my problem. Thanks to @Robert.Wall
I added ceramic capacitor and result still floating. Than I checked all connections and found bad contact.

Now results are much better


This is with connected CT sensor and without load.

@Robert.Wall is right by now all my tests are done without load. That is why I’m expecting to see 0 in the result.

I was going to say almost exactly the same as me but I notice you are using 3.3V.

I’ve noticed that this deviation is present everywhere:
on arduino and 5v power supply
on stm32 and 3.3v power supply
In addition other people has the same deviation. It seems to be stable - around 0.15 ±noise
Where it comes from? How to reduce it? Currently I’m reducing it with correction like @GeorgeB showed.

if (Irms0<k) {i0 = 0;} else {i0 = (Irms0-k)*v;}

where is k is a correction coefficient. In my case it is equals 0.18

1 Like


You started a parallel thread How to enable 12bit for STM32F103
that logically continues from the beginning part of this one. Separating this across two threads will waste everyone’s time.

What you need to do is determine whether __arm__ or anything else that indicates that you have a 12-bit ADC is set, then use that to switch ADC_BITS from 10 to 12. What you appear to have done will cause bad results for any sketch you compile for a 10-bit ADC. Do not forget that the same library is used in every sketch, unless you fork your own version, which you keep just for the STM board. And if you do that, you can leave out the test for __arm__ and simply write #define ADC_BITS 12

Robert thank you for support

Do know by chance where arm parameter is defined?

#if defined(__arm__)
#define ADC_BITS    12

Logically it should be defined some where in the board or processor config.
I checked, but for the first glance I couldn’t identify this parameter.


@mel it’s at line 259 of EmonLib.cpp