Sweden
Loading...
India
Loading...

State of Charge (SoC) Estimation for LFP Cells

This function runs per cell every 100 ms (sampling time).


Inputs

  • Cell voltage (slow filtered): cellVolt_(filt-slo)
  • Current (fast filtered): Current_(filt-fast)
  • Filtered cell temperature
  • Cell capacity

Calibration

  • cal_soc_ocv_lo
  • cal_soc_ocv_hi
  • cal_soc_ocv_unknown initialized to 0
  • soc_ocv table

Outputs

  • SoC for each cell
  • SoC error for each cell
  • Integrated current (for the whole pack)
  • Writing SoC and their respective error for each cell in NVRAM
  • soc_ocv_unknown_flag

Startup

At ECU start-up, SoC is estimated in two ways depending on the cell voltage:
- If the cell voltage is between cal_soc_ocv_lo and cal_soc_ocv_hi, read SoC from NVRAM (previously saved value at shutdown) and fetch their resp. error. In this scenario, cal_soc_ocv_unknown should be set to 0. - Otherwise, estimate SoC based on soc_ocv tables, in this case the respective error is 'cal_soc_ocv_err' (default 1%). In this scenario cal_soc_ocv_unknown should be set to 0. - If none of the above is possible, due to for instance a first ECU start after SW flashing, then we will have to consider that the soc is unknown and follow the procedure in the paragraph 0. Unknown cell soc and cal_soc_ocv_unknown should be set to 1.

0. Unknown cell soc

  • If cal_soc_ocv_unknown is true, then the BMS shall follow the "Soc recalibration procedure" in the "Current Limit.md" until the soc is known and that cal_soc_ocv_unknown is false.
  • Soc reported should be soc=cal_soc_ocv_lo + (cal_soc_ocv_hi - cal_soc_ocv_lo)/2, the mid point between soc_ocv_lo and soc_ocv_hi. The error reported should be soc_err=(cal_soc_ocv_hi - cal_soc_ocv_lo)/2.

Note: Typically cal_soc_ocv_lo = 10% and cal_soc_ocv_hi = 90%. These parameters depend on the cell model. Publish on CAN the variable 'soc_ocv_unknown_flag' which reflects the value of cal_soc_ocv_unknown.


Relaxation and resting states

IF the pack current absolute value gets below REST_THRESHOLD_MA A for SOC_RELAXATION_TIME_MS ms THEN, the BMS load state should be set to: - REST CHARGING if the BMS was previously charging. - REST DISCHARGING if the BMS was previously discharging.

IF the pack current absolute value gets below REST_THRESHOLD_MA A for SOC_LONG_REST_TIME_MS ms THEN, the BMS load state should be set to: - REST if the BMS was previously charging.

  • soc_ocv table maps cell voltage (and temperature, ignored in this iteration) to SoC when the cell is at rest.
  • Two tables exist: charge and discharge.
  • After charging and rest (>10 min), i.e. REST CHARGING, read from OCV charge table if the cell voltage is within the linear region.
  • After discharging and rest (>10 min), i.e REST DISCHARGING, read from OCV discharge table if the cell voltage is within the linear region.
  • If the OCV reading was within a linear region it is considered successful and the BMS should set cal_soc_ocv_unknown=0.
  • For long-term rest (>1 day), i.e. REST, read the mid-curve between OCV charge and discharge.

Important: This function will read from the OCV tables whenever the cell is considered relaxed or a rest (long term).

Every Loop (Coulomb Counting)

SoC is updated using coulomb counting:

\[ \text{SoC}(k) = \text{SoC}(k-1) + \frac{I(k) \cdot \Delta T}{Q_{\text{cell}}} \]

Where:
- \(\Delta T\) = sampling time in seconds (0.1 s)
- \(I(k)\) = filtered current in A at time step \(k\)
- \(Q_{\text{cell}}\) = cell capacity in AΒ·s (convert Ah β†’ As)

