This project presents a model-based approach for estimating the State of Charge (SOC) of a lithium-ion battery using:
-
A first-order equivalent circuit model (1RC)
-
A 1-state Extended Kalman Filter (EKF) for baseline SOC estimation
-
A 2-state EKF with states:
SOCV_RC
-
A lightweight embedded-oriented implementation
-
A C-based firmware-style implementation
-
Python vs C validation of the estimator
The project demonstrates a complete workflow from battery simulation to embedded-friendly implementation and estimator improvement.
- Simulate battery voltage and current behavior under dynamic load conditions
- Estimate SOC using model-based methods
- Compare true SOC and estimated SOC
- Improve estimation accuracy by extending the EKF state model
- Develop an embedded-oriented implementation
- Translate the estimator into C for firmware-oriented deployment
- Validate the C implementation against the Python reference
- First-order RC equivalent circuit model
- Nonlinear OCV-SOC relationship
- Terminal voltage model:
V_terminal = OCV(SOC) - I*R0 - V_RC
- Time-domain current profile
- Terminal voltage response
- SOC propagation using current integration
The initial EKF formulation estimated only:
SOC
This provided a baseline estimator and enabled:
- Q/R tuning
- sensitivity analysis
- embedded-oriented reformulation
Different Q/R combinations were evaluated to improve robustness under noisy voltage measurements.
Best tuning result from the 1-state EKF stage:
- Q = 1e-6
- R = 1e-2
The EKF was extended to estimate:
SOCV_RC
This reduced the mismatch between the estimator and the battery simulation model and significantly improved estimation accuracy.
- Step-based estimator update
- Lightweight structure for real-time use
- Reduced computational complexity
- Struct-based estimator state
- EKF logic implemented in C
- 2-state EKF replay using simulation-generated data
- Python EKF output compared with C EKF output
- Matching results confirm correct translation of the estimator logic
To improve estimation accuracy, the EKF was extended from a 1-state formulation to a 2-state model:
SOCV_RC
This improved consistency between the estimator and the battery simulation model.
- MAE: 0.000477
- RMSE: 0.000597
This result shows a clear improvement over the simpler 1-state EKF approach.
The 2-state EKF was implemented both in Python and in firmware-style C.
- SOC MAE: 0.00046861
- SOC RMSE: 0.00058532
- V_RC MAE: 0.00035691
- V_RC RMSE: 0.00044748
These results confirm that the C implementation closely matches the Python 2-state EKF reference.
battery-soc-estimation/
β
βββ src/
β βββ main.py
β βββ ekf_soc.py
β βββ embedded_soc_step.py
β βββ test_embedded_soc.py
β βββ compare_results.py
β
βββ c_version/
β βββ ekf_soc.h
β βββ ekf_soc.c
β βββ main.c
β
βββ data/
βββ results/
βββ figures/
β
βββ README.md
βββ requirements.txt
Install dependencies:
pip install numpy matplotlib pandasRun the main simulation:
python src/main.pyRun embedded-oriented simulation:
python src/test_embedded_soc.pyRun Python vs C comparison:
python src/compare_results.pyCompile:
gcc main.c ekf_soc.c -o ekf_test -lmRun:
./ekf_testThe project generates:
- Current profile plot
- Voltage response plot
- Noisy voltage measurement plot
- 2-state EKF SOC comparison
- 2-state EKF V_RC comparison
- 2-state EKF SOC error plot
- Python vs C validation plots
- CSV output files for further analysis
The C implementation was validated against the Python 2-state EKF reference implementation.
The final comparison showed that the C implementation closely matches the Python output, confirming that the estimator logic was correctly translated into a firmware-style implementation.
- Physics-based battery modeling
- 1-state EKF baseline estimator
- Q/R tuning workflow
- 2-state EKF with improved model fidelity
- Embedded-oriented algorithm design
- C firmware-style implementation
- Python vs C validation
- Port the 2-state EKF to MCU-specific real-time deployment
- Include temperature effects
- Improve the battery model further (e.g. 2RC model)
- Validate with real battery datasets
- Deploy on STM32 / Arduino
- Explore fixed-point implementation for embedded targets
This project demonstrates how model-based battery estimation can be developed in Python, improved through EKF state augmentation, adapted for embedded-oriented execution, translated into C, and validated across implementations.
Hossein Electronics Engineer








