22
\$\begingroup\$

I'm looking to make a battery life indicator that I can use in conjunction with a micro-controller. I'm hoping that I can then read the current battery life remaining and increasingly put the micro-controller to sleep to preserve battery life.

\$\endgroup\$
  • 1
    \$\begingroup\$ Which microcontroller? \$\endgroup\$ – Brian Carlton Apr 15 '10 at 14:35
13
\$\begingroup\$

To the primary question, as to how to measure the voltage of a battery, the most simple method is to use one of the ADC pins on the arduino.

If you're providing 5v from the battery (unlikely), then you can run the + straight to one of the analog in pins, and use analogRead() - each increment in value (from 0-1023) will represent 4.9mV. So multiply the read value by .0049 to get the volts read.

If you're running higher than 5v (more likely), you can use a voltage divider circuit (see: http://en.wikipedia.org/wiki/Voltage_divider) to bring the voltage you're sending to the analog input to <= 5v. If you're running 12V, you'll want to divide the voltage into roughly 1/3. Then, after multiplying the ADC value, multiply by 3 to get actual voltage.

Thus, if using 12V, and a 1/3rd voltage divider:

#define BAT_PIN 14

float read_batt_volts(void) {

  int val = analogRead(BAT_PIN);

  float volts = (float) val * (float) 0.0049 * (float) 3;

  return(volts)
}

!c

\$\endgroup\$
  • 2
    \$\begingroup\$ I have two major things to add to this. First, most 12V batteries do not die at 0V, but instead at something quite close, at least within 5 V, of your full charge voltage. A common technique to get higher resolution measurments in the operating range is to step down the voltage with a zener diode. A resistor in series with a zener and you measure across the resistor. Second, most people do not realize you need to draw current from a battery to get a good idea of the power left. \$\endgroup\$ – Kortuk Nov 24 '09 at 8:18
  • \$\begingroup\$ @Kortuk: Could you make two clarifications for my learning: (1) To get within the pin-accepted voltage range, are you suggesting that the zener-diode approach will give higher resolution than the voltage divider method? (2) Why did you make a particular mention here that "you need to draw current...", etc.? \$\endgroup\$ – boardbite Aug 25 '12 at 12:10
22
\$\begingroup\$

tinker.it published a "secret" voltage level meter in the Atmega168/atmega328. With a little trick an Arduino is able to compare VCC against an internal precision 1.1v reference. The explanation and the code is here: https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

\$\endgroup\$
  • \$\begingroup\$ excellent, I am running an atmega on batteries, and was not able to have a reliable vref value. thanks for posting this, it solved my issue like magic! \$\endgroup\$ – radhoo Jul 9 '13 at 18:29
10
\$\begingroup\$

shutterdrone's suggestion is very good, but is missing a detail, as it implies that the analog voltage reference is the same as the voltage being measured (aside from assuming that an Arduino is being used, which is not explicitly stated).

You'll need an ADC, whether it's integral to your uC or an external component. The ADC needs an analog voltage reference (ARef) to compare the input with. You don't want the ARef to be the same as the voltage you're sensing because then the ADC will always see the input and reference voltages as being equal, so the analog value for the sensed voltage will always be the maximum. What you need is a very accurate analog voltage reference that won't change as the power supply voltage changes. The ADC will compare that reference voltage to the battery voltage; you can use a voltage divider to reduce the battery voltage being sensed into the range of the ARef.

The Arduino (Atmega8/168/328/etc.) has a built-in ADC and a built-in 1.1V analog reference, so the only external components you'd need are resistors for the voltage divider. I think you would also want to use very high values for the resistors to reduce the current drain on the battery.

\$\endgroup\$
  • 2
    \$\begingroup\$ Excellent points - and you are correct that I (incorrectly) assumed an Arduino in the mix. =) !c \$\endgroup\$ – shutterdrone Nov 3 '09 at 17:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.