Community
OpenEnergyMonitor

OpenEnergyMonitor Community

EmonLibCM not working on EmonTx Shield + Leonardo

I am new to the openenergymonitor community. I bought an EmonTx Shield and an Arduino Leonardo, put them together and plug an AC/AC adapter and a CT sensor. Then, I tried the example Shield_CT1234_Voltage_SerialOnly and everything work fine out of the box (I just changed the platformio.ini config, and the VCal to ~150V).

Next, I want to run EmonLibCM instead. I used the EmonTxV3CM sketch as a reference, and removed all RFM and temperature logic (I do not have any of these). This is my sketch: emontx_shield_continuous.ino · GitHub

However, this one doesn’t work. I have tried to debug it by looking at the emonLibCM.cpp implementation, and I found that:

  • The interrupt system is working, EmonLibCM_interrupt() gets called and it enters the (sample_index == 0) branch, meaning that the AC/AC adapter is detected correctly.

  • The function EmonLibCM_allGeneralProcessing_withinISR() is also called, inside there is this code:

      if (acPresent) {
        if (polarityConfirmed == POSITIVE) { 
          if (polarityConfirmedOfLastSampleV != POSITIVE) {
            ....
    

    the first condition is met, i.e. acPresent == true, but the second condition is not met, i.e. polarityConfirmed != POSITIVE.

  • I also looked at the ADC value in rawSample (only for sample_index == 0), and the value oscillates between 0 and 1. It seems that AC data is not coming in correctly.

Intuitively, it looks like the problem could be on the ADC setup. Is there anything that I am missing? Any additional pointers to where to look next would be greatly appreciated.

Welcome to the OEM forum.

Firstly, emonLibCM and the software from which it was derived was never intended for anything other than an Atmel ATMega 328P. To my knowledge, it’s never been ported to or checked on any other processor. So unless the ATmega32u4 has the same arrangement for the multiplexer and the ADC, you will need to do some careful changes within the ISR. Another concern would be the interrupt priorities and how the USB driver interacts with the ADC.

The data sheets for the '328P and the '32u4 will be essential sources. You need to look at the commands that set up the '328P multiplexer and ADC and then check what the equivalents for the '32u4 are. The ADC is free running of course, on completion of the conversion it raises an interrupt, switches the multiplexer and starts conversion on the next input. The ISR then presets the multiplexer for the next conversion after the one that’s just started, and extracts and processes the value for the conversion just finished. So in effect there are three things happening that you need to get your head around (and it’s easy to get into a muddle until you have a good grip on the sequence of events).

If that doesn’t immediately move you forwards, I’d suggest you forget the whole of emonLibCM for the moment and get a very simple sketch working, one devoid of all the practical complications, the maths and the checking, etc; that just sets up the ADC and multiplexer, and reads values back into the correct variables. When you know you’re getting sensible values for each I/O pin that you’re using, then you can put that back into your version of emonLibCM. If you have a decent oscilloscope, that will be invaluable when it comes to checking the timing and the effect that the USB transactions might have on the ADC sampling. That’s something I’d check fairly early on, because if everything stops while the USB does its thing, it doesn’t bode well for accurate power measurements, and it might be back to the drawing board. I can tell you that emonLibCM’s near relative, the 3-phase sketch, can’t handle serial comms faster than 9600 baud, else the phase locked loop loses lock.

You also need to check the sample rate of your ADC, because that will affect the maths for compensating the phase error between the voltage and current transformers and the timing error between measuring voltage and current (which appears as a phase error also).

Indeed, the Leonardo is quite a bit different from the Uno.

Ref:

https://openenergymonitor.org/forum-archive/node/2542.html

From the link above:

The main improvements to the ADC are:

1. differential input capability
2. programmable gain
3. 2.56V internal reference
4. high speed mode
5. more inputs

In the Atmel datasheets I found that the ADMUX for '32u4 is more complex. It not only selects the input, but also the gain, or the pair of inputs for differential mode. However, in that section I noticed that there is no ADC2 input. That led me to look at the Arduino schematics, to discover that the A[0,5] pins are mapped to other MCU inputs, specifically:

  • A0 ----> ADC7
  • A1 ----> ADC6
  • A2 ----> ADC5
  • A3 ----> ADC4
  • A4 ----> ADC1
  • A5 ----> ADC0

If I change the proper channel value now on the EmonLibCM_SetADC_IChannel() and EmonLibCM_SetADC_VChannel() calls, then I get EmonLibCM to work, and to produce output values.

Regarding your comment about the USB, I do not have a scope to check it, but I can disable the USB module altogether. I will post more updates and links to my final sketches once I have the whole system working.

Thanks!