analogRead current shunt jumps in fixed steps.

Hi

I use two analogRead inputs over a 0,1 ohm shunt to read the voltages and then convert that to amps.

In theory the circuit works...but.

The amps reading jumps in 0.25A steps.

Does not show 1,12A or 1,21A or 1,35A

When I slowly increase the amps from 1A the next change in value will be 1.25A then 1.5A and the

next value is 1,75A there is never any values in between.

The 10 readings total is divided by ten to get a more stable reading.

Please help to solve this.

Thanks.

 #include <LiquidCrystal.h> //Arduino standard LCD Library
     
    int tempPin = 0;
    int lightPin = 1;
    const char TAB = '\t';
     //               B1  B0
    //                CS  E  D4  D5  D6  D7
    LiquidCrystal lcd(8, 9 , 4 , 5 , 6 , 7);
     
    void setup() 
    {
      Serial.begin(9600);  
      //Serial.println("Arduino LCD Library");
      
      lcd.begin(16, 4);
      
      //analogReference(INTERNAL);//1.1V ..
    }
     
    void loop()
    {
      int dummy1 = analogRead(A0);
      int readA0_1 = analogRead(A0);
      int dummy2 = analogRead(A1);
      int readA1_1 = analogRead(A1);
      
      int dummy3 = analogRead(A0);
      int readA0_2 = analogRead(A0);
      int dummy4 = analogRead(A1);
      int readA1_2 = analogRead(A1);
     
      int dummy5 = analogRead(A0);
      int readA0_3 = analogRead(A0);
      int dummy6 = analogRead(A1);
      int readA1_3 = analogRead(A1);
      
      int dummy7 = analogRead(A0);
      int readA0_4 = analogRead(A0);
      int dummy8 = analogRead(A1);
      int readA1_4 = analogRead(A1);
      
      int dummy9 = analogRead(A0);
      int readA0_5 = analogRead(A0);
      int dummy10 = analogRead(A1);
      int readA1_5 = analogRead(A1);
      
      int dummy11 = analogRead(A0);
      int readA0_6 = analogRead(A0);
      int dummy12 = analogRead(A1);
      int readA1_6 = analogRead(A1);
     
      int dummy13 = analogRead(A0);
      int readA0_7 = analogRead(A0);
      int dummy14 = analogRead(A1);
      int readA1_7 = analogRead(A1);
     
      int dumm15 = analogRead(A0);
      int readA0_8 = analogRead(A0);
      int dummy16 = analogRead(A1);
      int readA1_8 = analogRead(A1);
     

      
      int dummy17 = analogRead(A0);
      int readA0_9 = analogRead(A0);
      int dummy18 = analogRead(A1);
      int readA1_9 = analogRead(A1);
     
      int dumm19 = analogRead(A0);
      int readA0_10 = analogRead(A0);
      int dummy20 = analogRead(A1);
      int readA1_10 = analogRead(A1);
     

     float avgA0 = (readA0_1+readA0_2+readA0_3+readA0_4+readA0_5+readA0_6+readA0_7+readA0_8+readA0_9+readA0_10)/10;
     float avgA1 = (readA1_1+readA1_2+readA1_3+readA1_4+readA1_5+readA1_6+readA1_7+readA1_8+readA1_9+readA1_10)/10;

     float loadVolts = avgA1 - avgA0;
     float amps = (((4.5 / 1023.0)*loadVolts)*5.7)/0.1;//
     
    String SPACE = "   ";
    String A0 = "A0:";
    String A1 = "A1:";
    String AMPS = "AMPS:";
    String ALL = A0 + avgA0 + SPACE + A1 + avgA1+ SPACE + AMPS +amps;
     Serial.println(ALL); 
    
      lcd.setCursor(0, 0);
      lcd.print(amps);
      lcd.print(" Amps");
     
     lcd.setCursor(0, 0);//NB restore cursor

    
      delay(200);
    }

mikedb:
float loadVolts = avgA1 - avgA0;
float amps = (((4.5 / 1023.0)*loadVolts)*5.7)/0.1;//

Hi there!

