Mbed & current measurement with LEM

12 Apr 2011

Hi,

I am trying to use mbed as rms measurement tool. I have LCD to display current value (from program TextLCD, I am using hd44780). I don't have any problems regarding display anything on the LCD.

LEM that I am using is LTS_15-NP. When there is no current, LEM should give me 2.5 V +0.625 for every +Ipn. I don't want to exceed max voltage on mbed pin, so I used resistor divider (1 kOhm, 1 kOhm, total 2 kOhm from out to 0 V on LEM), and take measurement from 1 kOhm regarding 0 V.

LEM and mbed have the same supply voltage.

When I compute average value of LEM current when Ip = 0 (current runnign through LEM) I got near 0 values (what is good). When I try to compute rms value of 20 ms signal (still Ip = 0) I have max measurement of 2 A! And that value oscillates around 1 A...

Most likely I'm doing something wrong ... Do you have any suggestions on how to perform the measurement correctly? Ultimately the system will be used to measure the rms current of single phase asynchronous motor.

dummies in the code are for reductions in sampling, to approximately 64 times samples at 20 ms. If sampling could be increased - I'd like to know how :) However, averaging the measurements seems to be quite important.

#include "mbed.h"
#include "TextLCD.h"

DigitalOut xL1(LED1);   
DigitalOut xL2(LED2);
DigitalOut xL3(LED3);
DigitalOut xL4(LED4);

DigitalIn xP1(p5);      
DigitalIn xP2(p7);
DigitalIn xP3(p13);
DigitalIn xP4(p19);

Timer t;                
volatile long ix = 0;   
volatile char xx = 0;
volatile char dummie = 0;

AnalogIn ain(p20);      
volatile double wynik;   
volatile double wynik2;  
volatile double atemp = 0;   
volatile char licznikS = 0;

TextLCD lcd(p26, p25, p24, p23, p22, p21);  

int main() {

lcd.cls();
lcd.locate(0,0);
lcd.printf("Current:\n");

t.start(); 
   
    while(1)
    {
        

        wynik = 0.0;
        ix = 0;
        atemp = 0.0;
        t.reset();

        while(t.read_us()<=20000)
        {   
            if(licznikS<4)
            {
            atemp = atemp + ain;
            licznikS++;
            dummie=dummie*dummie+1.0;
            dummie=dummie*dummie+1.0;
            dummie=dummie*dummie+1.0;
            dummie++;dummie++;dummie++;dummie++;dummie++;dummie++;dummie++;dummie++;dummie++;dummie++;
            }
            else
            {
            atemp = atemp*13.2-20.00;   //3.3*16/4*atemp;, 4 - samples, 3.3 - mbed pin modifier, 16 and 20 - LEM configuration
            wynik = wynik + atemp*atemp;
            ix++;
            atemp = 0;
            licznikS = 0;
           }
        }
        
        wynik = wynik/float(ix+1.0);
        wynik = sqrt(wynik);
        xL1 = 1;

        lcd.locate(3,1);
        lcd.printf("%5.3f",wynik);
        wait(0.2);
        xL2 = 1;
}}  
12 Apr 2011

Bartosz Rybarczyk wrote:

When I try to compute rms value of 20 ms signal (still Ip = 0) I have max measurement of 2 A! And that value oscillates around 1 A...

The proximate cause is probably this statement:

            atemp = atemp*13.2-20.00;   //3.3*16/4*atemp;, 4 - samples, 3.3 - mbed pin modifier, 16 and 20 - LEM configuration

Consider that atemp is the sum of 4 ain samples; each ain equals a constant offset Vout (which is nominally 2.5V), plus a variable term Ip * K, where K = 625mV/15A = 41.67 mV/A. Also, ain is scaled by 1/2 due to your resistor network, and referenced to 3.3V by the ADC.

So after 4 samples, atemp = 4 * (Vout + K Ip) / (2 * 3.3).

Combining terms, atemp4 = 0.606*Vout + K'Ip; where K' = 625mV *4)/(15A * 2 * 3.3V) = 25.2mv/A.

The line of code quoted above multiplies this by 13.2, then subtracts 20.00. This gives atemp = 13.2 * 0.606*Vout + 13.2K'Ip - 20.0.

Now if Vout equals 2.50V exactly, the first term is 20.0, and the trailing "-20.0" cancels it exactly. (We ignore the Ip term for now, as Ip is zero. But in your application, you will need to account for its scaling.)

Referring to the datasheet, we see that Vout may be anything from 2.475V to 2.525V. Any deviation from the ideal value will show up magnified by (13.2 * 0.606) in atemp - an 8x multiplication.

The error in Vout can arise from part tolerances, from thermal drift, residual voltage after overload, etc.

Summing the squares of this 8-fold magnified error leads to the sort of cumulative error you are seeing in the final result, I suspect.

You could try removing the offset term from each sample as it is taken (by subtracting 2.5V/(2 * 3.3V)) from ain, and re-do the remainder of the code correspondingly. That will reduce the sensitivity to the error somewhat.

But what you really need is some sort of D.C. removal algorithm that will dynamically determine the operating point...

Good luck.