Measure Voltage on Batteries in Series

I would like to use an Arduino to monitor a couple of UPSs that I have. One has 4 (12 Volt) batteries connected in series and the other 6 batteries in series. I know I can use a voltage divider for the entire bank of batteries but I would like to measure each battery 's voltage individually. I am having difficulty finding an appropriate answer to my dilemma. Any help would be greatly appreciated.

One approach would be to use each battery to power a small circuit that drives an analog optoisolator:

Each optoisolator output could then be read by a separate A/D pin.

You could also use 6 voltage dividers, one for the first battery, another for the first two batteries in series, another for the first three batteries in series, etc. Then, using software you can just subtract adjacent readings to get individual battery pack voltages.

-- The Rugged Motor Driver: two H-bridges, more power than an L298, fully protected

We had a whole big thread on this not too long ago.

I had this suggestion, to have a relay pair for each battery that could be connected to the A/D converter. Requires the arduino to run off floating ground so the battery being measured had the same ground as the arduino. This was for a string of smaller voltage batteries, so stick in appropriate voltage dividers and the serial register/demux/whatever of your choice to control turning on 1 relay at a time.

I know I can use a voltage divider for the entire bank of batteries

As you can for the points in between the batteries on the first bank you have 12, 24, 36 and 48v (nominal) so you can just hook up 4 voltage dividers, either all the same (scaled for the 48v) or individualy scaled for the expected max at each point.

Also, if these are being charged then you may have up to 60v on a "48v" bank so scale the dividers for that.

The other bank is the same just more dividers.

EDIT: Just reread RC's post, what I suggested is the same as his 2nd option.


I saw the thread about using the relays. That just makes me a little nervous. If I write the code incorrectly or something in the arduino fires the wrong relay at the wrong time bad things could happen.

I like the optoisolator plan even though it does add a good bit to the cost. I was thinking the link to the level shifting doc would work for me - - but my lack of knowledge of optoisolators fooled me. I thought that would give me an analog output not a switched output.

I was actually writing out a voltage divider ladder if you will for calculating the voltages of each battery and subtracting each. My thoughts were:

(assuming 12v exact for easy calculations) Across the 1st battery use a 2k and 1k and read the junction (should be 4 volts) Across the 2nd + 1st battery use a 5k and 1k and read the junction (should also be 4 volts) Across the 3rd + 2nd + 1st battery use a 8k and 1k and 1k and read the junction (should also be 4 volts) ....

Would there be a better way as I believe my resolution would drop as I add more batteries.

Also, could I shrink the range using the optoisolators? For example, make the range be 4-7v (being full range) instead of 1-10 to give a better resolution. I cannot think of a way using only a resistor network.

If you want full resolution for each battery then something like RC proposed with an isolated circuit on each battery would be the go.

You could have VCOs and read the frequency or ATtiny85s and read a serial value. VCOs probably better if you can get 12v versions that don't need a regulator.


Here is a pre-packaged solution.

You can get one of these, then use the relay method to switch it into the circuit at the correct point, whilst maintaining total isolation from all of the potentials within the battery string. Alternatively you can put 2 or 4 or whatever units directly into the battery string, and then have them simultaneously feed multiple A-D inputs.

They are not super cheap, so the relay approach would keep costs down. If the relays each have a 200mA fuse and work on a 3:1 voltage divider, you should be good.

This is one of my hobby-horses, but I also am not keen on wasting A-D input range on the voltage range from 0 to 10V on a lead acid 12V battery. This range indicates total failure and is quite uninteresting. What I have done is inserted a 10V zener diode so that you are instead looking at the interesting part of the charge/voltage range 10V..15V

Lets try a simpler approach We know the a simple voltage divider with Vin feeding R1 to R2 to gnd and Vout at the junction of R1/R2 is this simple equation Vout = Vin * R2/(R1+R2) If we do a little rearranging, we can solve for R2 with everthing else known. R2 = Vout * R1/(Vin - Vout) Plug that into excel with some values & solve for R2:

R2 Vin Vout R1 7142.857143 12 5 10000 2631.578947 24 5 10000 1612.903226 36 5 10000 1162.790698 48 5 10000

Select standard R2s that are the next value up to ensure that Vout does not exceed 5V: R1 R2a R2b Vout 10000 6800 330 4.99474606 10000 2200 390 4.937251787 10000 1500 100 4.965517241 10000 1000 150 4.950672646

Or increase the total R2 as needed if Vin could go higher, say if measured while being charged. If the 12V is low, it will bring the rest of the chain down, so do some math to see what that 24V really is.

Then just do a circuit like below. If it turns out not to be accurate enough, can always go with one of the more complex solutions.

An external A/D can always be added then, get 24 bit resolution with serial output for <$4 from analog devices.

Can probably get a free sample to check it out with even.