In the above equation, would you mind explaining where the 4.5 and 5.7 come from?

Type in you're calculator:
4.5/1023*5.7/0.1

Does the answer sound familiar?
Also note, 1023 should be 1024 :wink:

Aka, you're drop across the resistor is just to little it's in the order of single LSB per 0,25A

Also heart of loops and arrays? That would safe you from writing the mess :wink:

And using float WILL hurt the precision although not a lot. But it WILL take an awful lot more time.

And if you don't want the reading, just don't assign it to anything. Would safe you from all the dummies. But better then reading twice would be to stabilize the analog voltage with a small cap :wink:

Also, don't use String. Just print it to serial and/or the display in parts :slight_smile:

mikedb:
I use two analogRead inputs over a 0,1 ohm shunt to read the voltages...

Shared ground?

analogRead is relative to GND on the processor.

Posting a schematic is always a good choice.

First of all, you should make a function to read an average instead of scaring the living daylight out of ppl with your code:

float getAverage(byte pin, byte numReadings = 10)
{
  float res = 0;
  for (byte i = 0; i < numReadings; i++)
  {
    analogRead(pin); //Dummy reading
    res += analogRead(pin);
    //Here should probably be a small amount of delay (1-5 ms)
  }
  return res / numReadings;
}

void loop()
{
     float avgA0 = getAverage(A0);
     float avgA1 = getAverage(A1);

     //Rest of code here
}

Why your calculations are bad, I cannot tell..

Thanks

The 4.5 is the reference voltage for the analog converter ,I might be wrong but I read that the reference is

supplied through a transistor with a 0.5V drop,I also read 4.5V on the reference pin on the arduino.

If this is incorrect I will change back to 5V.

The 5.7 is my resistors voltage divider ,before I divided with the 0.1 ohm to get Amps I tested the

voltage readings to make sure it is correct.

The string convertion is to display one line in the serial monitor with all the relevant information measured

in one loop.

I see some truth in the LSB bit that carries a value of 0.25 ,I did find that 1 bit changes 0.25 in the reading.

For a very low shunt value this does not work, need to use a op amp??

I use one 12V power supply positive to the arduino Vin and to the shunt.

The other side of the shunt goes to negative of the power supply negative to the arduino ground.

Thanks for the rest of the info.

First

question,

why

all

the

blank

lines?

mikedb:
The 4.5 is the reference voltage for the analog converter ,I might be wrong but I read that the reference is
supplied through a transistor with a 0.5V drop,I also read 4.5V on the reference pin on the arduino.

By default the reference of the analogRead is Vcc. If you have a crappy supply that may indeed be 4,5.

mikedb:
The 5.7 is my resistors voltage divider

Voltage divider? For a shunt?

mikedb:
The string convertion is to display one line in the serial monitor

That's just bull :wink: The Serial Monitor only goes to a new line with, drum roll please, a "new line"-character. So:

//or you call println() (ln for line)
Serial.println("Hello");
//or by printing it in a string with the '\n' aka new line character
Serial.print("wor\nld");

And in serial there is NO difference for the receiving side between:

Serial.println("foobar");

and

Serial.print("foo");
Serial.println("bar");

mikedb:
For a very low shunt value this does not work, need to use a op amp??

Depends, is that shunt on the low side? If so, you can switch to the 1,1V reference and get a LSB of 1,07mV instead of 4,39mV (with 4,5V).

If you really really want it on the high side (come with a good reason ;)) you might want to use an opamp indeed. That can do the differentiation and add gain.

septillion:
Voltage divider? For a shunt?

If only...

What

blank

lines

?

This arduino current meter is just one of many samples that can be googled,the only difference is they all

use 10 or 22 ohm shunt with a much higher voltage drop and then only read a few milli amps.

The only way to get a circuit on this post(for me) is to hand draw it and take a very low pixel photo

and then post it.(must be below 1.2meg).

Thanks.

mikedb:
The only way to get a circuit on this post(for me) is to hand draw it and take a very low pixel photo

This blank line.

mikedb:
and then post it.(must be below 1.2meg).

Which means the only thing stopping you from posting a schematic is you.