Skip to main content
emobility.academy
B.Tech / BEBattery modellingBeginner About 4 weeksMATLAB & Simulink

Coulomb Counting SOC Estimation in Simulink with Sensor Errors

Implement coulomb-counting SOC estimation in Simulink and study how current-sensor offset, gain error, noise, ADC quantisation, sample rate, capacity error and wrong initial SOC make the estimate drift, using a reference cell model and drive-cycle current profiles.

Tools: Simulink

Coulomb Counting SOC Estimation in Simulink with Sensor Errors: Students assembling a lithium-ion battery pack in a DIYguru workshop
Representative photo from DIYguru's EV lab, not of this specific project.

The problem

Coulomb counting is the base of almost every BMS SOC estimate, but it integrates every sensor error over time. Understanding how each error source grows, and what recalibration a BMS needs, explains why production systems combine counting with voltage-based correction.

Objectives

  • Build a reference cell model that provides true SOC and terminal voltage.
  • Implement a discrete coulomb counter as it would run on a BMS microcontroller.
  • Inject sensor and parameter errors one at a time and together.
  • Quantify SOC drift over drive-cycle current profiles.
  • Design and test a simple OCV-based recalibration at rest.

What you need

Tools and toolboxes

  • Simulink — Reference model, discrete-time estimator, error injection blocks and test harness.
  • MATLAB — Error budgets, sweep scripts with sim() and result analysis.
  • Simscape Electrical (optional) — A physical cell model as the reference; a Simulink ECM built from base blocks works equally well.

Software

  • MATLAB R2023b or later
  • Simulink
  • Drive-cycle current profiles, from a vehicle model or a public battery dataset such as NASA PCoE

Extra parts and data

None beyond the software above.

Key concepts

Coulomb counting
SOC(k) = SOC(k−1) − η·I(k)·Ts / (3600·Q), where Ts is the sample time, Q the capacity in Ah and η the coulombic efficiency.
Offset error
A constant bias in measured current. Because it is integrated, it causes SOC error that grows linearly with time even when the vehicle is parked.
Gain error
A proportional error in current measurement, producing SOC error proportional to charge throughput.
OCV recalibration
After a long rest, terminal voltage approaches OCV, so SOC can be reset from the OCV–SOC curve, removing accumulated drift.

