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.
August 22, 2009 at 7:15 pm |
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.
August 22, 2009 at 7:31 pm |
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.
October 17, 2009 at 10:41 pm |
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.
May 16, 2011 at 8:07 pm |
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.
May 16, 2011 at 8:32 pm |
it’s an hack, but i’ve found a solution here: http://code.google.com/p/tinkerit/wiki/SecretVoltmeter
July 2, 2012 at 8:05 pm |
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.
August 31, 2012 at 9:59 pm |
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
January 17, 2013 at 2:58 pm |
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.
January 18, 2013 at 7:52 am |
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.