Project: 500Ah LiFePO4 Bank Monitor Upgrade — From Voltage Logging to Coulomb Counting
TL;DR: After 130+ days and 712k samples on a Shelly Plus Uni, the 500Ah mixed-brand parallel bank study hit the limit of voltage-only monitoring. The new THT V2 carrier — XIAO ESP32-C3 + INA228 + DROK 200A/75mV low-side shunt — is commissioned and live as of July 16 2026. First anchored full charge: 115.39 Ah / 1586 Wh, 16.8 min absorption. It turns the bank from a voltage trend into a true energy instrument.
Full commissioning report and open data: https://github.com/wkcollis1-eng/Lifepo4-Battery-Banks
What the Shelly Plus Uni Did Right
The Shelly was perfect for Phase 1. It ran for 130+ days straight:
- 397 Ah validated (99.3% of nameplate @80% DoD) — architectural immunity holds
- MA-60s noise reduction validated: 42-50% (712k high-freq samples @ ∼3s)
- Temperature coefficient: +1.0 mV/°F, stasis drift -0.575 mV/day OLS
- Self-discharge: ∼0%/month confirmed, all loss from parasitic loads
- BMS balancing signature: ∼80-90 sec cycles above 14.4V
For $15 and 5 wires, it proved the 500Ah parallel topology doesn't diverge.
Shelly Limits on a 500Ah Flat Curve
This is exactly what you hit in the UPS build too:
- Voltage-only, 10 mV quantization. In the LiFePO4 plateau, 6.0 mV = 1% SOC for this bank. Shelly can't resolve SOC.
- No current. Parasitic draw had to be inferred from voltage drift (12.5 mA = Drok ∼10mA + Shelly ∼2-6mA). No efficiency, no SOC, no self-discharge direct measurement.
- Sense-tap IR error. Shelly read 24-34 mV low, load-dependent, because it shares a different IR path than the power bus. It tracked a 300 mV sag faithfully, but as a cross-check, not a reference.
- Flatlined idle. Anything < ∼0.05A reported as 0.0 W. Idle self-draw invisible.
- No local display, no independent protection. All alarms depended on Wi-Fi + HA.
That was fine for stasis monitoring. It fails for efficiency, SOC, and Ri trending.

The Upgrade: Bank-Monitor-THT V2
Same carrier philosophy as the UPS-MONITOR-THT V1 you shipped to OSH Park:
- Sensor: Adafruit INA228 breakout, on-board 15 mΩ shunt removed, 20-bit, ADCRANGE 0 = ±163.84 mV, 4120 µs x 128 averaging, 2s poll, Kelvin taps to DROK 200A / 75mV manganin shunt (375 µΩ) in negative leg, low-side
- Voltage: Fused VBUS lead from positive busbar — 195.3125 µV LSB survives end-to-end to HA CSV export, σ ≈ 0.10 mV (half an LSB)
- Brain: Seeed XIAO ESP32-C3, ESPHome
- Temp: DS18B20 on pack case, isolated mount
- UI: SSD1306 OLED STEMMA + wake button + status LED (slow-flash proof-of-life / solid active / fast FAULT)
- Power: Pololu D24V7F3 3.3v regulator
Firmware V1.21 at commissioning: 2s integration (stale-bus watchdog 10s, 8-16V and ≥350A plausibility guards), coulomb-counted SOC anchored at confirmed full-charge (≥14.20V sustained 60s + charger-stop edge), true signed mW power.
Independent hardware alerts written to INA228 at boot and latched on GPIO5: BUVL 12.20V, BOVL 14.80V, SOVL +250A, SUVL -250A, POL 1500W — decoded to alert_reason with operator acknowledge, independent of firmware.

What V2 Can Do That Shelly Can't
Capability | Shelly Plus Uni | V2 INA228 + DROK |
|---|---|---|
Current / Power | No — inferred from drift | Direct ±250A, mW resolution. Idle -0.08W now visible |
SOC | Impossible in plateau | Coulomb-counted, anchored at full charge. First anchor: 2026-07-16 19:50 UTC, SOC 100.0%, 1 cycle |
Energy Accounting | No | Ah/Wh integrators agree with independent CSV integration to 0.03-0.15h |
Internal Resistance | ∼4.9 mΩ system baseline (inferred) | DC-IR 3.73 mΩ @ 69°F ∼80% SOC, ohmic R0 2.63 mΩ. Trend metric with 45s dwell + ±15% stability gate, expected 3.3-3.5 mΩ |
Efficiency Ladder | Inverter 90.3% @440W avg only | Voltaic 95.8% (13.17V dis / 13.745V chg), Round-trip ∼94.8%, Charger AC→DC 95.7% ±2.5% (1586 Wh DC / 1657 Wh AC), Inverter 87-94% provisional + 127W self-consumption... |
Bill Collis
Nelectra
Open Green Energy
jaromir.sukuba