BMS

The battery management system keeps every cell safe and makes the pack's state known. Learn cell monitoring, protection limits and contactor control, SOC estimation (coulomb counting, OCV, Kalman filters), SOH, power limits, cell balancing (passive/active), insulation monitoring and functional safety.

A battery pack of hundreds of cells is only as good as its weakest cell. The BMS measures every cell's voltage and temperature, estimates charge and health, decides how much power can be used, balances cells, and disconnects the pack if anything goes wrong.

Accurate state of charge drives the range display; robust protection prevents fires.

An analogy

The BMS is the battery's doctor and bodyguard: it takes the pulse of every cell, reports how much energy is left, and steps in before anything dangerous happens.

Monitoring and protection

Cell supervisor chips measure every cell voltage (±1–2 mV) and temperatures. The BMS enforces limits: over/under-voltage (e.g. 4.2/2.8 V NMC), over-current, over/under-temperature. Main contactors, pre-charge circuit and pyro fuses disconnect the pack when needed.

SOC and SOH estimation

Coulomb counting integrates current but drifts; OCV lookup is accurate only at rest; model-based observers (equivalent-circuit model + extended Kalman filter) combine both. SOH tracks capacity fade and resistance growth — essential for warranty and resale.

Cell balancing

Cells drift apart in SOC due to self-discharge and temperature differences. Passive balancing bleeds energy from high cells through resistors (simple, wasteful); active balancing moves energy between cells with converters (efficient, complex). Balancing usually happens near full charge.

Power limits, isolation and safety

State-of-power algorithms tell the vehicle how much charge/discharge power is allowed now (depends on SOC, temperature, resistance). Insulation monitoring checks HV-to-chassis resistance (≥ 100–500 Ω/V). BMS software is ASIL C/D under ISO 26262; wireless BMS reduces wiring.

Formulas

Worked example: Coulomb counting

Given: SOC 80 %, capacity 150 Ah; Discharge 50 A for 30 min

Find: New SOC.

Answer: ≈ 63 %

Worked example: Passive balancing

Given: Imbalance 100 mAh; Bleed current 100 mA at 3.6 V

Find: Time, resistor, heat.

Answer: 1 h, 36 Ω, 0.36 W

Coulomb counter with OCV correction (C)

#include <stdint.h>

typedef struct {
    float soc;        /* 0..1 */
    float cap_ah;     /* current capacity estimate */
} bms_state_t;

extern float ocv_to_soc(float ocv);   /* lookup from calibrated OCV curve */

/* Called every dt seconds with measured pack current (A, + = discharge). */
void soc_update(bms_state_t *s, float current_a, float dt_s)
{
    s->soc -= (current_a * dt_s / 3600.0f) / s->cap_ah;
    if (s->soc > 1.0f) s->soc = 1.0f;
    if (s->soc < 0.0f) s->soc = 0.0f;
}

/* After a long rest (no current) the OCV reflects true SOC: correct drift. */
void soc_rest_correction(bms_state_t *s, float rest_ocv, float rest_time_s)
{
    if (rest_time_s > 3600.0f) {
        float soc_ocv = ocv_to_soc(rest_ocv);
        s->soc = 0.7f * soc_ocv + 0.3f * s->soc;   /* blend to avoid jumps */
    }
}

Pure coulomb counting drifts with sensor error; production BMSs fuse it with OCV and model-based estimators (extended Kalman filters).

Common mistakes

Applications

Key takeaways

Going further