Understanding SOC Drift

Why your battery percentage jumps - and how to fix it.

Below is the long version - what's actually happening inside the battery, why the percentage drifts in the first place, and exactly how the reset works.


The problem: the flat voltage curve

To understand SOC drift you need to know one thing about how lithium differs from lead-acid - the voltage curve.

The lead-acid "fuel gauge"

A traditional lead-acid battery behaves like a car's fuel tank. As you use energy, the voltage drops in a straight, predictable line. A monitor just looks at the voltage (say 12.2V) and knows almost exactly how full the battery is (around 50%). Easy.

Lead-acid voltage curve graph
Figure 1: Lead-acid voltage drops linearly, making it easy to read.

The lithium "cliff edge"

LiFePO4 doesn't behave like that. It's designed to deliver stable power for the entire usable range, so the voltage barely moves whether the battery is 80% full or 30% full. Then it falls off a cliff at the very end.

This is brilliant for your appliances - your fridge sees the same voltage all day - but it's a nightmare for the monitor. Voltage can't tell it the percentage, because the voltage isn't changing.

Lithium flat voltage curve graph
Figure 2: LiFePO4 maintains a flat voltage until the very end, making it hard to estimate remaining capacity.

How your monitor counts energy (Coulomb counting)

Since voltage is no help, the BMS uses a different method: Coulomb counting. External shunts (like the Victron BMV when paired with a TITAN battery) work the same way - and the TITAN battery range exposes the same data over Bluetooth so you can see it in the TITAN Lithium app on your phone.

Imagine standing at a door with a clicker, counting people entering and leaving a building:

  • You know the building started with 100 people (full).
  • You count 50 people leaving.
  • You assume there are 50 people still inside.

That's exactly what the BMS does. It measures the current (amps) flowing in and out over time, and from that works out how many amp-hours are left in the pack.

TITAN Lithium
Ah
BMS sensor



→ In (Charging)


← Out (Usage)

Figure 3: Animation showing the BMS counting energy as it enters and leaves.


Why the "jump" happens (the drift)

Coulomb counting is very accurate over a day or a week. But tiny measurement errors stack up over months.

  • A 0.1% measurement error doesn't matter today.
  • After three months of constant charging and discharging, that 0.1% error can have grown into a 10%, 20% or even 30% discrepancy.

Your monitor thinks the battery is at 40%, based on its running tally. But physically the cells are empty.

The "ghost load" effect

The TITAN BMS is deliberately calibrated to ignore extremely small currents - they can look like electrical noise. There's a good safety reason for this: if we made the BMS more sensitive (say 0.2A), random electrical noise could trick it into thinking current is flowing when it isn't. That matters because the BMS uses discharge current as one of its safety signals - it waits to see real load before it'll re-open the charge port after a full-charge cut. If noise mimicked discharge, the BMS could re-open the charge port on a full pack, leading to over-charge and a real fire risk.

The 0.6A threshold: the TITAN BMS effectively rounds anything below ~0.6A (about 8W at 12V) down to zero. So a single LED light, a USB phone charger or a TV standby indicator might be invisible to the monitor.

The result: a 0.4A load running overnight (10 hours) physically removes 4Ah of energy. The BMS, however, has logged 0Ah. Your screen says 100% when the battery is actually at about 96%. Multiply that across a few months and you get a noticeable drift.



Reality
(physical energy)








BMS screen


Ghost loads (<0.6A) sneak past the sensor… Real energy drains, but the screen stays at 40%… Voltage crash - BMS jumps to 0%.

Figure 4: How ghost loads create SOC drift and eventual jumps.


The fix: re-synchronising the system

The proper fix is to give the BMS a known reference point so it can reset its counter to a true 100%. We've engineered an explicit reset trigger into the protection logic for exactly this situation.

The solution: a full 100% charge

Charge the battery fully until one of two things happens:

  1. Pack over-voltage protection triggers (around 14.4V).
  2. Cell over-voltage protection triggers (around 3.60V on any single cell).

When the charger pushes the pack to either of those limits, the BMS briefly cuts the charge. At that exact moment, the BMS knows for certain the battery is physically full.

It immediately resets its internal counter to 100%, wiping out all the accumulated drift. From that point your monitor is back in sync with the actual energy in the cells.

BMS reset logic illustration
Figure 5: Reaching 14.4V forces the BMS to reset the SOC to 100%.