Measure voltage on 12v SLA battery with arduino

Dmm

Joined Apr 13, 2015
58
I've been reading how to measure voltage using an arduino uno (cheap knock off) analog pin. I have a project that will be powered by a 12v SLA battery. I do have a 7805 to get 5v to the arduino and a few components. I would like to turn on a red LED when the voltage gets down around 11v as that is when the battery is considered low and should be put on a charger. I also intend to eventually use a barrel jack connector so you can use a 12v wall wart to power the circuit in addition to using the battery. The barrel jack would have a switch that would disconnect the battery when you plug in the adapter. I've read power adapters can output more than their rated voltage, some quite high. I suppose it may come down to you get what you pay for.

I plan to use a voltage divider to bring the input voltage (battery, or adapter) down to 5v max to use on the arduino pin, and I'm worried about putting more than 5v on the analog pin. A website I found shows the use of a zener diode and capacitor to help protect overvoltage on the pin. I'm still learning a lot, I'm definitely new to most electronic designs, but this seems to make sense to me after reading through it. I've included a screen shot in the attached Circuit-1.png file. I've seen some websites that just use the divider, and some that use the divider with just the zener diode. And then this one which includes the capacitor. I guess my first question is I'm just looking for confirmation/discussion if this is a decent circuit to use to measure the voltage? Seems easy and simple. I realize the addition of the adapter (or more specifically, 2 power source options with different "fully charged" values) doesn't help matters. I don't have the wall adapter so for now, I'll have to assume a maximum voltage that would supply the power and then test when I do get a 12v wall adapter.

Second question: If I over assume say 20v max input and the divider is designed to bring 20v down to 5v (20 / 4 = 5), then a full battery charged is around 13v, so would the divider read a full battery at 13 / 4 = 3.25v on the arduino input pin? I know I need to look up voltage divider calculator, I'm sure that will help me with this question. It's on my to do.

Third, do you need a resistor in series with the zener to control current through it, similar to an LED+resistor setup?

I think I'll have a transistor connected to another arduino pin to "turn on" the measuring circuit so it isn't drawing power constantly. I'm sure I'll have a few more questions down the road.

Attachments

• 64.3 KB Views: 14

Joined Feb 20, 2016
4,177

Something like this will work.
The 2 reverse connected diodes clamp the ADC input voltages to safe limits.
And, yes, you always need a series resistor of some sort with a Zener, even if it is just the internal resistance of the source voltage device.

Dmm

Joined Apr 13, 2015
58
Thank you for your input. I'll have to study that diagram more to understand what's going on. I think I saw something similar but I didn't understand connecting to the 5v on the microcontroller. My thought now looking at your diagram, is when the input voltage to the analog pin is less than 5v, the top diode (connected to +5v) would normally allow voltage/current to flow (forward bias) but since it's connected to the +5v at the cathode, the anode side is a lower potential so it does not flow into the +5v arduino pin. So the diode is reverse bias when less than 5v is on the pin. As long as breakdown voltage is higher than 5v then that acts like an open circuit, correct? So this protects the input pin when higher than 5v is at the input pin? Assuming the input pin sees a voltage in the range of 0 to 5 volts, this diode will always be reverse bias, and always an open circuit? But that's the "what if" protection if it somehow gets higher than 5v, then it (the arduino input pin) is protected?

Something not obvious to a noob, what happens if you have say 20v there, is it okay to put that on the 5v input of the arduino? I thought that had to be a well regulated voltage that didn't stray much from 5v. I am powering the arduino with the 5v output from the 7805 into the 5v pin on the arduino.

Going back to the zener circuit I referenced...If I add a resistor to the zener circuit is there any drawback to using that circuit? Just uses less components and at this time I can follow the zener circuit and understand it better (I think.) I also came across this video (at 22:25) which shows the zener circuit to limit voltage into the input pin, but does not use the capacitor so even less components.

I need to search clamping diodes I think to learn more about your diagram. It's hard for a noob to wrap mind around the diode and how it limits the output voltage. I've read and seen more videos so it's starting to make a little more sense. The lower diode (between input pin and GND/COM) I'm not sure I understand its purpose.

My design assumption is the input voltage won't be drastically high. Meaning I always use a 12v battery, not a 24v or 6v, and charge it when it gets around 11v. And if using an AC to DC wall adapter, it would be rated at 12v, but may stray depending on the quality. It won't ever be AC voltage input to my circuit. But with the adapter, maybe you get some variation depending on the quality of the adapter? Not sure if that changes any thinking on the circuit. Does your diagram with clamping diodes provide "more" or "better" protection for higher (or varying) voltages than just a zener diode? I'm thinking a voltage divider to bring down to 5v (and I have to assume an upper limit input voltage to design the divider) and then use a 5v zener incase the voltage is over my design and the divider creates more than 5v would work. What am I missing? Or do both circuits work and there are advantages/disadvantages to either of them?

