Battery level indicator with Arduino analog pin


The Arduino mini pro (8MHz) operates at 3.3V and has a 10-bit ADC, i.e., a read on an analog pin can return a value from 0 to 1023. Each value corresponds to 3.3/1024 volts or 3.22 mV. If you’re running Arduino on a battery, then you would want to get an idea of the remaining level of the battery. One way to do this, is to use a voltage divider (you don’t want the voltage input to the analog pin to be greater than 3.3 V, hence the need for the divider) to provide about half of the VCC as input to the analog pin. I use a 3.6V battery, and based on a voltage divider with two 1.2KΩ resistors, the voltage associated with each of the 1024 point values is 3.27 mV. This value can then be used to get a reasonably accurate estimate of the current battery voltage level. For instance, if the value of the analog pin is 544, then 544*0.00327*2 will give you the current battery level.

9 Responses to “Battery level indicator with Arduino analog pin”

  1. Matt E Says:

    A note about the voltage divider, if you wish to utilize the complete range of ADC resolution, 0-1023 instead of only 0-558, use a resistor ratio of 1:1.091 (3.6V / 3.3V) instead of 1:1. Try a 1.2K from ADC pin to 3.6V and a 1.309K from ADC pin to GND. Then a ADC reading of 1023 will represent 3.6V instead of a reading of 558. That should almost double the resolution of voltage monitoring. Make sure that if the battery voltage goes higher, possibly due to charging, that you use the highest voltage (approx. 4.2) divided by 3.3 for the correct ratio.

    • Shahram Javey Says:

      Excellent hint. Thank you. Although for Lithium-thionyl chloride batteries this method of monitoring voltage is not that effective, since these batteries manage to maintain 3.6V almost for their entire life-time and then just go over the cliff and die. An alternative is to keep track of the time (current draw) of the main part of the system and tally it up on the server and thus come up with an approximate measure of when the batteries ought to be replaced.

  2. Matt E Says:

    Upon doing further voltage divider work of my own, I realized my comments earlier are incorrect. Best to checkout http://en.wikipedia.org/wiki/Voltage_divider for a better formula.

  3. lesion Says:

    I don’t know how you can sense the voltage this way, as analogRead returns the read value referenced to the current voltage supply. I’m interested to sense the battery level but from an analogInput you’ll always see ~512 (half 1023 for equal value of R1 and R2) also if voltage from battery is 2V.

  4. themastiff.org/ Says:

    It’s really a cool and helpful piece of information.
    I am glad that you shared this useful information with
    us. Please keep us informed like this. Thanks for sharing.

  5. memoryleach Says:

    The description of how to set up voltage sensing on an analog pin is correct, except that for a 3.6 volt battery each ADC bit would equal 3.52 mV not 3.27mV.

    @ lesion: You state that “analogRead returns the read value referenced to the current voltage supply”. Actually, analog to digital conversion is relative to the Vcc, so that for a 3.3 volt board like the Pro Mini board in question 1023 equals 3300 mV.

    Using a 1:1 divider we can safely measure a nominal 3.6 or 3.7 V supply, for instance a 1S LiPo battery, even if it is overcharged to say 4.2 V, by simply doubling the potential read at the divider.

    Say we get an ADC value of 575. That’s (575/1024) * 3300mV * 2 = 3706 mV or 3.7 V for the “raw” (supply) voltage.

    At least, that’s the way it works for me :-)

  6. Mark Gray Says:

    You should perhaps consider the usefulness of the battery meter. Most people use a dry cell, often rechargeable. Let’s take a Li-Pol, operating at a nominal 3.7V
    The protective circuit normally used with a single cell Li-Pol will not allow voltage to drop below 3V (to prevent cell damage). Following a full charge, you can expect the cell voltage to have increased to as much as 4.2V.
    So the useable voltrage you want to measure is really only between 4.2 (full power – 100%) and 3V (fully discharged – 0%). This allows you to change your cells before that critical low voltage shut-down occurs!
    So – its only 1.2V full scale deflection you need, from 3 to 4.2V isn’t it?
    That being the case, rounding to 1.1V can be useful, as the ‘secret’ internal voltage reference is 1.1V so integers can be used to measure 0-100% power remaining.
    As for electronics, you will need a potential divider to reduce input by a suitable amount – to ensure the analogue input has full scale readability 0-255.
    It is a simple case of using map(inputVolts, 0, 100, 0, 255) to scale the inmput to a percentage
    Does this sound more suitable for a ‘power capacity’ or ‘power left’ meter reading.
    A serial.print message can send you the figue to your PC, or to an OLED – using serial, SPI or I2C, if pins are at a premium.

    Please provide feedback on this comment – does it sound right?

    thanks for reading – hope it helps in scaling your meter to useful levels.

  7. Mark Gray Says:

    Sorry, the map command should read ‘map(inputVolts, 0, 1023, 0, 100);’ This is becasue analogue iputs have a resolution (can read up to) 1024 so map changes the 1024 voltage steps and changes them into a percentage (0-100).
    If you serial.println and/or display.println(“power “, inputVolts, ” %); you will see the correct reading – assuming you have chosen the correct value resistors to provide the voltage divider.
    You could use a 6V zener and resistor for the negative side of the voltage divider (zener in reverse of course), and a resistor to limit current and set the 2V full scale deflection. Analogue input would be taken directy after first resistor (before the second resistor and zener).
    Experiment with resistor values and a voltmeter before attempting to connect your voltage divider (and zener, if used) to the Arduino. You need to calibrate to produce the 0-2.2V full scale voltage variation by adjusting resistor values. when correct, you can connect knowing you are not going to blow up the Arduino.
    Remeber: you cannot supply a higher voltage to the analogue inputs, than is being used to power the arduino.
    Ensure the ground and negative of your voltage divider being used to measure battery condition are tied together.
    Hope the comments help.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: