The problem
Battery capacity and power fade with use, and an EV's range estimate, warranty and second-life decisions all depend on knowing SOH. Full capacity tests take hours, so practical BMS units infer SOH from features measured during normal use.
Objectives
- Extract ageing features from public datasets and train regression models for capacity-based SOH.
- Measure the same features on the kit's cell with a repeatable test routine.
- Deploy the chosen model on the STM32 in fixed point and store history in SPI flash.
- Quantify prediction error and the effect of the domain gap between dataset cells and the kit cell.
What you need
From the EV Embedded Development Kit
- Second STM32F103C8T6 as the Smart BMS unit
- 1S battery with connector and T-sense input
- Battery charging unit with its own switch
- Charge/discharge control relay
- Load section: three switchable resistive loads with LEDs
- SPI flash memory
- BMS power switch, OLED and six navigation buttons
- Serial UART interface
Software
- STM32CubeIDE
- Embedded C with HAL drivers
- Python (pandas, NumPy, SciPy, scikit-learn, matplotlib)
- NASA PCoE and CALCE battery ageing datasets
Extra parts
- INA219 I2C current/power monitor module — Internal resistance (voltage step divided by current step) and partial capacity both need measured current, which the kit does not provide.
This project uses the kit's lithium cell. Respect polarity, never short the terminals, and don't leave the cell charging unattended.
Key concepts
- State of health (SOH)
- Usually present capacity divided by rated or initial capacity. A power-based SOH uses internal resistance growth instead.
- Internal resistance from a load step
- When a load switches on, the immediate voltage drop divided by the current step gives the ohmic resistance, which rises as a cell ages.
- Incremental capacity features
- dQ/dV during a slow charge shows peaks whose height and position move with ageing, a widely used SOH feature.
- Domain shift
- A model trained on one set of cells may not transfer to a different chemistry, size or temperature. This project measures that gap explicitly.
Step-by-step guide
- 1
Study the datasets and choose features
Load the NASA PCoE and CALCE ageing data in pandas. For each cycle compute capacity, ohmic resistance from load steps or impedance data, and charge features such as constant-voltage phase duration or the incremental capacity peak. Choose features that you can also measure on the kit with three resistive loads and the charging unit. Compare chemistries and test conditions with the kit cell's datasheet, and note the differences.
Checkpoint: A feature list, each with a formula, and plots of each feature against capacity fade for several dataset cells.
- 2
Train offline models
Train linear regression, a small gradient-boosted tree model and a small neural network to predict SOH from the features. Use leave-one-cell-out validation so the model is always tested on a cell it has not seen. Record mean absolute error, RMSE and maximum error. Prefer models that are cheap on a Cortex-M3: a linear model or a shallow tree can be enough if accuracy is close.
Checkpoint: A table of models with leave-one-cell-out errors and a chosen model with its size.
- 3
Set up the BMS controller with current sensing
Wire the INA219 in series with the load path with the cell disconnected, following polarity markings. On the Smart BMS STM32 configure ADC with DMA for voltage and T-sense, I2C for the INA219, the relay and load GPIOs, SPI for the flash and a UART. Never short the cell, keep within its voltage limits and supervise charging. Turn on only the DIP switches of the blocks in use.
Checkpoint: Synchronised voltage, current and temperature logging at 100 Hz during load steps.
- 4
Implement the on-kit feature test
Write a test routine started from the OLED menu: rest the cell, switch a known load on, sample at 100 Hz to capture the voltage step, compute resistance, then discharge a fixed amount of charge and measure the voltage change, and during a supervised charge record the constant-voltage phase duration. Control temperature as far as you can and record it, because resistance depends strongly on temperature.
Checkpoint: Ten repeated runs on the same cell give resistance values with a spread you report, for example as a coefficient of variation.
- 5
Bridge the domain gap
The kit's cell differs from the dataset cells, so normalise features relative to the cell's own first measurements, for example resistance ratio rather than absolute ohms. Retrain the model on normalised features and check it still generalises across dataset cells. If possible, test a second cell of the same type with a different history to see whether the model ranks them correctly.
Checkpoint: Leave-one-cell-out error for normalised features compared with absolute features.
- 6
Deploy the model in fixed point
Export the model coefficients or tree thresholds as integers with known scaling, and implement inference in C with no floating point. Test with feature vectors from the PC over UART and compare outputs with Python. Measure execution time with the DWT cycle counter and record flash and RAM from the map file. Keep the export script in the repository so any retrained model can be deployed the same way without manual editing.
Checkpoint: Firmware predictions match Python within one least-significant bit of the output scaling.
- 7
Store feature history in SPI flash
After each test, write a record to SPI flash: test number, temperature, features and predicted SOH, with a CRC. Implement wear-aware appending so sectors are erased only when full. Show the SOH trend on the OLED and add a UART command to export the history as CSV. Include the firmware version and model version in each record, so later analysis can tell which model produced each prediction and whether results changed after an update.
Checkpoint: History survives power cycling and exports correctly, with CRCs verified.
- 8
Validate against capacity tests
Run full capacity tests on the kit cell at the start and end of the project, with supervised charging, to get a measured SOH. Compare the on-device prediction with this measurement. Over a few weeks the cell will age very little, so also report the model's error on held-out dataset cells, which is the main accuracy evidence, and present the kit as a deployment and feature-measurement testbed.
Checkpoint: Measured versus predicted SOH for the kit cell, and held-out dataset error, both reported.
- 9
Write up the results
Present the features, models, deployment and the domain-gap analysis. Be clear about what was proven on kit hardware (feature repeatability, deployment cost, prediction consistency) and what relies on public data (accuracy across ageing). Include all scripts and logged data. Present feature repeatability, the deployment cost table and the transfer study separately, so readers can see which conclusions rest on kit data and which on public data. End with clear recommendations for future cells and tests.
Checkpoint: A thesis chapter with reproducible figures and a clear limitations section.
Testing & validation
- Leave-one-cell-out errors on public datasets reported for every model.
- Repeatability of on-kit resistance measurement reported.
- Firmware inference matches the Python model.
- Predicted SOH compared with a measured capacity test on the kit cell.
Expected results
An on-device SOH predictor with a documented accuracy on public ageing data, a repeatable feature-measurement routine for the kit cell, and stored SOH history on SPI flash.
Research angle for your M.Tech thesis
Research questions: which ageing features measurable with a simple BMS (load-step resistance, partial capacity, charge-phase timing) carry most SOH information, and how well does a model trained on public cells transfer to a different cell? Metrics: MAE and RMSE in SOH percentage points under leave-one-cell-out validation, feature repeatability, inference cost on the MCU. Baselines: resistance-threshold SOH, linear regression, and models from the literature on the same datasets. A strong result is a careful transfer study with normalised features and honest uncertainty.
Take it further
- Add temperature compensation of resistance from controlled tests.
- Report a prediction interval, not just a point estimate.
- Send SOH over CAN in a standard-style BMS message.
- Combine with an on-device incremental update as the cell ages.
Viva and review questions
Why can't you validate ageing fully on the kit cell?
A cell ages slowly at these low currents, so its capacity changes very little in a few weeks. We use public ageing datasets for accuracy and the kit to prove feature measurement and deployment.
Why does temperature matter for internal resistance?
Li-ion resistance falls as temperature rises, so a warm aged cell can look like a cool new one. We record temperature with every test and normalise or restrict the comparison.
Why leave-one-cell-out validation?
Cycles from the same cell are correlated, so mixing them across train and test overstates accuracy. Holding out whole cells tests generalisation to a new battery.