Step-by-step guide

  1. 1

    Define the error budget

    Choose an example 50 Ah cell and a current sensor with example specifications: offset ±0.2 A, gain error ±1 per cent, noise 0.1 A RMS, a 12-bit ADC over ±200 A, sampling at 10 Hz. Also consider ±3 per cent capacity error and a ±5 per cent initial SOC error. Compute by hand the SOC error each source would cause after one hour of driving and 24 hours parked.

    Checkpoint: A hand-calculated error budget table for each source over driving and parked periods.

  2. 2

    Build the reference model

    Build a first-order ECM of the cell in Simulink with continuous integration of true current to give true SOC, an OCV–SOC lookup and an RC branch, using a variable-step solver for accuracy. This is the truth against which the estimator is judged, so keep it separate from the estimator in its own subsystem. Use a tight relative tolerance (for example 1e-6) so the reference itself adds negligible error.

    Checkpoint: True SOC falls by exactly 1/Q per amp-hour drawn in a constant-current test.

  3. 3

    Prepare current profiles

    Generate current from a vehicle model on IDC and WLTP, scaled to the example cell, or use a dynamic profile from a public dataset. Add parked periods with a small standby current. Feed the profile through a From Workspace block and resample to the reference model's needs. Make sure the profiles include both charging and discharging, so gain errors and coulombic efficiency affect the result in both directions as they would in a real vehicle.

    Checkpoint: Current profiles plotted with charge throughput per hour computed for each.

  4. 4

    Implement the estimator

    Create a discrete subsystem with sample time 0.1 s that reads measured current from an error-injection block, quantises it with a Quantizer block matching the ADC resolution, and integrates with a Discrete-Time Integrator (forward Euler) scaled by 1/(3600·Q_est). Clamp SOC between 0 and 1 with a Saturation block and set the initial SOC as a parameter. Keep the estimator's capacity separate from the reference capacity so capacity error can be injected.

    Checkpoint: With no errors injected, estimated SOC matches true SOC within 0.1 per cent over a full cycle.

  5. 5

    Build error injection

    Build a subsystem that adds offset (Constant), gain error (Gain), white noise (Band-Limited White Noise or Random Number with a fixed seed) and quantisation to the true current. Make each error source switchable with a parameter so the script can turn them on one at a time. Log measured and true current to the Simulation Data Inspector. Use a fixed seed for every random source so results are repeatable.

    Checkpoint: Measured current shows each error source correctly when enabled individually.

  6. 6

    Run single-error studies

    Write a script that enables one error source at a time and runs IDC, WLTP and a parked period with sim(). Record SOC error over time for each. Compare the simulated drift with your hand-calculated budget; differences point to model or calculation mistakes. Plot all the error curves on one figure with a shared time axis, marking the driving and parked periods, so the growth pattern of each error source can be compared directly.

    Checkpoint: SOC error curves for each source agree with the hand budget within about 10 per cent.

  7. 7

    Run combined and Monte Carlo studies

    Enable all errors with values drawn at random from their specified ranges and run a Monte Carlo of a few hundred simulations using a Simulink.SimulationInput array. Plot the distribution of SOC error after one day of mixed driving and parking. Identify the largest contributor using a simple variance decomposition. Check that the histogram shape is stable by repeating with twice the number of samples and comparing the percentiles.

    Checkpoint: A histogram of SOC error after one day and a ranked list of contributors.

  8. 8

    Add OCV recalibration

    Implement a Stateflow chart or MATLAB Function block that detects rest (current below a threshold for a set time, for example 30 minutes), then resets SOC from the OCV lookup of measured voltage. Model voltage-measurement error too. Rerun the Monte Carlo with recalibration and compare SOC error distributions. Discuss what happens for a cell with a flat OCV curve, where a small voltage error gives a large SOC error.

    Checkpoint: SOC error after one day with recalibration clearly smaller than without, with a histogram comparison.

  9. 9

    Sample-rate and offset-calibration study

    Sweep sample time from 10 ms to 1 s on a high-dynamic current profile and record SOC error from sampling alone. Then add a simple offset calibration at key-on (average measured current with contactors open) and measure the improvement. Present the two results as design guidance for a BMS. Explain why fast current pulses, such as regenerative braking spikes, are where low sample rates cause the most error.

    Checkpoint: Plots of SOC error against sample time and with or without offset calibration.

  10. 10

    Report

    Document the error budget, reference model, estimator, error injection, single-error and Monte Carlo results, recalibration and design guidance. State the limits: one cell, a simple OCV model without hysteresis, and idealised rest detection. Recommend sensor accuracy and recalibration rules for the example BMS. Present the error budget as a table that a BMS engineer could reuse, with the error source, its specification, its simulated effect and the recommended mitigation.

    Checkpoint: A report with an error budget validated by simulation and quantified design guidance.

Testing & validation

  • Error-free estimator matches true SOC.
  • Single-error drift matches hand-calculated budgets.
  • Monte Carlo results are reproducible with fixed seeds.
  • Recalibration reduces SOC error in the combined case.

Expected results

A Simulink coulomb-counting study with a validated error budget, Monte Carlo SOC-error distributions, an OCV recalibration scheme and quantified guidance on sensor accuracy, sample rate and offset calibration.

Take it further

  • Add capacity estimation from SOC change between two OCV rests.
  • Replace recalibration with an EKF and compare.
  • Add temperature-dependent capacity.
  • Generate C code for the estimator and compare fixed-point and floating-point drift.

Viva and review questions

Why does an offset error matter more when the vehicle is parked?

The offset is integrated continuously, so over many parked hours it adds a large charge error even though the true current is almost zero.

Why is the initial SOC error not corrected by counting?

Counting only adds changes to the starting value, so an initial error stays until an external correction such as an OCV reset.

When can you trust OCV for recalibration?

After a long enough rest for polarisation to decay, and in SOC regions where the OCV curve is steep enough that voltage error gives small SOC error.

Learn it at DIYguru

These DIYguru courses and programmes teach what this project needs.

Related EV projects

All 100 MATLAB & Simulink EV projects