Using a voltage divider to measure battery voltage

mrm

Well-known member
Hello All,

It would seem to be a simple matter to use a voltage divider and ADC pin to measure voltage but the forum and the internet seems to be awash with complicated solutions and discussions on unexpected ADC values.

Picaxes also seem to be quite sensitive to the resistor values on their pins.

Are there recommended values for the total resistance across the divider and for the recommended voltage for the Picaxe power supply in order to get consistent and reliable readings?

Or is the idea of using a Picaxe and an ADC pin to measure battery level a non-starter?
 

neiltechspec

Senior Member
It is a simple matter to use a voltage divider and readadc (or readadc10).

What exactly are you wanting to measure ? & what level of accuracy is required.

Neil
 

premelec

Senior Member
This has been discussed many times in other threads... a fundamental condition is that for full accuracy the source impedance to the READADC pin should be 10000 ohms or less...
 

AllyCat

Senior Member
Hi,

If the battery is connected (directly) to the PICaxe supply rail then you can use the CALIBADC{10} function which needs NO divider resistors or even a pin. I've posted various code snippets to give down to 10 mV resolution, or some "advanced" methods down to about 1mV resolution, NOT
accuracy (of the Fixed Voltage Reference), which is another issue that I've also discussed elsewhere on the forum.

Cheers, Alan.
 

mrm

Well-known member
The requirement is to monitor the state of two 12 volt lead-acid batteries which are attached to a theoretically 'intelligent' regulator which charges the primary battery as a priority but also attempts to maintain the secondary battery in condition.

It seems that this has not been happening during the lockdown period when it was not possible to access the installation for about 10 weeks.

So what is required is a simple circuit to monitor the secondary battery on demand with a traffic light led indicator as the secondary battery is fairly inaccessible.

Longer term it might be nice to monitor both batteries at intervals and save the readings to eeprom in order to check the charging pattern and if needed reposition the solar panel.

Accuracy is not that important so 0.2 Volt would suffice.
 

premelec

Senior Member
All that sounds fine - don't know what power levels you are working at but a switching regulator to run a PICAXE from 12 volts with burst mode high efficiency would reduce battery drain - and eventual lithium batteries would give less self discharge losses....
 

mrm

Well-known member
Hi,

If the battery is connected (directly) to the PICaxe supply rail then you can use the CALIBADC{10} function which needs NO divider resistors or even a pin. I've posted various code snippets to give down to 10 mV resolution, or some "advanced" methods down to about 1mV resolution, NOT
accuracy (of the Fixed Voltage Reference), which is another issue that I've also discussed elsewhere on the forum.

Cheers, Alan.
Thanks for this helpful input.

Can you point me at one of your other posts as I have tried searching the forum and do not find any concise data on what resistor values would be appropriate but somewhere I have seen that this should not exceed 100k ohms in total.

Driving of the supply being tested is good and I have used this on other projects to monitor supply voltage but in this case is not really necessary and would be problematic due to the unstable supply voltage.

I have also posted a further description of the requirement on the forum (see below your post) and had in mind a very simple setup driven by 3v coin cell and powered on demand with a simple traffic light led indicator.
 

inglewoodpete

Senior Member
Thanks for this helpful input.

Can you point me at one of your other posts as I have tried searching the forum and do not find any concise data on what resistor values would be appropriate but somewhere I have seen that this should not exceed 100k ohms in total.

Driving of the supply being tested is good and I have used this on other projects to monitor supply voltage but in this case is not really necessary and would be problematic due to the unstable supply voltage.

I have also posted a further description of the requirement on the forum (see below your post) and had in mind a very simple setup driven by 3v coin cell and powered on demand with a simple traffic light led indicator.
A source impedance of 100k is too high. The data sheet says a maximum of 10k. Personally, I would treat that figure as a maximum rather than a target. On your voltage divider, a capacitor across the divider's lower resistor will reduce the effect of any electrical/magnetic noise on your readings. The external capacitor will help keep the input voltage stable when the ADC input draws a charge into its internal (on-chip) capacitor.

