Diagram of how the pack is built: 12 LFP cells form a stack, 4 stacks a module, 4 modules a bank, and 2 banks the 192S2P pack, with the master BMS where BG_SOX runs marked
How the pack is built: 12 cells in series form a stack, 4 stacks a module, 4 modules a 192S bank, and 2 banks in parallel the 192S2P pack. BG_SOX runs on the master BMS in the high-voltage box.

State of charge (SOC) is the number a pack’s users rely on most, and on lithium iron phosphate (LFP) cells it is the hardest one to get right. We have published a white paper on integrating BG_SOX, BattGenie’s physics-based state estimator, into the battery management system (BMS) of a 192S2P LFP pack for a heavy-duty commercial vehicle. This article covers what we did, how we tested it, and what it delivered.

Read the white paper

Why SOC is hard to estimate on LFP

Most production BMSs read SOC from an open-circuit-voltage table at rest and count current in and out between rests. Better designs correct the count against measured voltage with a model-based observer. Both depend on voltage, and LFP gives them little to work with:

  • A flat curve. Cell voltage moves only about 0.1 V across the 20 to 80 % SOC range. On this pack it changed by just 38 mV from 70 % to 40 % SOC during a 0.5C discharge.
  • Hysteresis. At the same SOC, the cell settles at a different voltage depending on whether it was last charged or discharged.
  • Sensor drift. Through the flat middle, the current count carries the estimate and inherits every error of the current sensor.
Average cell voltage against state of charge for a 0.5C discharge, changing only 38 mV from 70 to 40 % SOC
Measured average cell voltage against reference SOC during a 0.5C (230 A) discharge of the 192S2P pack. From 70 to 40 % SOC the voltage changes by only 38 mV. Source: BattGenie pack test, June 2026.

The usual answer is a larger reserve. On this 282.6 kWh pack, every point of SOC held back is about 2.8 kWh that the end user paid for and can’t use.

Every point of SOC held back is about 2.8 kWh that the end user paid for and can't use.

What we integrated

The test article is a liquid-cooled pack of 384 prismatic 230 Ah LFP cells: 192 in series and two banks in parallel, for 460 Ah at 614.4 V. The pack, the BMS hardware and the BMS software belong to the vehicle manufacturer. BattGenie supplies the state estimator.

The integration followed five steps, the same on every platform:

  1. Know the system: the pack layout, BMS architecture, duty cycle and limits.
  2. Characterize the cell: teardown plus open-circuit-voltage, pulse and cycling tests in BattGenie’s lab, so the parameters come from the physical cell and not from a datasheet.
  3. Build the model: a physics-based model of the cell’s electrochemical and thermal behavior, reformulated so it solves in real time on the BMS microcontroller.
  4. Integrate into the BMS: a pre-compiled C library that the master BMS software calls at each time step. It needs no new hardware and no new sensors.
  5. Validate on the pack: BG_SOX runs live on the BMS while the pack cycles on a test cycler, and its SOC is compared with the cycler’s own charge count.
Diagram of the 192S2P LFP pack, its high-voltage box with the master BMS board, and the BMS microcontroller where BG_SOX runs, above the BMS software stack
From pack to code: the master BMS in the high-voltage box, its microcontroller, and the software layers that run on it. BG_SOX reads the measurements the BMS already takes and returns its estimates to the BMS, which sends them over CAN.

How we tested it

The pack ran for 51.7 hours of active cycling over 6.4 days in June 2026, at currents from −350 A to +300 A and cell temperatures from 26 to 45 °C. The validation window, everything after the first BMS restart, covered 47 hours. It included four full discharges from 100 % to the cycler’s cut-off: two dynamic drive profiles, a 0.5C constant-current discharge, and an intermittent drive cycle spread over 3.3 days. The reference SOC is the cycler’s own charge count, which uses no value from the estimator.

Results

  • 0.6 % root-mean-square SOC error over the 47-hour validation window
  • Within 1.2 % of the reference for 95 % of samples, and within ±1 % for 89 % of the time
  • 11 BMS restarts carried through, with no SOC step larger than 0.01 %
Reference SOC and BG_SOX SOC over the 47-hour validation window, with the SOC error below staying mostly within plus or minus 1 %
Reference SOC from the test cycler and BG_SOX SOC over the 47-hour validation window (top), and the difference between them (bottom). Pauses are removed from the time axis. Source: BattGenie pack test, 11–17 June 2026.

The edges are where a gauge earns or loses reserve. In each of the four full discharges, BG_SOX reached 0 % shortly before the cycler’s voltage cut-off, with 0.3 to 1.6 % of the pack’s charge still inside. It never read above 0 % at the cut-off, so it erred on the side that doesn’t strand a vehicle.

Four charts of the last 12 % of each full discharge, with BG_SOX reaching 0 % shortly before the cycler cut-off each time
The last 12 % of each full discharge, plotted against the charge still to be drawn before the cycler’s voltage cut-off. The dot marks where BG_SOX first read 0 %. Source: BattGenie pack test, 11–17 June 2026.

The paper also reports where the estimate was weakest, including a slow drift to −1.3 % through the 3.3-day intermittent cycle. The tests did not cover cell temperatures below 25 °C or aged cells.

It never read above 0 % at the cut-off, so it erred on the side that doesn't strand a vehicle.

What it takes on your platform

The model describes the cell, not a curve fitted to one finished pack, so the same method carries to other cells and packs:

  • A new cell needs characterization and validation.
  • A new pack layout needs validation against its own data.
  • A new controller needs a new build of the library.

None of these means writing a new estimator. BG_SOX runs on standard automotive microcontrollers such as NXP S32K3 and Infineon AURIX TC3xx, from a bare-metal loop, an RTOS task or an AUTOSAR runnable. It is also available as a cloud deployment that works from the data a pack already sends.

Questions integrators ask

What does BG_SOX need from our BMS?
Pack current and voltage, the minimum, maximum and average cell voltage and temperature, and the time step. To build the model, we also need representative cells.

What does it report?
State of charge, state of health, state of energy, state of power as charge and discharge limits, predicted cell voltage, and time to empty and to full.

Is anyone’s IP exposed?
No source code changes hands in either direction. BG_SOX ships as a pre-compiled library behind a documented API.

What if our current sensor drifts?
BG_SOX checks the current count against the cell voltages and corrects SOC when they disagree in the pattern a mis-scaled sensor produces. Section 07 of the paper covers this.

Read the full paper

The full paper covers the test segments, the predicted-voltage accuracy, and what accurate SOC is worth on this pack.

Read the white paper

To scope BG_SOX on your platform, send a cell datasheet and a sample of your pack data to [email protected].

Share
LinkedIn