Go Down

Topic: How to test battery level with Arduino? (Read 113767 times) previous topic - next topic

Mastino

Hello everybody!
I have a little problem, how can I measure battery level with arduino? I want to measure the same battery from which Aurduino works. You can see it on the picture. If I connect this way(see on the picture) arduino do not shows me the voltage, because it use the same battery. Thank you!


MarkT

You've connected GND and '+5V' to the same breadboard rail...

Also you can't measure the battery voltage this way if its also the supply, since the ADC outputs the ratio between the ADC input and the ADC reference (which defaults to the supply voltage).  So you'll just measure a ratio of resistors this way.

However it is possible to set the AREF pin to an internal 1.1V reference  source, analogReference(INTERNAL).

But then you'll have to make sure the resistor divider takes the battery voltage below 1.1V. 

Alas the 1.1V on chip reference is not very accurate between different chips, the datasheet says its between 1.0 and 1.2V, which is +/-10%...
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Mastino

So what should I do? How should I connect? Which components I need?
Thank you very much!

xl97


So what should I do? How should I connect? Which components I need?
Thank you very much!


look at the two blue lines/wires coming form your Arduino from the GND & v5+ pins..

you have them BOTH going to the same rail/place..  (the V++ of the battery pack)..

the GND line from Arduino needs to be moved to the GND rail/GND output of the battery pack.


retrolefty

#4
Feb 15, 2012, 06:13 pm Last Edit: Jan 25, 2015, 02:35 am by Coding Badly Reason: 1
First your drawing is flawed in that you show a 9vdc voltage source powering the +5vdc pin which of course would damage the board.

Now assuming you are powering an arduino board directly with batteries (which must be limited to +5.5vdc max or damage to the board is possible), is there a way to measure the battery voltage? Note that this does not apply if you are powering your board via the external power connector or the Vin pin using a battery voltage between 6-12vdc. In that case you only need to use a simple two resistor voltage divider to scale down the battery voltage to a value that stays within the normal 0-5vdc measurement range for a analog input pin.

But again if you are powering the board directly with batteries via the +5vdc pin, yes there is a way to measure the actual battery voltage on the run. It's not simple and utilizes some tricky coding but it can be done. Here is a sketch that will perform that task and also allows any analog readings to be 'corrected' on the run as the battery voltage lowers while being discharged. The comments should explain how the method works.

Note: not tested under new Arduino IDE 1.0, but does run under V22.

Code: [Select]

// Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference
// This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc
// Now works for 168/328 and mega boards.
// Thanks to "Coding Badly" for direct register control for A/D mux
// 1/9/10 "retrolefty"

int battVolts;   // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc

void setup(void)
    {
     Serial.begin(38400);
     Serial.print("volts X 100");
     Serial.println( "\r\n\r\n" );
     delay(100);
    }
    
void loop(void)
    {
     battVolts=getBandgap();  //Determins what actual Vcc is, (X 100), based on known bandgap voltage
     Serial.print("Battery Vcc volts =  ");
     Serial.println(battVolts);
     Serial.print("Analog pin 0 voltage = ");
     Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
     Serial.println();    
     delay(1000);
    }

int getBandgap(void) // Returns actual value of Vcc (x 100)
    {
        
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
     // For mega boards
     const long InternalReferenceVoltage = 1115L;  // Adjust this value to your boards specific internal BG voltage x1000
        // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc reference
        // MUX4 MUX3 MUX2 MUX1 MUX0  --> 11110 1.1V (VBG)         -Selects channel 30, bandgap voltage, to measure
     ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
  
#else
     // For 168/328 boards
     const long InternalReferenceVoltage = 1056L;  // Adjust this value to your boards specific internal BG voltage x1000
        // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc external reference
        // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG)         -Selects channel 14, bandgap voltage, to measure
     ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
      
#endif
     delay(50);  // Let mux settle a little to get a more stable A/D conversion
        // Start a conversion  
     ADCSRA |= _BV( ADSC );
        // Wait for it to complete
     while( ( (ADCSRA & (1<<ADSC)) != 0 ) );
        // Scale the value
     int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L; // calculates for straight line value
     return results;
 
    }

Mastino

retrolefty - this is exactly what I need! Can you describe me in few words how I should connect (to which pins) arduino and battery? The code seems very difficult to me..:) How should I configure this code to adapt it to my board(Arduino Mega 2560)?
Thank you very much!

retrolefty


retrolefty - this is exactly what I need! Can you describe me in few words how I should connect (to which pins) arduino and battery?

That depends of the battery voltage you are using, type as well as voltage. The program just measures what voltage is present on the chips Vcc pin. Again, I would need to know what battery voltage you are using to tell you more.

The code seems very difficult to me..:) How should I configure this code to adapt it to my board(Arduino Mega 2560)?

The sketch is already set up to handle either 328p or mega1280 or mega2560 chips automatically. How to adapt the sketch to your on application sketch is not a simple task and I don't really know how to guide with that. What is your sketch overall objectives?


Thank you very much!

Your welcome.

Lefty

Mastino

#7
Feb 17, 2012, 07:53 pm Last Edit: Feb 17, 2012, 07:55 pm by Mastino Reason: 1
I have 9 AA 1.2v batteries. So 10.8V from all 9 batteries.
For what I need that?
1. I want send the data to my processing program. So I will see how much % of battery is available(100-90% full, 40-50% middle and 20-30%low), you know like on the mobile phone.
Also I want to use the data in the code, for example if there are about 20-30%, the robot goes to docking for charge.
Thank you for your attention and help!

retrolefty


I have 9 AA 1.2v batteries. So 10.8V from all 9 batteries.
For what I need that?
1. I want send the data to my processing program. So I will see how much % of battery is available(100-90% full, 40-50% middle and 20-30%low), you know like on the mobile phone.
Also I want to use the data in the code, for example if there are about 20-30%, the robot goes to docking for charge.
Thank you for your attention and help!



For that you don't need my program at all. Just wire the 10.8vdc battery voltage to either the arduino external power connector or the shield Vin pin.

Then use a two resistor voltage divider of the proper values connected to the 10.8v and wire the junctions of the resistors to a analog input pin.

Lefty

Mastino

The problem is that my arduino works from the same 10.8V battery.

Grumpy_Mike

Quote
The problem is that my arduino works from the same 10.8V battery.

Why is that a problem?
The arduino has a 5V regulator giving you a 5V voltage reference against which you can measure your varying voltage from the battery.

retrolefty


The problem is that my arduino works from the same 10.8V battery.


Again that is not a problem. The +10.4 volt battery terminal would just wire to two places, 1. to the arduino Vin pin and 2. to the top of a two resistor voltage divider.

Lefty


Mastino

You mean like this?:


If yes, it doesn't work. It is the same if you take a multimeter and you will try to measure the battery inside it. It don`t shows you the voltage, because the multimeter takes the power from this battery for it self. But if you will measure another battery, it will show you the voltage. I think the same is with arduino.

Grumpy_Mike

You are wrong it does work because the 5V reference is regulated and the battery voltage you are measuring is not.

retrolefty


You mean like this?:


If yes, it doesn't work. It is the same if you take a multimeter and you will try to measure the battery inside it. It don`t shows you the voltage, because the multimeter takes the power from this battery for it self. But if you will measure another battery, it will show you the voltage. I think the same is with arduino.


I'm sorry, not a single thing you said is that statement makes any sense to me or is just not correct. Of course you can measure a battery's voltage even if it's powering another load, in fact that is preferred way. as voltage under a normal load is a more accurate representation of a battery's actual terminal voltage.

Lefty

Go Up