Solar & EnergyEngineer

Battery Bank State-of-Charge Monitor

Count every amp-hour in and out of a small LiFePO4 battery and show a real percentage instead of guessing from voltage.

LevelEngineer
Time2 h
Est. cost~$99
Steps5

LiFePO4 voltage stays almost flat between about 20% and 90% charge, so a voltmeter can't tell you much. Coulomb counting adds up current over time — the same method used by commercial battery monitors.

⚠ SAFETY
Fuse the battery's positive lead close to the terminal, use wire rated for the current, and never short a LiFePO4 battery — it can deliver very high current.

Mission steps

  1. Place the sensor

    Put the INA219 in series with the battery's negative or positive lead so every load and charge current passes through it.

  2. Mind the limits

    The common INA219 board with a 0.1 Ω shunt reads up to about 3.2 A and 26 V, which suits small 12 V banks; bigger systems need a higher-current shunt monitor.

  3. Count amp-hours

    Every second, add charge current and subtract load current from the stored amp-hours.

  4. Re-sync at full

    When voltage reaches the charger's full level and current tapers off, reset to 100% to cancel accumulated error.

  5. Show it

    Print to a terminal, an OLED or a small Flask page with percentage, watts and estimated hours left.

Code

import time, board, adafruit_ina219

ina = adafruit_ina219.INA219(board.I2C())
CAPACITY_AH = 6.0
ah = CAPACITY_AH            # assume full at start
FULL_V, TAPER_A = 14.2, 0.1 # adjust to your charger
last = time.monotonic()

while True:
    time.sleep(1)
    now = time.monotonic(); dt = now - last; last = now
    v, a = ina.bus_voltage, ina.current / 1000   # amps; + = charging (depends on wiring)
    ah = max(0, min(CAPACITY_AH, ah + a * dt / 3600))
    if v >= FULL_V and 0 <= a < TAPER_A:
        ah = CAPACITY_AH
    soc = 100 * ah / CAPACITY_AH
    hours = ah / -a if a < -0.01 else float('inf')
    print('%.2f V  %+.2f A  %5.1f %%  %.1f h left' % (v, a, soc, hours))

Tip: test every script on the bench before installing it in a moving machine.

Questions

Why does my percentage drift over days?

Small measurement errors add up. Regular full charges re-sync it; that is why commercial monitors need a full charge from time to time.