loading...
running...
How to use
Pick a preset and press play. Each cycle is charge (CC then CV), a balancing hold, a discharge and some storage time. Try: (1) No balancing and watch the delivered capacity fall each cycle in the lower graph; (2) Weak bleed against Strong bleed and compare capacity with the heat in the readout; (3) Matched cells where nothing needs balancing; (4) increase the self-discharge spread or the storage time; (5) change the seed to draw a different cell lottery. Space pauses, R resets, drag to orbit, wheel to zoom, or press Guided tour.
The bench (cells, nickel strips, BMS board with bleed resistors and LEDs, charger and load) is a Blender 5.2 model with baked PBR textures; the pack model runs live in JavaScript.
The science
Series strings. One current I flows through every cell. A cell's terminal voltage is the open-circuit voltage plus the resistive drop:
V_i = OCV(SoC_i) + (I - I_b,i) R_i dSoC_i/dt = (I - I_b,i) / (3600 C_i)
Charge and discharge limits. The charger runs constant current until the highest cell reaches 4.2 V, then holds that cell at 4.2 V (constant voltage) until the current tapers. The discharge ends when the lowest cell reaches 3.0 V. The delivered capacity is therefore set by the span between the cell that fills first and the cell that empties first, and cannot exceed the weakest cell.
Q_delivered ~ min_i ( C_i SoC_i ) at the start of discharge (small R)
Passive balancing. When a cell is above the start voltage and above the lowest cell by more than the threshold, the BMS switches a bleed resistor across it, diverting I_b = V / R_b around the cell. That charge is lost as heat, P = V^2 / R_b. During the constant-voltage phase the highest cell is limited by (V_max - OCV)/R + I_b, so bleeding lets the pack keep charging while the top cell is held back.
Why packs drift. Cells self-discharge at slightly different rates. Between cycles each cell loses a different charge; without balancing the SoC pattern spreads cycle after cycle and the delivered capacity falls. Balancing restores the alignment at the top of charge each time, as the capacity-per-cycle graph shows.
Honest simplifications. A single piecewise-linear OCV curve (generic NMC, no hysteresis or temperature), constant R, no ageing, no thermal model, ideal switches, charger with exact CC-CV control. Capacity mismatch alone is not repaired by passive balancing; only the SoC mismatch is. Educational model, not a BMS design tool.
Checks in the page. (1) Coulomb counting equals the integral of the cell current for every cell; (2) identical cells deliver the nominal capacity; (3) a mismatched pack delivers min C_i SoC_i; (4) the highest cell never exceeds 4.2 V during charging.