Goal: A weighted fusion of coulomb counting SOC and OCV SOC. A high accuracy and low-cost implementation.
Why? Coulomb counting on its own can accumulate errors due to repeated integration. We also cannot predict the current SOC using only coulomb counting, which is why we must incorporate OCV mapping.
System inputs:
- Sampling time = dt
- Pack current = I[n]
- Previous Pack current = I[n-1]
- Pack voltage (under load) = V[n]
- Previous Pack voltage (under load) = V[n-1]
- SOC = SOC[n]
- Previous SOC = SOC[n-1]
Coulomb Counting:
This is the easier algorithm to implement of the two. The equation for SOC using coulomb counting is:
Taken into discrete-time for embedded systems, the new equation is:
SOC[n] = SOC[n-1] + (I[n] * dt) / C
OCV SOC:
This algorithm raises issues that will be addressed through empirical data collection. OCV mapping allows us to predict the current SOC when there is no load on the pack.
Issue #1 = How do we map OCV - SOC?
Discharge testing.
To extract the OCV-SOC curve you can fully charge the battery, and then by 1% SOC decrements, discharge the battery and wait for 30min-1 hr for the battery to rebalance. Measure the voltage and map it, then repeat by 1% decrements until you reach min cell/pack voltage. To calculate the current to discharge at:
For example, if you wanted to discharge a 5000mAH battery, at a rate of 5% per hour, you would need to discharge 250mA:
A great visual on how to discharge test from TechLanz:
I plan on discharging at 5% SOC increments per 30 minutes, with 1 hour to allow pack stabilization. This means it will take 90 * 100/5 = 1800 minutes or 30 hours to complete a full discharge test (Likely automating this). The MS15 pack has 9 modules in series, with cells arranged 8P4S. I will run discharge tests on 2 modules, and if time permits on 2 cells.
MS15 uses INR21700 cells which have a capacity of 4850 mAH. For 5% SOC increments per 30 minutes I will have to discharge a cell at 485 mA. For an entire module it will be 8 * 4850 mAH = 38800 mAH. So for 5% increments I will discharge the module at 3880 mA.
Issue #2 = The pack is always under load, how do we get the OCV?
Battery modelling!
TLDR: Lots of math I had fun with, we use this equation for the RC circuit:
We can model our battery pack with either a 2RC or RC model. For simplicity, I will stick to an RC model.
The circuit can be modelled with the equation:
Two ideas to model this equation for the firmware:
1. First-order Taylor series approximation of ex
So OCV voltage can be estimated using this:
2. Transfer function with Inverse Laplace Transform (S domain → Time domain)
https://www.youtube.com/watch?v=nkq4WkX7CFU
The transfer function for the RC circuit (eq 1) can be converted into the time domain using reverse Laplace transform (eq 2)
Discretized for embedded systems, the equation can be written as:
This is what will be implemented in our firmware, it is more accurate than the first-order Taylor series approx.
TO BE CONTINUED….
Resources:
https://www.analog.com/en/resources/technical-articles/a-closer-look-at-state-of-charge-and-state-health-estimation-tech.html
https://www.linkedin.com/pulse/li-ion-battery-rc-modeling-what-how-done-part-1-testing-techlanz-lscyc/