I used the following code in a PICAXE 08M2 running on around 3 volts. I then made the voltage divider deliver a maximum voltage 1/10 of the battery source, making it easy to scale (x 10 for 12v) for an accurate representation of the SLA battery source. This would result in a Bulk Charge voltage of 14.4v providing 1.44v at the ADC input.
Rich (BB code):
      FVRSetup FVR2048       'FVR2048 = Fixed Voltage Reference is 2.048 Volts
      ADCConfig %011         'VRef- = 0v; VRef+ = FVR2048 (Ie 2.048 volts)
                             '2048mV & 10-bit ADC results in 2 millivolts per step
                             'With external 10:1 voltage divider, gives 20 mV / step
If using a "traffic light" battery condition indicator, you probably only need to use a ReadADC rather than ReadADC10 command
 

neiltechspec

Senior Member
The above from ip is pretty much what I have done for monitoring various No Cell LiPo's - 3, 4 & 5.
Used FVR40968 & ADCConfig %011, although I ran the picaxe of 5v through a 78L05.
Just to give me a green for good & red for low / recharge, it was easy enough to work out the adc
value for a 1/10 divider, but I did use readadc10.

example:
Code:
'5 cell LiPo battery monitor V1.0
'pin C.1 330R to IRL540 Mosfet Gates & 470R to Green LED
'pin C.2 330R to Red LED
'pin C.4 ADC I/P - 20k multiturn pot to Supply

#picaxe 08m2
#no_data
#terminal 4800

main:
    low c.1, c.2
    pause 1000
    fvrsetup fvr4096
    adcconfig %011
    do
    readadc10 c.4, w1
    fvrsetup fvr4096
    adcconfig %011
    w1 = w1 * 10 / 48
    sertxd (13,10)
    bintoascii w1,b10,b11,b12
    sertxd (b10,b11,".",b12,"v",13,10)
    if w1 > 174 then gosub opon
    if w1 <= 174 then gosub opoff
    pause 1000
    loop
    
opon:
    high c.1
    low c.2
    sertxd ("Output On",13,10)
    return

opoff:
    pause 1000
    readadc10 c.4, w1
    fvrsetup fvr4096
    adcconfig %011
    w1 = w1 * 10 / 48
    if w1 <= 174 then
     sertxd ("Output Off")
     low c.1
     high c.2
     end
    endif
    return
Neil.
 

mrm

Well-known member
A source impedance of 100k is too high. The data sheet says a maximum of 10k. Personally, I would treat that figure as a maximum rather than a target. On your voltage divider, a capacitor across the divider's lower resistor will reduce the effect of any electrical/magnetic noise on your readings. The external capacitor will help keep the input voltage stable when the ADC input draws a charge into its internal (on-chip) capacitor.

I used the following code in a PICAXE 08M2 running on around 3 volts. I then made the voltage divider deliver a maximum voltage 1/10 of the battery source, making it easy to scale (x 10 for 12v) for an accurate representation of the SLA battery source. This would result in a Bulk Charge voltage of 14.4v providing 1.44v at the ADC input.
Rich (BB code):
      FVRSetup FVR2048       'FVR2048 = Fixed Voltage Reference is 2.048 Volts
      ADCConfig %011         'VRef- = 0v; VRef+ = FVR2048 (Ie 2.048 volts)
                             '2048mV & 10-bit ADC results in 2 millivolts per step
                             'With external 10:1 voltage divider, gives 20 mV / step
If using a "traffic light" battery condition indicator, you probably only need to use a ReadADC rather than ReadADC10 command
Thank you for this information which is very helpful.

With regard to the capacitor on the lower resistor what sort of value is recommended?

Thank you also for the explanation of why the small white rectangular capacitor on the input supply is needed which also explains why an adc pin shows capacitive effects if measurements are rapidly repeated.
 

mrm

Well-known member
The above from ip is pretty much what I have done for monitoring various No Cell LiPo's - 3, 4 & 5.
Used FVR40968 & ADCConfig %011, although I ran the picaxe of 5v through a 78L05.
Just to give me a green for good & red for low / recharge, it was easy enough to work out the adc
value for a 1/10 divider, but I did use readadc10.