The coulomb counting error shall be added on top of the existing error. soc_cc_err= Qcell_err * (Sum(I(k).DeltaT) / (Qcell*(Qcell+Qcell_err))


Shutdown

The SoC estimation and its resp. error and cal_soc_ocv_unknown should be saved in NVRAM at shutdown for each cell.



Depth of Discharge

  • Manufacturer recommends using a SoC span (e.g., 5–95%) to guarantee lifecycle (e.g., 4000 cycles).
  • Use battery within agreed SoC regions: soc_win_lo β†’ soc_win_hi.

Useful SoC Window

  • Externally communicated as 0–100%
  • 0% corresponds to soc_win_lo
  • 100% corresponds to soc_win_hi

Dynamic Hysteresis Function

  • To be defined (TBD)

Cell characterization - OCV tables update protocol

In work - see issue LFP cell OCV data collection #18: https://github.com/Simtestlab/bms_master/issues/18#issuecomment-3983114193

Soc source

There should be a signal sent on CAN that informs how the SOC is calculated, i.e. OCV, CC, NVRAM or unknown. By default: unknown. If at least one cell has its source unknown, then the soc source signal shall report unknown. E.g. if most of the cells report OCV and 2 cells have their source unknown then the signal should report unknown.


Testing Procedure

a. Coulomb Counting Integration Accuracy

  1. Bring cell voltage down to 2.8 V (cell, module, or pack level)using the power supply constant voltage function.
  2. Let the cell relax (wait for 10min).
  3. Make sure the BMS communicate 0% soc.
  4. Charge system at constant current = C/4 (e.g., for 100 Ah cell β†’ C/4 is 25A) for 1h.
  5. Observe that the BMS soc (from coulomb counting) shows 25%.
  6. Repeat twice and make sure the soc from the BMS shows 50% after 2h and 75% after 3h of charging.

b. OCV Reading - normal condition

  1. Bring cell voltage down to 2.8 V using the power supply constant voltage function. Please make sure to always respect the current limits!
  2. Wait until cell is relaxed (~10 min).
  3. Verify SoC = 0% (Β±2%) and that the BMS reads from the ocv discharge curve.

  4. Charge cell with C/4 (the cell nominal_capacity/4 A) current for 1 h then stop charging. Please make sure to always respect the current limits!

  5. Observe: SoC β‰ˆ 25% (Β±2%)
  6. Wait 10–15 min β†’ SoC still β‰ˆ 25% (Β±2%)
  7. For LFP cell in the flat region of the ocv curve, make sure the BMS does not read from the ocv curve but rather keeps the same value it had from coulomb counting.

  8. Repeat for 50% and 75% SoC, make sure the BMS does not read from the ocv curve. Please make sure to always respect the current limits!

  9. Charge remaining C/4 (final charge current may vary).

  10. Please make sure to always respect the current limits!
  11. Please make sure not to overshoot 3.65V otherwise the overvoltage violation will open the contactors.
  12. Observe: SoC β‰ˆ 100% (Β±2%)
  13. Wait 10–15 min β†’ SoC still β‰ˆ 100% (Β±2%), make sure the BMS reads from the ocv charge curve.

  14. Shutdown the BMS and make sure it has time to save data into NVRAM.

  15. Wait for 6-12 hours (optional but preferred).
  16. Start the BMS again and make sure the SOC is read from the center ocv curve (not charge nor discharge ocv curve but the middle one).
  17. Discharge the BMS such that the SOC becomes =60% (or somewhere in the flat ocv region)
  18. Shutdown the BMS.
  19. Start the BMS and make sure the SOC is still =60% and that the soc is coming from NVRAM.

c. OCV Reading - unknown soc

  1. Make sure the cell soc is 40-60%.
  2. Flash the BMS with a new sw to erase all NVRAM data.
  3. Start the BMS.
  4. The BMS shall display a SOC of 50% (default) and a soc unknown flag shall be set to true.
  5. Make sure the current limit charge is 0A and that the discharge current limit is not 0A.
  6. Discharge the cell according to the current limit discharge until the soc unknown flag is set to false (this will involve discharging until the current gets to 0A and wait for relaxation).
  7. Make sure the new soc is is close to 0% or at least less than 10%.