Measuring Battery Voltage with an ADC
How to measure the voltage on a power source that is greater than the maximum rating of your ADC
If you are using a battery powered device, it's often useful to be able to measure the current voltage level on the battery to estimate how much stored energy is left. You may wish to alert the user if the charge level drops below a certain level, for example, or automatically shut the device off beyond a certain lower threshold. On the other end of the scale, if you are charging the battery, you may wish to cut off the charging process once a certain upper limit is reached.
These measurements would all be relatively easy if your battery supply never exceeded 3.3V, for example, but many batteries do indeed exceed 3.3V, such as Lithium Polymer cells that typically go up to 4.2V when fully charged -- much too high to safely connect to an ADC line on your MCU. So how can you go about safely measuring voltage great than 3.3V with a simple ADC? The most common solution is the simple Voltage Divider.
Basic Voltage Divider
In it's simplest form, a voltage divider consists of two resistors that 'divide' the incoming voltage by a pre-determined amount. The amount that the incoming voltage will be reduced by can easily be determine with the following formula:
Calculating the Relationship Between the Input and Output Voltage
Vout = R2 / (R1 + R2) * Vin
Using the example above, we could calculate the ratio of the battery supply to the ADC input with:
1.0 Vin = 4.7 / (10.0 + 4.7) = 0.31973 Vout
This effectively triples the highest voltage rating that we can now safely measure with the ADC (though you should always add a safe margin-of-error, and use a combination of resistors that will allow you to measure 25% more V than you actually need). For example, 4.2V on the Vin/Battery will now appear as 1.343V on the ADC, or a value of approximately 417 on a 10-bit ADC with a 3.3V VREF (1.343 / 0.00322).
Controllable Voltage Divider
This simple solution above is fine if you are monitoring a constant power supply and don't have to worry about the amount of current being drawn by your device, but it has one important limitation if you are working with batteries: it will constantly draw a little bit of energy from the battery supply, and will eventually drain the batteries entirely if left long enough (though you're probably talking about a period of months). This may not be an issue in certain situations, but if absolute minimum power consumption is a goal in your project, you can take a few more steps to improve this simple circuit and extend the life of the batteries you wish to monitor with the following circuit:
This example extends on the basic voltage divider by allowing you to enable or disable the divider with a simple GPIO pin (BATTSENS_EN). Q1 is a P-Channel MOSFET that will selectively allow the battery current to flow throw the voltage divider and into the ADC. Q2 is an NPN Transistor that will turn the P-Channel MOSFET (Q1) 'on' or 'off'. The extra transistor is necessary because the battery voltage may well be above the maximum level that the GPIO pin can handle, which would almost certainly damage the MCU if they were connected directly. By setting the GPIO line high, the transistor (Q2) will open the flow of current through the MOSFET (Q1), allowing you to safely measure the current battery voltage on the ADC line. By setting the GPIO line low, you shut off the flow of current to the ADC and the voltage divider and can be certain that you are not needlessly using any of the battery's stored energy. (Tip: If you don't have an NPN transistor, an N-channel MOSFET could also be used in place of R4 and Q2.)