example:
Code:
'5 cell LiPo battery monitor V1.0
'pin C.1 330R to IRL540 Mosfet Gates & 470R to Green LED
'pin C.2 330R to Red LED
'pin C.4 ADC I/P - 20k multiturn pot to Supply

#picaxe 08m2
#no_data
#terminal 4800

main:
    low c.1, c.2
    pause 1000
    fvrsetup fvr4096
    adcconfig %011
    do
    readadc10 c.4, w1
    fvrsetup fvr4096
    adcconfig %011
    w1 = w1 * 10 / 48
    sertxd (13,10)
    bintoascii w1,b10,b11,b12
    sertxd (b10,b11,".",b12,"v",13,10)
    if w1 > 174 then gosub opon
    if w1 <= 174 then gosub opoff
    pause 1000
    loop
   
opon:
    high c.1
    low c.2
    sertxd ("Output On",13,10)
    return

opoff:
    pause 1000
    readadc10 c.4, w1
    fvrsetup fvr4096
    adcconfig %011
    w1 = w1 * 10 / 48
    if w1 <= 174 then
     sertxd ("Output Off")
     low c.1
     high c.2
     end
    endif
    return
Neil.
Thank you for this code.

This should prove very helpful in getting the application up and running.
 

AllyCat

Senior Member
Hi,

The source resistance for driving the ADC inputs is recommended to be a maximum of 10k (although connecting a capacitor between the pin and ground can permit higher values if power consumption is a major issue). The simplest way to achieve this (and keep the calculations simple) is to make one of the divider resistors exactly 10 kohms. Your next choice is the Reference voltage which could be either an internal "FVR" (probably FVR2048 = nominally 2.048 volts) or the PICaxe supply rail from an external regulator of perhaps 3.3 or 5.0 volts. It's worth noting that an "ordinary" 78{L}05 regulator will probably drain more current from the main supply (12 volt lead acid battery) than is used by the PICaxe, plus the divider resistors and possibly even an illuminated Traffic Light LED. But the drain will still be almost insignificant compared with the internal leakage current of a "car" or utility Lead Acid battery. Personally, I wouldn't consider a "Coin" cell if you already have a 12 volt supply available (but we can discuss further, how best to obtain the PICaxe supply).

A "12 volt" Lead Acid battery has a maximum (charging) voltage of almost 15 volts so I'd make that the "full scale" for the divider chain. Thus, with a 10k lower resistor, the upper resistor should be about 68k with the FVR2048, or 36k with a 3.3v reference/rail or 20k (or 22k if more convenient) with a 5v reference/rail (e.g. 78L05). +/- 0.2 volt accuracy is still better than 2%, which can't be guaranteed even with 1% resistors and a high quality reference voltage, so I'd be inclined to Keep It Simple with the FVR , 5% resistors and calibrate (within the program) against a basic Digital Multimeter.

I believe the output / charging voltages of Lead acid batteries are quite variable with temperature, so if you've planning a 24/7 "all weather" application, you should probably also monitor the temperature and correct accordingly. The traditional PICaxe DS18B20 is rather "overkill", a thermistor would be "good enough" but they are not well covered on the forum (perhaps because the maths is more tricky). There are also "linear thermistors", or you could calibrate the forward voltage drop of a diode (~-2mV/degC), or I've posted a code snippet which uses the diodes within the PICaxe.