Ya’akov

Joined Jan 27, 2019
6,270
I've been reading how to measure voltage using an arduino uno (cheap knock off) analog pin. I have a project that will be powered by a 12v SLA battery. I do have a 7805 to get 5v to the arduino and a few components. I would like to turn on a red LED when the voltage gets down around 11v as that is when the battery is considered low and should be put on a charger.
Do you intend to have the Arduino do any besides light the LED?

Dmm

Joined Apr 13, 2015
58
Do you intend to have the Arduino do any besides light the LED?
I don't think it makes much of a difference, but I will be using a nano instead of uno mentioned originally.

Yes, there will be 6 buttons, couple pins to control 2 single leds, two pins to send WS2812b signal (individually addressable LED strip,) 6 pins for rotary encoder inputs w/ momentary switch, 1 pin for a POT, possibly a phototransistor input to automatically control brightness. And if I can get it to work a couple pins to read the battery voltage and to turn on the voltage reading circuit with a transistor. It's possible instead of a dedicated red LED indicator for low battery voltage, I may incorporate into the WS2812 LEDs somehow.

The arduino, buttons (each button has an LED in it as well,) rotary encoder, phototransistor, all are powered from 12v input -> 7805.

The WS2812b led strips are powered from the same 12v input -> 5v buck regulator -> LED strip
The regulator used on the LED strip is not the 7805 but a small PCB 5V/3A buck with LM2596 you can buy cheap online. I have 2 strips and each uses a dedicated buck.

