Accurately Measuring Battery Voltage From A Higher Voltage Source

The Problem of Voltage Drops

When attempting to measure the voltage of a battery or other low voltage source that is powered from a higher voltage rail, issues with voltage drops can lead to inaccurate readings. Voltage drops occur due to the resistance present in wires, contacts, and other conductive elements between the power source and the battery being measured. According to Ohm’s law, current flowing through a resistor will lead to a proportional voltage drop. If the path between the battery and the measurement point has resistance, the measured voltage will be lower than the actual battery voltage.

For example, if a 3.7V lithium ion battery is being powered from a 5V rail, any resistance in the electrical path to the battery will cause a voltage drop between the 5V supply and the battery itself. If there is 0.5 ohms of resistance, and 100mA of current is flowing, by Ohm’s law the voltage drop will be 0.5 * 0.1 = 50mV. So the measured voltage at the battery terminals will be 3.7V – 50mV = 3.65V, an error of 1.3%. For accurate battery fuel gauging or other precision monitoring, such errors could impact the quality of readings.

Using Voltage Dividers

Resistor Selection

A simple way to measure lower battery voltages off higher voltage rails is by using a voltage divider circuit. This consists of two resistors in series between the rail and ground, with the battery voltage being tapped from the center point of the divider. By selecting appropriate resistor values, the divider can attenuate and shift the higher rail voltage down to lower levels compatible with measurement inputs.

The selection of resistor values involves a tradeoff between divider loading, power consumption, and measurement accuracy. Lower value resistors draw more current out of the higher voltage source when none is being drawn by the battery, wasting power. Higher value resistors have less loading effect but also make the divider output more sensitive to measurement errors. Standard value resistors in the kilohm range typically provide a good compromise.

Calculating Divider Ratios

The relationships between voltages and resistances in a divider can be calculated using the voltage divider formula. If R1 and R2 are the upper and lower resistors respectively, Vin is the higher voltage source, and Vout is the output voltage being measured, then:

Vout = Vin * (R2 / (R1 + R2))

Rearranging to solve for R2 in terms of the other variables gives:

R2 = R1 * (Vout / (Vin – Vout))

As an example, if measuring a 3.7V battery voltage off a 5V rail, with an upper divider resistance R1 of 10 kilohms, R2 can be calculated as:

R2 = 10k * (3.7 / (5 – 3.7)) = 6.1 kilohms

Using standard value resistors, 6.2 kilohms would be the closest available option for R2.

Voltage Follower Circuits

Unity Gain Op Amps

Rather than directly tapping a divider output to measure lower battery voltages, an alternative technique is to use a unity gain buffer op amp voltage follower circuit. This isolates the divider from measurement errors caused by changes in load currents, provides accurate low impedance signal levels for ADC inputs, and prevents measurement loading from disrupting the divider ratios.

In this configuration, the resistor divider is used to shift down from the higher voltage rail to the battery’s voltage level, but the actual measurement point is taken at the output of an op amp instead of directly from the divider center point. The op amp buffers the voltage with extremely high input impedance, usually gigaohms, loading the divider minimally.

Input Impedance

Op amp inputs also minimize errors caused by variable input impedance in the measuring device. Analog-to-digital converters and microcontrollers often have fluctuating input impedance depending on sampling mode, clock speeds, and other factors. This interacts with any series resistance in the signal path to cause voltage errors and spikes. An op amp isolates downstream circuitry from these effects by maintaining a high, steady input impedance.

Overall, combining resistor dividers with unity gain voltage followers improves measurement consistency and stability when reading lower battery voltages off higher voltage sources.

Analog-to-Digital Conversion

ADC Resolution

When measuring divided down battery voltages, the analog-to-digital conversion resolution determines measurement precision and accuracy. For example, a 3.7V lithium battery voltage range, when divided down from a 5V rail, would span a narrow output range centered around 1.5V. Typical microcontroller ADCs digitize analog input voltages into 8, 10, or 12-bit digital values.

A 10-bit ADC, for instance, divides a measurement range spanning 0-3.3V into 1024 quantization levels, yielding increment steps of about 3.3/1024 = 3.2mV per step. This sets the limit for measurement resolution of the battery voltage to roughly +/- 1.5mV, without additional interpolation.

Maximizing ADC Input Range

Getting maximum ADC resolution for narrow battery voltage ranges involves configuring the resistor divider ratios to match the expected voltages to the ADC measurement window. Rather than dividing down the higher supply rail to 0-3.3V centered around 1.5V for a 3.7V battery, a divider ratio leading to 0-1.2V or 0.6V-1.8V better utilizes the full ADC range just for the battery voltage span of interest.

For wider range measurements, input scaling can also improve resolution. Placing an instrumentation amplifier with programmable gain front-end before the ADC effectively creates higher bit values for smaller signals. Combined with dividers optimized to ADC input voltages, over 16-bit equivalent measurements are possible.

Example Code for Reading Battery Voltage

Here is sample Arduino code for measuring a lithium battery voltage centered around 3.7V, using a resistor divider, voltage follower op amp, and the Arduino’s built-in 10-bit ADC:

const int batteryPin = A0;     // Battery connected to this analog pin
const float R1 = 10000;       // Upper divider resistance
const float R2 = 6200;        // Lower divider resistance 

void setup(){

  // Configure serial  
  Serial.begin(9600);
}

void loop(){

  int sensorValue = analogRead(batteryPin);            // Read divider voltage
  float voltage = sensorValue * (3.3 / 1023.0);       // Convert to 0-3.3V   
  voltage = voltage * (R1 + R2) / R2;                 // Scale back to source voltage  
  Serial.print("Battery voltage: ");
  Serial.println(voltage);                             // Print measured voltage 
  
  delay(100);
}

Leave a Reply

Your email address will not be published. Required fields are marked *