Most of my posts (mainly in the "code snippets" section of the forum) have concerned variants of CALIBADC, for example here, but the code snippets section is not particularly large, so well worth a scan. You might also consider monitoring the charge and/or discharge current of your batteries (there's a snippet on that as well) although monitoring both directions together accurately, is more complex.

Cheers, Alan.
 

neiltechspec

Senior Member
For me, current drain doesn't matter. It's only active when switched on to enable the IRL fets.
So no current drain when not in use - just my DIY method of battery protection.

What I posted was as an example, not a suggested solution for the original poster.
 

mrm

Well-known member
Hi,

The source resistance for driving the ADC inputs is recommended to be a maximum of 10k (although connecting a capacitor between the pin and ground can permit higher values if power consumption is a major issue). The simplest way to achieve this (and keep the calculations simple) is to make one of the divider resistors exactly 10 kohms. Your next choice is the Reference voltage which could be either an internal "FVR" (probably FVR2048 = nominally 2.048 volts) or the PICaxe supply rail from an external regulator of perhaps 3.3 or 5.0 volts. It's worth noting that an "ordinary" 78{L}05 regulator will probably drain more current from the main supply (12 volt lead acid battery) than is used by the PICaxe, plus the divider resistors and possibly even an illuminated Traffic Light LED. But the drain will still be almost insignificant compared with the internal leakage current of a "car" or utility Lead Acid battery. Personally, I wouldn't consider a "Coin" cell if you already have a 12 volt supply available (but we can discuss further, how best to obtain the PICaxe supply).

A "12 volt" Lead Acid battery has a maximum (charging) voltage of almost 15 volts so I'd make that the "full scale" for the divider chain. Thus, with a 10k lower resistor, the upper resistor should be about 68k with the FVR2048, or 36k with a 3.3v reference/rail or 20k (or 22k if more convenient) with a 5v reference/rail (e.g. 78L05). +/- 0.2 volt accuracy is still better than 2%, which can't be guaranteed even with 1% resistors and a high quality reference voltage, so I'd be inclined to Keep It Simple with the FVR , 5% resistors and calibrate (within the program) against a basic Digital Multimeter.

I believe the output / charging voltages of Lead acid batteries are quite variable with temperature, so if you've planning a 24/7 "all weather" application, you should probably also monitor the temperature and correct accordingly. The traditional PICaxe DS18B20 is rather "overkill", a thermistor would be "good enough" but they are not well covered on the forum (perhaps because the maths is more tricky). There are also "linear thermistors", or you could calibrate the forward voltage drop of a diode (~-2mV/degC), or I've posted a code snippet which uses the diodes within the PICaxe.

Most of my posts (mainly in the "code snippets" section of the forum) have concerned variants of CALIBADC, for example here, but the code snippets section is not particularly large, so well worth a scan. You might also consider monitoring the charge and/or discharge current of your batteries (there's a snippet on that as well) although monitoring both directions together accurately, is more complex.

Cheers, Alan.
Thanks. Lots of information to digest here.

The reason for the coin cell was simplicity. For a longer term monitoring solution the voltage regulator would be better and give a more accurate result and the drain will be minimal compared to the several hundred ampere hour capacity of the batteries being monitored and topped up by the solar panel.

I will also check the code snippets which might prove helpful for the longer term monitoring version.
 

inglewoodpete

Senior Member
With regard to the capacitor on the lower resistor what sort of value is recommended?
If you use a 0.1uF (100nF) capacitor, it will filter out most noise down to about 150Hz. As Alan suggests, not essential but it should make the readings a little more consistent.
 

oracacle

Senior Member
I would, as a precaution use a Zener diode on the input to ground so that if something goes wrong the excess voltage flow to 0v instead of the picaxe.
If you supply the picaxe with 5v, a 5v1 Zener can be used, or 3v3 for a 3.3v supply.
 

AllyCat

Senior Member
Hi,
If you supply the picaxe with 5v, a 5v1 Zener can be used, or 3v3 for a 3.3v supply.
Be careful, the OP (and the title) concerns the design of a potential divider to measure an analogue voltage to better than about 2% accuracy. No definitive design has been confirmed, but (up to) a 10k source impedance and a 3 or 5 volt supply rail / reference voltage have been proposed. That implies that the loading on the ADC input pin should be greater than 500k ohms, equivalent to a "leakage" current of a few micro-Amps. Unfortunately, Zener diodes, particularly below about 7 volts, have a poor "knee" (i.e. leakage current) at lower currents.

It's quite difficult to find good Zener diode data now, but here's a copy (scanned from the manufacturer's data book) that I posted on the forum years ago. Note the current scale is milli-Amps (10 mA per square) and a 3v3 Zener, for example, probably leaks away up to 1 mA at 2.5 volts. Therefore, for an analogue measurement, I wouldn't trust a Zener of less than 6 volts to be "negligible" at a half (or even a quarter) of its rated voltage. :(

BZX79zeners.jpg

Cheers, Alan.
 

premelec

Senior Member
Probably best to put current limiting resistor in series with low impedance divider output - resistor to capacitor to V- and PICAXE in pin... Alan is right about zeners - could use TL431 if carefully configured... probably not necessary...
 

matchbox

Senior Member
If the battery is connected (directly) to the PICaxe supply rail then you can use the CALIBADC{10} function which needs NO divider resistors or even a pin.
What happens in this case, when the ADC pin is powered by the batteries (e,g. 3.7v). If the Picaxe VCC (5v) is turned off, with a GND still connected.
Will the ADC input pin be damaged, without the Picaxe having a supply voltage?
 

AllyCat

Senior Member
Hi,

That's why you should nearly always connect a resistor in series with input pins (typically 1k - 10k). In the case of the OP, that was "automatic" because the pin was being driven by two resistors formed into a potential divider.

If you don't fit a resistor (or it's too small) then when the (intended) power supply is removed, current can flow from the external voltage source (battery) into the pin and through the "electrostatic protection" diode which connects to the supply rail. This can potentially continue to power the PICaxe; it's often called "phantom powering" and probably won't damage the PICaxe, but may cause all kind of "unexpected issues". However, if the PICaxe outputs are driving large currents, then the 20mA rated protection diode (which is effectively powering the chip) might be damaged.

The PICaxe "core" needs less than 1 mA (and 2 volts supply with most M2s) so to prevent phantom powering you might need to use a series resistance significantly more than 1k and/or put an additional load (perhaps a 1k resistor) between the PICaxe supply and ground, to ensure that the PICaxe is "off" / reset when the intended power is removed.

Cheers, Alan.
 

matchbox

Senior Member
That's why you should nearly always connect a resistor in series with input pins (typically 1k - 10k).
Thought I better report back on my results.
For those who might be interested. The ADC pin was directly connected through a 12K resistor to a 1S Lithium Ion 18500 cell. With a 10k tie down resistor on the ADC pin also.
The Picaxe was driven off a boost regulator to take the 3.8v nominal cell, up to 5v.
If the power to the picaxe was turned off. I was concerned that the picaxe or its ADC pin maybe damaged.... But the 12K resistor limited the ADC current to 190uA when in use, And when the Picaxe's 5v supply was removed, the ADC pin seems to shut off with it. Because the current dropped to zero amps.
Its a plus that it protects itself.:)
 

lbenson

Senior Member
What readings did you get at varying voltages on the ADC pin, and how did you convert them to voltages?
 

matchbox

Senior Member
I used ADC10.
Here is the settings that I have tuned the ADC to. Its based on a classic Lithium Ion Voltage vs Capacity table. Driving a custom character on the display.
The current drain is < 8mA. So load is not going to effect the readout at all. Its really just a general reference of the batteries charge state.

Code:
  Select Case battery                                           
      Case > 383 : bat_level = 5                                   ;85% up to 100%    > 4.05v
      Case > 373 : bat_level = 4                                   ;70% up to 85%     > 3.95v  
      Case > 364 : bat_level = 3                                   ;55% up to 70%     > 3.85v  
      Case > 359 : bat_level = 2                                   ;40% up to 55%     > 3.80v  
      Case > 354 : bat_level = 1                                   ;25% up to 40%     > 3.75v  
      Case > 349 : bat_level = 0                                   ;10% up to 25%     > 3.69v      
      Case <=349 : bat_level = 0                                   ;10% or less  
  End Select
 

lbenson

Senior Member
Ok, thanks. So you didn't do a formulaic conversion, but by measurement figured out the appropriate ADC readings for your voltages?
 
Top