The turning on of the voltage measuring circuit via a transistor may or may not be needed, and if not, that would free up a pin for me. I've read somewhere the voltage divider can be designed to use low amps relative to battery capacity so it may not be critical to turn that portion on and off just to check. The battery would be in the 5Ah to 10Ah range. And I estimate total amps of everything to be 4A max, but realistically maybe a max around 2.5 to 3. And quite possibly closer to a "normal operation" of 2A when brightness of the WS2812s isn't set to highest level (The POT is how I'm controlling the brightness of the WS2812 strip.)

Ya’akov

Joined Jan 27, 2019
6,270
I don't think it makes much of a difference, but I will be using a nano instead of uno mentioned originally.

Yes, there will be 6 buttons, couple pins to control 2 single leds, two pins to send WS2812b signal (individually addressable LED strip,) 6 pins for rotary encoder inputs w/ momentary switch, 1 pin for a POT, possibly a phototransistor input to automatically control brightness. And if I can get it to work a couple pins to read the battery voltage and to turn on the voltage reading circuit with a transistor. It's possible instead of a dedicated red LED indicator for low battery voltage, I may incorporate into the WS2812 LEDs somehow.
I am going to suggest you use this: https://datasheets.maximintegrated.com/en/ds/MAX8211-MAX8212.pdf which will do the work of monitoring the battery and provide a signal which you can use on an interrupt. Much more reliable, simpler, and more accurate.

Dmm

Joined Apr 13, 2015
58
I am going to suggest you use this: https://datasheets.maximintegrated.com/en/ds/MAX8211-MAX8212.pdf which will do the work of monitoring the battery and provide a signal which you can use on an interrupt. Much more reliable, simpler, and more accurate.
Looks interesting. But at $4.00+ and you still need to design a voltage divider, I'd opt for the divider+zener or dendad's solution. It's just a toy I'm making nothing too critical other than depleting the battery too far and its lifespan goes down. Yes$4.00 wouldn't break my budget, but "why" is my question if a few cheap resistors and diodes work? I do appreciate the suggestion. Just more fun parts to learn about! But with this part my disadvantages I see are more connections to solder and the $4 price tag - both minor issues. Accuracy would be nice, but if I'm off a volt and the user waits until the light goes on every single time before charging the battery the worst case is life span of the battery issue. Not that critical for me at the price of$15 to \$20 for a new battery.

Last edited:

Joined Feb 20, 2016
4,177
The 2 clamp diodes work by limiting the positive voltage and the negative voltage input to the ADC.
A Zenner will work too, as it will be forward biased for negative voltages, and breakdown for the positive.
But, the breakdown is not linear, so as it starts to breakdown, inaccuracies can be introduces to the reading.
The fix is to have the voltage divider set to make the Zener start to operate outside the expected input voltage range.
So, in this case, a max input of 20V is way outside the battery voltage so a 4.7V or 5.1V will work quite well.
I find it is always a good idea to add a capacitor to the ADC input, but that to may be omitted if you want.
So, the minimum configuration would be the 30K and 10K voltage divider with a Zener across the 10K one.
Just those 3 parts.
I'd still add the cap, but try it and see what changes in the reading are produced with it there or not. The cap filters out any noise and can supply a burst of current some ADCs need when they read.
And there is no need to switch the voltage divider off as it will only draw about 0.3mA.

Dmm

Joined Apr 13, 2015
58
So, the minimum configuration would be the 30K and 10K voltage divider with a Zener across the 10K one.
Ok, so this is what I'll proceed with. I've attached a schematic to look over with some info what I expect the arduino pin to read. Does this make sense?

One question I have is power and current on the components. Is this how that works...assuming 21v on the input:
R1 voltage drop is 21- 5.1 = 15.9 v and I=V/R = 15.9 v / 30,000 ohm = 0.00053 A or 0.53mA? Then power = VxA = 15.9v x 0.00053 A = 0.008 W, for R1?
How about R2 and the zener? The zener clamps the voltage between R1 & R2 at 5.1v when input voltage is 21v so would the power on R2, with Vin of 21v be -> voltage drop R2 = 5.1 v - 0 v = 5.1v and I=V/R = 5.1 v / 10,000 ohm = 0.00051 A or 0.51mA? Then power on R2 would be 5.1v x 0.0005 A = 0.003 W?

For the zener, looking at this datasheet they have steady state power rating of 300 mW, so the maximum current I should put on the zener using A = W / V = 0.30 W / 5.1v = 0.059 A, is that correct?

How do I know the current through the zener? Is the current through R1 the same as the current through the zener? Or does R2 (and/or R1) affect current on the zener?

Attachments

• 28.2 KB Views: 7

crutschow

Joined Mar 14, 2008
30,438
I would like to turn on a red LED when the voltage gets down around 11v as that is when the battery is considered low and should be put on a charger.
That's a little low.
For best battery life you don't want to go below 50% capacity which is about 12V.

Joined Feb 20, 2016
4,177
How do I know the current through the zener? Is the current through R1 the same as the current through the zener? Or does R2 (and/or R1) affect current on the zener?
There will be no current through the Zener under normal conditions.
And, yes, any Zener current will flow through R1. But, if you look at max R1 current with a 12V battery, it is less than 1mA. There is no problem with overloading the Zener current.

Joined Jan 15, 2015
6,822
As to the Arduino using an analog input channel the Arduino Uno or Arduino Nano results in a 10 bit (1024 quantization levels) analog to digital converter. Both use their VCC as their A/D reference voltage. Actually it's a ratio metric measurement so if powering the chip using 5 volts you want an accurate 5.0 volts. Keep in mind when using the external power jack applying 7 to 12 VDC the onboard regulator regulates down to about 5.0 volts. Whatever it actually is becomes the Vref (A to D reference voltage). The Arduino Uno I have laying here actually regulates an external 12 VDC to 4.80 VDC so my Vref is now 4.80 VDC and not 5.0 VDC, consider that in your code. So just as an example the typical code to measure a voltage would look like this:

voltage = value * 5.0/1023; / Convert the bit count between 0 and 1023 to a voltage 0 to 5.0 volts

This depends on the Vref being 5.0 volts. So in my example if my Vref is 4.80 volts the 5.0 in the above code would be changed to read 4.80.

Next since you want an increased range you would, as mentioned, use a voltage divider which would now become 0 to 20 volts ( a 4:1 Divider) is 0 to 5 volts. Then in your code you include the multiplier. Just remember the overall accuracy will only be as good as the tolerances of your resistive divider. The Zener Diodes are used as a safety feature to make sure the Vin to your micro chip (Arduino) never exceeds 5.0 volts. Keep in mind also a Zener has a knee curve so it is not like a 5 volt Zener diode goes into full on from off or no current to short current exactly at it's rated voltage. Data sheets should show you the curve.

Rather than using the old classic 7805 you may want to consider a 5 volt out buck converter. They offer a wide input range and stable regulated output and are very inexpensive through any component supplier including Amazon. You should have no trouble finding an adjustable one capable of two to three amps. This will allow you to power your Arduino on an accurate 5.0 volts.

That's a little low.
For best battery life you don't want to go below 50% capacity which is about 12V.
You really do not want to run a 12 volt SLA battery below 12 volts. That really starts reducing their life expectancy.

You can either use the voltage or bit count to set the limit(s) where you turn a LED On/Off. Just a matter of the code and how you want to do it.

Ron

Dmm

Joined Apr 13, 2015
58
That's a little low.
For best battery life you don't want to go below 50% capacity which is about 12V.
Thanks for the note. Thought I read somewhere 11v can go to, but that makes sense to limit to 12v. I guess it all affects life of the battery from what I have been reading? Maybe "deep cycle" or "marine battery" comes to mind??? Can they be discharged lower with less adverse effects?

Dmm

Joined Apr 13, 2015
58
There will be no current through the Zener under normal conditions.
That I follow and makes sense to me.

And, yes, any Zener current will flow through R1...
Not 100% clear to me but that's what I guessed, so I'm on the right track. I'm shaky on the math if my thoughts & numbers were right, is my 0.53mA calc correct for R1 when input is 21v? Back in post #9.

Dmm

Joined Apr 13, 2015
58
This depends on the Vref being 5.0 volts. So in my example if my Vref is 4.80 volts the 5.0 in the above code would be changed to read 4.80.
Thanks for this info. I've heard of Aref pin, but haven't investigated it other than knowing you can change reference voltage using the Aref pin. I can do some searching, but how do you measure the reference the board is using, just measure voltage on the Aref pin?

Keep in mind also a Zener has a knee curve...
I have heard of the knee before. I'll have to look at datasheets when I get to picking one out and keep this in mind.

Rather than using the old classic 7805 you may want to consider a 5 volt out buck converter.
I'm learning...and have a bunch of the 7805s around from learning how to use them. I also read somewhere microcontrollers like a clean 5v and the 7805 provides a cleaner voltage than a buck. True? Or is that a bad memory from reading too much too fast? Probably not an issue with my type of projects. I do have some of those cheap 5v/3a adjustable bucks and I am using 2 of them for my LED strips. Side note, I started working on PCB design and not sure if I'll put the bucks closer to the LED strips, or on my board with arduino. If on the PCB with arduino it would be easy to tap into that 5v. If not, then probably best for me to use the 7805 as they take up less room, and I can use up my stock...lots to think about down the road!

You can either use the voltage or bit count...
By "bit count" are you referring to the 0 to 1024 values? Setting limits in code I have a handle on. And thanks for 2nd opinion on the draining level of the battery.

crutschow

Joined Mar 14, 2008
30,438
Maybe "deep cycle" or "marine battery" comes to mind??? Can they be discharged lower with less adverse effects?
Yes, they have thicker plates that are designed to better tolerate discharge to a lower level of capacity.
You might consider one of those if you want to discharge your battery more than 50%.

Dmm

Joined Feb 20, 2016
4,177
I'm shaky on the math if my thoughts & numbers were right, is my 0.53mA calc correct for R1 when input is 21v? Back in post #9.
Yes, that is correct.
21V/40000R = .000525A

Dmm

Dmm

Joined Apr 13, 2015
58
Thank you all for the help. I'll have to get some parts in and start testing things out now.

Joined Jan 15, 2015
6,822
, just measure voltage on the Aref pin?
You can just measure the 5V pin.That will be whatever it's using for Vcc.

As to the 7805 I have used them in automotive applications the buck converter was just a passing thought. Check out a 7805 data sheet as you will want a few caps in there. A little filtering is a good thing.

By "bit count" are you referring to the 0 to 1024 values? Setting limits in code I have a handle on. And thanks for 2nd opinion on the draining level of the battery.
Yes, that is what I meant. Figure things this way. Your Arduino will see 0 to 5 volts. That divided down from 0 to 20 volts. The 0 to 5 volts is actually 0 to 1023 bits. With a 10 bit Analog to Digital conversion that becomes 5 / 1024 = 4.88 mV per bit or 4.88 mV is the best resolution we can get. So figuring the divider in there 12 volts becomes 12 / 4 = 3 volts so when your Analog to Digital channel sees 3 volts that is 12 volts applied. That would be about 614 bits.

Something else to think about is taking several samples or averaging.

Here is an example. This uses two channels but you will get the idea.
Code:
//--------------------------------------------------------------*/

// number of analog samples to take per reading
#define NUM_SAMPLES 10

int sum = 0;                    // sum of samples taken
unsigned char sample_count = 0; // current sample number
float voltage1 = 0.0; // calculated voltage

void setup()
{
Serial.begin(9600);
}

void loop()
{
// take a number of analog samples and add them up
while (sample_count < NUM_SAMPLES) {
sample_count++;
delay(10);
}

// calculate the voltage
// use 5.000 for a 5.0V ADC reference voltage
//5.000V is the calibrated reference voltage

voltage1 = ((float)sum / (float)NUM_SAMPLES * 5.000) / 1024.0;

// send voltage for display on Serial Monitor
// voltage multiplied by 4 when using voltage divider that
// divides by 4.

Serial.print(bitCount0);
Serial.println (" Bits");

Serial.print(voltage1 * 4);
Serial.println(" Volts");

Serial.println("");

delay(100);
sample_count = 0;
sum = 0;
}
You would add an "IF" to turn on a LED using a digital out pin. I used 5 volts for the reference but my actual reference is lower.

Ron

Dmm