TECHNICAL MANUAL — PORTABLE BATTERY MANAGEMENT SYSTEM
Document Number: TM-BMS-001
Revision: A
Date: 2026
Classification: UNCLASSIFIED — AMATEUR RADIO TECHNICAL
REFERENCE
Applicability: Field Station Battery Systems, LiFePO4
and Li-Ion Packs
TABLE OF CONTENTS
- Introduction and Scope
- Battery Chemistry Reference
- BMS Architecture and Protection Functions
- BQ76920 Primary Protection IC
- Discrete Backup Protection Circuits
- Cell Balancing Theory and Implementation
- SOC Estimation: Coulomb Counting and Kalman Filter
- Low-Voltage Disconnect
- MPPT Solar Charge Integration
- ESP32 BLE Monitor System
- Pack Assembly and Cell Wiring
- Installation and Commissioning
- Test Procedures
- Fault Isolation and Troubleshooting
- Preventive Maintenance
Appendix A: Complete Parts Lists
Appendix B: BQ76920 Register Reference
Appendix C: Kalman Filter Mathematics
Appendix D: BLE GATT Service Definition
Appendix E: File Index
1. INTRODUCTION AND SCOPE
1.1 Purpose
This manual covers design, construction, commissioning, and maintenance of battery management systems for portable amateur radio field operation. Systems described include:
- LiFePO4 4S BMS using Texas Instruments BQ76920 — the preferred chemistry for field radio due to inherent safety and cycle life
- Li-Ion 3S/4S BMS using BQ76930 or Seiko S-8254 — higher energy density for weight-critical deployments
- Discrete backup protection — hardware-level overvoltage/undervoltage failsafe independent of all ICs
- Active and passive cell balancing — equalizing cell voltages to maximize pack capacity
- Extended Kalman Filter SOC — accurate state-of-charge estimation combining coulomb counting and open-circuit voltage correlation
- Low-Voltage Disconnect (LVD) — protecting cells from deep discharge during unattended operation
- Solar MPPT integration — field recharging with temperature-compensated charge profiles
- ESP32/CYD monitor — Bluetooth LE telemetry, real-time display, web interface
1.2 System Layered Protection Philosophy
The BMS uses a four-layer protection architecture. Failures cascade through layers; no single point of failure causes pack damage.
LAYER 1: BMS IC (BQ76920/BQ76930)
Hardware OV/UV/OC/SC per-cell; coulomb counter; cell balancing
Response time: 70 µs (SC) to 4 s (UV)
Controllable via I2C from ESP32
LAYER 2: Discrete Comparator Backup
TL431 + SCR latch (OV); LM393 (UV, OC); independent power
Response time: < 100 ms
No dependency on BMS IC or firmware
LAYER 3: ESP32 Firmware
Temperature management; charge control; LVD; MPPT interface
Response time: 250 ms – 2 s (poll rate)
Implements charging algorithm, balancing, efficiency tracking
LAYER 4: Hardware Fuses and PTC
ANL fuse (main), PTC resettable (balance wires)
Non-resettable; last resort
1.3 Safety Precautions
WARNING: Lithium cells at any charge level can deliver thousands of amperes into a short circuit. The resulting arc is instantaneous and can cause fires, severe burns, or explosion of the cell. NEVER short battery terminals. ALWAYS install the BMS before making any cell connections.
WARNING: LiFePO4 is significantly safer than NMC/LCO chemistry, but overcharged or damaged LiFePO4 cells can vent toxic gases (HF, PF5, CO). Work in ventilated spaces. Do not seal a damaged cell in an airtight enclosure.
CAUTION: Charging below 0°C causes irreversible lithium plating on the anode. A plated cell looks fully charged but has reduced capacity and a raised short-circuit risk. Never charge any lithium cell below 0°C.
CAUTION: Cells must not be over-discharged (below 2.5V for LiFePO4, below 3.0V for Li-Ion). Over-discharge causes copper dissolution into the electrolyte, permanently reducing capacity and increasing internal resistance.
2. BATTERY CHEMISTRY REFERENCE
2.1 LiFePO4 (Lithium Iron Phosphate)
LiFePO4 is the preferred chemistry for field ham radio operation. The olivine crystal structure of the iron phosphate cathode does not release oxygen under stress, preventing thermal runaway — the dangerous exothermic reaction that causes Li-Ion fires.
Cell Parameters:
| Parameter | Value | Notes |
|---|---|---|
| Nominal voltage | 3.20 V | Used for capacity calculations |
| Full charge (OCV) | 3.55–3.65 V | Measure after 1 hr rest |
| Charge cutoff | 3.60 V | BMS OV trip; charger setpoint |
| Discharge cutoff | 2.50 V | BMS UV trip; never go below |
| Self-discharge | < 3%/month | Excellent shelf life |
| Cycle life | 2000–5000 | At 80% depth of discharge |
| Operating temperature (charge) | 0°C to +45°C | Charging below 0°C = plating |
| Operating temperature (discharge) | −20°C to +60°C | Reduced capacity at extremes |
4S Pack (4 cells in series): - Nominal: 12.8V - Full charge: 14.4V (3.6V/cell × 4) - Discharge cutoff: 10.0V (2.5V/cell × 4)
The LiFePO4 Discharge Curve Problem:
The voltage changes very little between 20% and 80% SOC (approximately
13.0V to 13.2V for a 4S pack). This flat curve makes voltage-based SOC
estimation unreliable during operation. The Kalman filter SOC estimation
system (Chapter 7) addresses this limitation.
2.2 Li-Ion NMC (Nickel Manganese Cobalt)
NMC offers higher energy density (~150–200 Wh/kg vs. ~100–120 Wh/kg for LiFePO4) at the cost of reduced safety margin. The layered oxide structure of the NMC cathode releases oxygen when overheated or overcharged, enabling thermal runaway.
Cell Parameters:
| Parameter | Value | Notes |
|---|---|---|
| Nominal voltage | 3.60 V | |
| Full charge voltage | 4.20 V | NEVER exceed; triggers thermal runaway |
| Conservative charge | 4.10 V | Extends cycle life significantly |
| Discharge cutoff | 3.00 V | Capacity degradation accelerates below 2.8V |
| Cycle life | 300–500 (at 4.2V) | 1500+ at 4.1V/cell |
Pack Configurations: - 3S: 10.8V nominal, 12.6V full, 9.0V cutoff — for QRP gear - 4S: 14.4V nominal, 16.8V full, 12.0V cutoff — for standard 12V radios
Important: A 4S Li-Ion pack at 16.8V full charge exceeds the 13.8V nominal radio supply. Use a voltage regulator, or limit charge voltage to 4.1V/cell (16.4V), which is still above 13.8V but within most radio input tolerances (verify equipment specifications).
2.3 Cycle Life and Degradation
Cycle life depends primarily on:
- Charge voltage: Lower V_max = exponentially longer life. LiFePO4 at 3.45V/cell (80% capacity) lasts 10,000+ cycles; at 3.65V/cell it degrades faster.
- Depth of discharge: Shallower DoD extends cycle life. Cycling 20%–80% SOC (60% DoD) vs. 0%–100% (100% DoD) roughly triples cycle count.
- Temperature: Every 10°C above 25°C approximately halves cycle life (Arrhenius aging).
- Charge rate: Higher C-rate during charging generates more heat and SEI layer growth. Charge at ≤ 0.5C for longest life.
Field use recommendation:
Keep LiFePO4 packs between 20%–90% SOC for day-to-day operation. Only
charge to 100% when maximum runtime is needed for a specific activation.
Store at 50% SOC if not used for > 2 weeks.
3. BMS ARCHITECTURE AND PROTECTION FUNCTIONS
3.1 Required Protection Functions
A BMS must protect against six fault conditions:
| Fault | Abbreviation | Effect if unprotected | Response |
|---|---|---|---|
| Cell overvoltage | OV | Electrolyte decomposition, gas generation, cell failure | Open CHG FET |
| Cell undervoltage | UV | Copper dissolution, permanent capacity loss | Open DSG FET |
| Overcurrent discharge | OCD | Heating, separator damage, possible fire | Open DSG FET |
| Short circuit discharge | SCD | Catastrophic current spike, cell explosion | Open DSG FET (< 100 µs) |
| Over-temperature | OT | Accelerated aging, thermal runaway risk | Open CHG+DSG FET |
| Cold charging | LT (low temp) | Lithium plating, reduced capacity, safety risk | Open CHG FET |
3.2 FET Topology
The BMS switches the negative terminal of the pack (B−) through two MOSFETs in series:
Pack B− ──── DSG FET ──── CHG FET ──── P− (output)
DSG FET: controls discharge path. Body diode faces toward CHG FET.
CHG FET: controls charge path. Body diode faces toward B−.
Both ON: Normal operation (charge and discharge)
CHG OFF: Discharge only; body diode of CHG FET blocks reverse (charge) current
DSG OFF: Charge only; body diode of DSG FET blocks forward (discharge) current
Both OFF: Pack isolated
Why the negative path? The gate drive for an N-channel MOSFET in the negative path is referenced to pack negative, which is also the circuit ground. This avoids the need for a floating bootstrap supply. P-channel MOSFETs in the positive path are an alternative but have higher Rds_on for equivalent die size.
3.3 Common-Port vs. Separate-Port BMS
Common Port: Single output connector (P−). Charge and discharge share the same terminal. The BMS determines mode from current direction. - Simpler wiring; one output connector - Limitation: cannot charge and discharge simultaneously through separate BMS ports
Separate Port: C− for charging (charger connects here); P− for discharge (load connects here). CHG and DSG FETs operate independently. - More complex wiring - Allows simultaneous solar charging and radio operation without current direction ambiguity - Preferred for field station use
4. BQ76920 PRIMARY PROTECTION IC
4.1 Overview
The Texas Instruments BQ76920 is a purpose-built 3–5 cell monitor and protector IC. It provides all required protection functions in a single TSSOP-24 package.
Key capabilities: - 14-bit ADC, 1.22 mV voltage resolution, ±1% accuracy - Internal coulomb counter (16-bit, 250 µA LSB) - Per-cell passive balance FET outputs (external resistors) - I2C interface for host communication (ESP32) - ALERT interrupt output (open-drain, fires on any fault) - Factory-calibrated OTP registers (ADCGAIN, ADCOFFSET — read at startup)
4.2 Register Configuration for LiFePO4 4S
The BQ76920 thresholds are set via registers. Key registers:
OV_TRIP (0x09): Sets overvoltage trip voltage.
Formula: V_OV = (OV_TRIP + 1) × 50.6 mV + 2.0 V
For 3.65V: OV_TRIP = (3.65 − 2.0) / 0.0506 − 1 = 31.6 → write 0x20
(gives 3.663V, slightly above 3.65V; conservative)
UV_TRIP (0x0A): Sets undervoltage trip
voltage.
Formula: V_UV = (UV_TRIP + 1) × 50.6 mV + 1.0 V
For 2.80V: UV_TRIP = (2.80 − 1.0) / 0.0506 − 1 = 34.6 → write 0x22
(gives 2.834V)
PROTECT1 (0x06): Short circuit protection.
SCD_THRESH = 0b011 → 100 mV on sense resistor
With 2 mΩ shunt: I_SCD = 100 mV / 0.002 Ω = 50A
SCD_DELAY = 0b00 → 70 µs
PROTECT2 (0x07): Overcurrent protection.
OCD_THRESH = 0b011 → 50 mV on sense resistor
With 2 mΩ shunt: I_OCD = 50 mV / 0.002 Ω = 25A
OCD_DELAY = 0b01 → 20 ms
4.3 Startup Sequence
The ESP32 must perform the following sequence on power-up:
- Read ADCGAIN1 (0x50) and ADCGAIN2 (0x59) → compute g_adc_gain in µV/LSB
- Read ADCOFFSET (0x51) → store as g_adc_offset in mV
- Write SYS_CTRL1 → enable ADC and select thermistor pin
- Write SYS_CTRL2 → enable CHG and DSG FETs; enable coulomb counter
- Write OV_TRIP, UV_TRIP, PROTECT1, PROTECT2, PROTECT3 → set thresholds
- Write SYS_STAT (0x00) → clear any startup fault flags (write 0xFF)
- Begin reading cell voltages and CC register
If ADCGAIN registers are not read and applied, the cell voltage calculations will be inaccurate. The factory calibration typically places gain at 365–380 µV/LSB; not reading the registers and assuming 365 µV/LSB can introduce up to 40 mV per-cell error.
4.4 Cell Voltage Calculation
V_cell(n) = raw_adc × (ADCGAIN / 1,000,000) + ADCOFFSET / 1000
Where:
raw_adc = 14-bit ADC reading from BQ_VC(n)_HI + BQ_VC(n)_LO
ADCGAIN = calibration value in µV/LSB (read from OTP, typically 365–380)
ADCOFFSET = calibration offset in mV (read from OTP, signed byte)
4.5 Coulomb Counter
The BQ76920 integrates current continuously. The CC register (0x32/0x33) is a signed 16-bit value that increments/decrements based on current direction.
I_actual = CC_register × (ADCGAIN / 4) / (R_sense × 1,000,000)
The CC register saturates at ±32767 and does not roll over automatically — firmware must read and reset it periodically. Recommended: read every 250 ms; accumulate in a software float accumulator. Reset CC by clearing the CC_EN bit and re-enabling.
5. DISCRETE BACKUP PROTECTION CIRCUITS
5.1 Overvoltage Backup (TL431 + SCR Latch)
The TL431 is an adjustable shunt reference with a built-in comparator. When the REF pin voltage exceeds 2.495V (internal reference), the device conducts. This is used to fire an SCR (silicon controlled rectifier) that latches the charge FET gate low.
Operating principle: 1. V_cell rises above trip threshold → TL431 REF pin exceeds 2.495V 2. TL431 cathode current flows → drives NPN transistor base 3. NPN collector drives SCR gate → SCR fires and latches 4. SCR holds CHG FET gate at battery negative → FET stays OFF 5. Once SCR fires, it remains conducting until anode current falls below holding current (~5 mA) 6. Recovery: remove charger (interrupts anode current) → SCR unlatches
Trip voltage setting:
V_trip = 2.495 × (R_A + R_B) / R_B
For V_trip = 3.65V (LiFePO4): R_A / R_B = (3.65/2.495) − 1 = 0.463
Using R_B = 220 kΩ: R_A = 102 kΩ → use 100 kΩ (gives 3.630V, slightly
conservative)
Why use a latching SCR? A simple comparator with relay would reset automatically when V_cell drops slightly below the trip threshold. This could allow repeated charge/discharge cycling around the overvoltage threshold, damaging cells. The SCR latch requires deliberate operator intervention (remove charger) to reset.
5.2 Undervoltage Backup (LM393)
The LM393 dual comparator monitors pack voltage and opens the discharge FET when voltage falls below the UV threshold. Unlike the OV circuit, UV recovery is automatic — when a charger is connected and voltage rises, the LM393 output changes state and allows the FET to conduct.
Hysteresis is essential. Without hysteresis, the comparator oscillates rapidly around the threshold as the FET switching changes the load current, which changes the battery terminal voltage. A 50–100 mV hysteresis band prevents this: - Disconnect at 11.0V (4S LiFePO4 UV threshold) - Reconnect at 11.1V (hysteresis restores 100 mV above disconnect)
5.3 Short Circuit Detection (Fast Comparator Path)
The short circuit path uses the same LM393 but with no RC delay on the output. Response time is limited by comparator propagation delay (~1 µs) and MOSFET turn-off time (~100 ns). Total SCD response: < 2 µs.
At 50A through 2 mΩ shunt: V_sense = 100 mV. At 100A (dead short): V_sense = 200 mV. Set SCD threshold to 150 mV (75A) to provide margin above maximum normal peak current.
5.4 Backup Circuit Independence
The backup circuits must operate independently of: - BMS IC power supply (BQ76920 derives power from the top cell) - ESP32 (may be unresponsive during firmware crash) - I2C communication (bus failure should not disable protection)
Power supply for backup comparators: Run LM393 and TL431 circuits from a separate voltage reference derived from a middle cell tap (e.g., VC2, approximately 6.4V for 2S reference). Use a 5V zener regulator. This supply remains valid even if the BQ76920 REG pin supply fails.
6. CELL BALANCING THEORY AND IMPLEMENTATION
6.1 Why Cells Go Out of Balance
All cells in a series string are manufactured with slight differences in: - Capacity (Ah): ±3–5% variation even within the same bin - Internal resistance (mΩ): Higher-resistance cells heat more, age faster - Self-discharge rate: Varies cell to cell; some discharge slightly faster
Over hundreds of cycles, these small differences accumulate. Without balancing, the cell with lowest capacity reaches UV cutoff first during discharge (limiting pack capacity), and the cell with highest capacity reaches OV first during charging (limiting charge input). The effective capacity is constrained by the weakest cell in both directions.
6.2 Top-of-Charge Balancing Algorithm
The firmware implements top-balance: cells are equalized only when the pack is near full charge (SOC > 85%). This strategy: - Ensures all cells reach 100% SOC together - Uses the absorption phase (when charge current is tapering) for balancing - Avoids unnecessary resistor heating during normal discharge cycles
Balance decision at each 2-second tick:
if (SOC < 85%) → disable all balance FETs (no balancing below 85%)
if (cell temperature > 45°C) → disable all balance FETs (thermal protection)
find V_min = minimum cell voltage in pack
for each cell:
if (V_cell > V_min + 10 mV) → enable balance FET for this cell
else → disable balance FET
when all cells within 5 mV → disable all balance FETs (balanced)
6.3 Passive Balance: Resistor Selection
The balance current flows through R_BAL when the BQ76920 balance FET for that cell is enabled:
I_bal = V_cell / R_BAL (approximately; FET Rds_on is small)
Trade-off: - Low R_BAL (e.g., 10 Ω): 360 mA at 3.6V; fast balancing (hours); 1.3W dissipation - High R_BAL (e.g., 47 Ω): 76 mA at 3.6V; slow balancing (days); 0.3W dissipation
For field use where overnight charging is available: 10 Ω is recommended. The 1.3W per resistor is manageable with a ventilated bracket; balance completes in 1–5 hours for typical imbalances encountered in field operations.
Balance current flows through the CELL being balanced, not across the pack. The bottom terminal of the balance resistor connects to the cell’s bottom junction (the previous cell’s positive terminal). Energy is wasted as heat in the balance resistor — not transferred to lower-SOC cells. This is the fundamental limitation of passive balancing.
6.4 Active Balancing (JK BMS Module)
Active balancing transfers energy from high-SOC cells to low-SOC cells using an inductor-based converter. The JK BMS active balancer operates at approximately 88% efficiency.
For a 50 Ah pack with 100 mV imbalance: - ΔAh = 100 mV × 50 Ah / 3.2 V = 1.5 Ah - At 1A balance current (JK BMS): t = 1.5 Ah / 1A = 1.5 hours - Energy saved vs. passive: 1.5 Ah × 3.2 V × (1 − 0.88) = 0.58 Wh
The 0.58 Wh savings is small, but over thousands of cycles this accumulates, and the cells are maintained in better condition by avoiding the heat of passive dissipation.
Active balancing is most beneficial when: - Pack is > 50 Ah (imbalance represents significant capacity loss) - Cells are used at high C-rates generating larger voltage divergence - Pack temperature is high (passive heat is unwanted)
7. SOC ESTIMATION: COULOMB COUNTING AND KALMAN FILTER
7.1 Why SOC is Difficult
The State of Charge of a battery is not directly measurable. The two observable quantities — terminal voltage and current — provide indirect information:
- Voltage: Reliable indicator only at rest (OCV = Open Circuit Voltage). Under load, the terminal voltage drops due to IR losses and polarization. A LiFePO4 cell under 10A load may read 0.3V lower than its OCV.
- Current integration (coulomb counting): Accurate over short time periods but accumulates error from measurement offset and sensor noise over hours. Also requires knowing the initial SOC.
No single method is perfect. The EKF combines both.
7.2 Coulomb Counting
Coulomb counting integrates current over time to track accumulated charge:
SOC(t) = SOC(t₀) + [∫ η_c × I(t) dt] / Q_nominal × 100%
Where:
η_c = Coulombic efficiency (0.97 for LiFePO4 during charging; 1.0 during discharge)
I(t) = net current (positive = charging, negative = discharging)
Q = rated capacity in Ah
Coulombic efficiency: Not all charge input emerges as discharge output. The difference (3% for LiFePO4) is lost to side reactions (SEI layer growth, electrolyte decomposition). If η_c is not applied, the SOC estimate will drift upward over many cycles.
Accuracy limitation: A current sensor with 10 mA offset error at 1A average current introduces 1% SOC error per hour. Over a 10-hour activation, this accumulates to 10% error — significant. INA226 at 16-bit resolution has < 1 mA offset typical, limiting accumulated error to < 0.5% per hour.
7.3 Extended Kalman Filter
The EKF is a recursive estimator that optimally combines two sources of information:
- Prediction: What we expect SOC to be based on the dynamic model (coulomb counting)
- Measurement: What we can observe (OCV mapped to SOC via the OCV-SOC curve)
The “Extended” in EKF refers to the linearization of the nonlinear OCV-SOC relationship at each time step.
EKF State Equations:
State: x = SOC (fraction, 0.0 to 1.0)
Prediction step (each time increment Δt):
x̂(k|k-1) = x̂(k-1|k-1) + η_c × I_net × Δt / Q_nom
P(k|k-1) = P(k-1|k-1) + Q_noise
Update step (only when battery is at rest and OCV is valid):
H = dV_OCV/dSOC (derivative of OCV curve at current SOC estimate)
y = SOC_from_OCV (OCV measured → mapped to SOC via lookup table)
S = H² × P(k|k-1) + R_noise (innovation covariance)
K = P(k|k-1) × H / S (Kalman gain)
x̂(k|k) = x̂(k|k-1) + K × (y - x̂(k|k-1))
P(k|k) = (1 - K × H) × P(k|k-1)
Notation:
Q_noise = process noise covariance (uncertainty in current measurement; ~1×10⁻⁵)
R_noise = measurement noise covariance (uncertainty in OCV-SOC mapping; ~0.01)
K = Kalman gain (how much to trust measurement vs. prediction)
OCV Rest Requirement:
The OCV measurement is only valid when current is < 100 mA and the
pack has rested for at least 60 seconds. The EKF firmware watches for
this condition and gates the update step accordingly.
Practical Effect:
After a day of field use (charge → operate → charge), coulomb counting
may have drifted ±5% SOC. When the operator stops for lunch and the pack
rests, the EKF corrects the estimate using OCV. The display SOC snaps to
a more accurate value. This self-correction is the primary advantage of
EKF over pure coulomb counting.
7.4 OCV-SOC Tables
The OCV-SOC relationship is chemistry-specific and must be measured or obtained from cell manufacturer datasheets. The tables in the firmware were derived from published LiFePO4 and NMC OCV data at 20°C. At other temperatures:
- Warm cells (> 30°C): OCV shifts slightly higher for a given SOC
- Cold cells (< 10°C): OCV shifts lower; the flat LiFePO4 region becomes less flat
- Temperature correction: add 2 mV/°C to OCV measurement before table lookup (approximate)
For best accuracy: calibrate OCV-SOC table against your specific cell type by doing controlled discharge measurements at known SOC.
8. LOW-VOLTAGE DISCONNECT
8.1 Purpose and Behavior
The LVD circuit protects battery cells from deep discharge during unattended operation — overnight APRS, weather stations, remote sensors.
Design parameters (4S LiFePO4): - Disconnect voltage: 11.5V pack (2.875V/cell — well above 2.5V UV cutoff but providing warning margin) - Reconnect voltage: 12.5V pack (requires charger to restore voltage before load reconnects) - Hysteresis: 1.0V — prevents load cycling around threshold
Rationale for 11.5V disconnect (not 10.0V UV):
If discharge is allowed to continue to 10.0V (BMS UV trip), the pack is
at near-zero SOC. Reconditioning from near-zero frequently accelerates
aging. The LVD at 11.5V conserves ~10% SOC, leaves cells in a healthier
state, and provides a visible “pack nearly empty” indication to the
operator before complete shutdown.
8.2 Latching LVD
A non-latching LVD would reconnect immediately when a charger raises the battery voltage. This is usually correct. However, if the load itself (a large capacitor bank) caused a momentary voltage dip, a non-latching LVD would disconnect and reconnect repeatedly.
The firmware implements a latching LVD: once the LVD trips, the load is not reconnected until: 1. Pack voltage rises above 12.5V (charger connected and charging), AND 2. SOC estimate exceeds 20%
This prevents re-energization on a momentary recovery — the pack must genuinely be partially recharged before the load returns.
8.3 LVD vs. BMS UV Protection
These are different protections:
| Feature | BMS UV (BQ76920) | LVD (Firmware + Hardware) |
|---|---|---|
| Monitors | Per-cell voltage | Pack terminal voltage |
| Trip point | 2.5V/cell (10.0V pack) | 11.5V pack |
| Recovery | Automatic (cell V rises) | Requires charger + SOC > 20% |
| Response | 2–4 s (BQ76920 delay) | < 100 ms |
| Purpose | Final safety cutoff | Conservation / capacity protection |
Both must be present. The LVD is a conservation measure; the BMS UV is a safety measure.
9. MPPT SOLAR CHARGE INTEGRATION
9.1 Charge Setpoint Communication
The BMS ESP32 communicates charge setpoints to the MPPT controller ESP32 via a dedicated UART (9600 baud, ASCII protocol):
"VSET=14.40 ISET=25.0\n" → Bulk charge: 14.4V limit, 25A limit
"VSET=14.40 ISET=10.0\n" → Absorption: 14.4V, taper to 10A
"VSET=13.50 ISET=5.0\n" → Float: 13.5V, minimal trickle
"VSET=0.0 ISET=0.0\n" → Charge inhibit (temperature, OV fault)
The MPPT controller parses these commands and updates its PID setpoints accordingly. The BMS monitors I_charge via INA226; if the charge current exceeds ISET by > 10%, the BMS sends a reduced ISET command to the MPPT.
9.2 Temperature-Adjusted Charge Voltage
LiFePO4 charge voltage must be reduced at elevated cell temperature to prevent overvoltage stress on warmed cells (internal resistance drops; terminal voltage rises faster than expected):
V_adj = V_nominal - (T_cell - 25°C) × 0.003 V/°C × N_cells
= 14.4V - (T - 25) × 0.012
At T = 40°C: V_adj = 14.4 - 0.18 = 14.22V
At T = 10°C: V_adj = 14.4 + 0.18 = 14.58V (slightly higher charge voltage acceptable in cold)
At T = 0°C: Charge inhibited entirely
The BMS reads NTC temperature every 2 seconds and sends an updated VSET command whenever the temperature changes by more than 2°C.
9.3 Multi-Source Charge Arbitration
When both solar and a mains charger are simultaneously connected: - Both sources connect through separate Schottky diodes (MBR3045, 30A, 0.3V drop) - The source with higher terminal voltage provides more current (natural ORing) - BMS monitors total I_charge; if > I_max, reduces MPPT current limit - Mains charger current cannot be reduced (no control interface); MPPT backs off
Priority logic: 1. If V_solar > V_mains + 0.1V: solar provides all current (mains Schottky reverse-biased) 2. If V_mains > V_solar: mains provides current; solar adds what it can 3. Combined current limited by BMS I_max command to MPPT
10. ESP32 BLE MONITOR SYSTEM
10.1 Bluetooth LE GATT Service
The ESP32 implements a BLE GATT server with a custom BMS service. Any BLE-capable device (phone, tablet, another ESP32) can connect and receive real-time battery data.
BMS Service UUID:
4fafc201-1fb5-459e-8fcc-c5c9c331914b
Characteristics:
| Characteristic | UUID (suffix) | Data | Update Rate |
|---|---|---|---|
| Cell Voltages | …26a8 | 4× float32 (V) | 2 s |
| SOC | …26a9 | float32 (%) | 2 s |
| Current | …26aa | 2× float32 (I_chg, I_load, A) | 250 ms |
| Temperature | …26ab | 2× float32 (cell, FET, °C) | 2 s |
| Status Flags | …26ac | uint8 (bit field) | 2 s |
| Efficiency | …26ad | 2× float32 (coulombic %, energy %) | 2 s |
Status flag byte:
Bit 0: OV fault active
Bit 1: UV fault active
Bit 2: OC/SC fault active
Bit 3: Over-temperature active
Bit 4: CHG FET enabled
Bit 5: DSG FET enabled
Bit 6: LVD relay connected
Bit 7: Spare
10.2 BLE Client Application
Any BLE scanner application (nRF Connect, BLE Scanner, or custom app) can read the characteristics. The data encoding uses native float32 little-endian format.
Python example (laptop/Raspberry Pi BLE client):
from bleak import BleakClient
import struct
BMS_SERVICE = "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
CELLV_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
SOC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a9"
async def read_bms(address):
async with BleakClient(address) as client:
data = await client.read_gatt_char(CELLV_UUID)
cells = struct.unpack('<ffff', data)
print(f"Cells: {[f'{v:.3f}V' for v in cells]}")
soc = struct.unpack('<f', await client.read_gatt_char(SOC_UUID))[0]
print(f"SOC: {soc:.1f}%")10.3 CYD Display Pages
The display rotates through four pages automatically (every 10 seconds):
- Cell Voltages: Individual cell voltage bars + values; pack total at bottom
- SOC: Large percentage readout; SOC bar; remaining time; EKF vs. coulomb comparison; temperature
- Power Flow: Charge and load current; power; FET status indicators; Wh accumulators
- Efficiency: Coulombic efficiency %; energy efficiency %; session Ah/Wh totals; BLE UUID reference
Any fault overrides all pages with a red alarm screen showing the active fault(s) and BQ76920 SYS_STAT register value.
10.4 Web Interface
The ESP32 hosts a web server on WiFi AP mode (SSID:
BMS-Monitor, password: hamradio): - Connect to
192.168.4.1 in any browser - / — Summary HTML
page (auto-refreshes every 3 s) - /api/status — JSON
telemetry (all measurements, faults, efficiency data) -
/api/reset — Reset session energy counters
11. PACK ASSEMBLY AND CELL WIRING
11.1 Cell Matching and Selection
Never mix cells of different models, manufacturers, or ages
in one series string.
Within a pack, all cells should have: - Same model number (same
chemistry lot) - Capacity within 5% of each other (verify by individual
discharge test before assembly) - Internal resistance within 10%
(measure with dedicated impedance meter at 1 kHz) - Same initial SOC
(pre-balance to same voltage before series connection)
Pre-balance cells before first connection:
Individually charge each cell to the same voltage (e.g., 3.30V for
LiFePO4) before connecting in series. If cells are connected at
different voltages, large equalization currents flow between cells
through the balance wires, potentially damaging the BMS balance circuit
or cells.
11.2 LiFePO4 Prismatic Cell Assembly
Cell orientation: All terminals on same side. Positive terminal of Cell 1 faces away from negative terminal of Cell 2 (alternating orientation reduces wiring complexity for bus bars).
Bus bar installation: 1. Clean cell terminal surfaces with isopropyl alcohol 2. Apply anti-oxidant compound (NoAlox) to aluminum terminals 3. Torque M6 bolts to 4–5 N·m (35–44 in-lb) — do NOT over-torque 4. Verify 0V between adjacent cells (no accidental short) before final assembly 5. Install terminal covers (insulating caps) on all exposed bolt heads immediately
Cell compression:
Apply 10–15 psi perpendicular to the large face of each cell: - Two 3mm
aluminum plates (or printed template + aluminum) - Four M8 threaded rods
through drilled holes in plates - Tighten M8 nuts until plates are snug
but cells are not visibly distorted - Verify all four M8 fasteners are
at equal tension (torque to 12 N·m each)
11.3 18650 Pack Assembly
Spot welding vs. soldering:
Spot welding with 0.15mm × 8mm pure nickel strip is the correct method.
Soldering directly to 18650 cell terminals is possible but risks thermal
damage to the cell separator and anode. If spot welder is unavailable:
use pre-welded tabbed cells, or use high-quality spring-contact cell
holders (limited to < 5A).
Parallel connections first: Build each parallel group (e.g., 2P or 4P) before connecting in series. Connecting parallel cells at equal voltage first avoids large equalization currents.
Balancing nickel strips: Route nickel strips so all parallel cells in a group have equal resistance to the series connection point. Asymmetric resistance leads to unequal current sharing during charging and discharging.
11.4 Balance Tap Wiring (Critical)
The balance tap wires carry only milliamperes but must be connected correctly. An error in balance wiring is the most common BMS failure cause.
Wire from BMS connector to cell junctions (4S): - B− (BMS pin): Cell 1 negative terminal - VC1 (BMS pin): Junction between Cell 1 positive and Cell 2 negative - VC2 (BMS pin): Junction between Cell 2 positive and Cell 3 negative - VC3 (BMS pin): Junction between Cell 3 positive and Cell 4 negative - B+ (BMS pin): Cell 4 positive terminal
Use color-coded wires: Black (B−), Red-1 (VC1), Red-2 (VC2), Red-3 (VC3), Red-4 (B+). Apply colored heat shrink at both ends.
Measurement verification: Before final BMS connection, measure voltage at each tap point: - B− to B−: 0V (reference) - B− to VC1: V_cell1 (should be ~3.2–3.6V) - B− to VC2: V_cell1 + V_cell2 (should be ~6.4–7.2V) - B− to VC3: V_cell1 + V_cell2 + V_cell3 (should be ~9.6–10.8V) - B− to B+: Full pack voltage (should be ~12.8–14.4V)
Incorrect wiring at this step can immediately destroy the BMS IC.
12. INSTALLATION AND COMMISSIONING
12.1 Pre-Commissioning Checklist
Before powering the BMS system for the first time:
12.2 First Power-Up Sequence
- Connect balance tap wires to BMS (one at a time, starting from B−)
- Verify BMS LED or ESP32 boot indication
- Check that CHG and DSG FETs are enabled (firmware default)
- Measure V_out at Anderson Powerpole terminal: should equal pack voltage
- Connect load (resistor bank, not valuable radio equipment)
- Verify load current reads correctly on CYD display and BLE
- Connect charger; verify charge current reads correctly
12.3 Initial Calibration
SOC initialization:
On first power-up, the EKF initializes from OCV if the pack has been at
rest. If the pack was just assembled, let it rest at least 30 minutes
before checking SOC. The firmware reads pack voltage; if current is <
100 mA, it uses the OCV-SOC table to initialize SOC.
Manual SOC override (web interface if OCV initialization is uncertain):
POST http://192.168.4.1/api/setsoc
Body: soc=50.0
Current calibration verification:
Apply a known load (e.g., 10 Ω resistor: I = 12.8V / 10 = 1.28A). Verify
INA226 reads 1.28A ± 0.05A. If not, check shunt resistance and INA226
calibration register value.
13. TEST PROCEDURES
13.1 BMS Protection Test — Overvoltage
Procedure: Apply variable bench supply to cell tap VC1 (Cell 1 +). Increase voltage to above 3.65V while monitoring BQ76920 SYS_STAT via I2C.
Expected result: BQ76920 OV flag sets (bit 3 in SYS_STAT = 0x00); CHG FET disabled within configured delay (2 s for OV_DELAY = 0b10); ALERT pin pulses LOW; display shows OV fault.
Acceptance: OV protection fires at ≤ 3.70V on affected cell. CHG FET confirmed disabled by voltmeter at output (charge current blocked).
13.2 BMS Protection Test — Undervoltage
Procedure: Drain one cell with a resistive load on its balance tap until V_cell < 2.80V.
Expected result: BQ76920 UV flag sets; DSG FET disabled within 4 s; display shows UV fault.
Recovery test: Apply charger. UV fault should clear when cell V rises above UV_TRIP threshold.
13.3 BMS Protection Test — Short Circuit
Caution: Short circuit test must be performed with a controlled resistance (0.01–0.1 Ω), not a dead short. Place a 0.05 Ω test resistor temporarily across P+ / P−.
Procedure: Monitor drain current with oscilloscope current probe. Connect test resistor. Record time to FET turn-off.
Expected result: BQ76920 SCD fires within 70–200 µs; FET turn-off within 100 µs of SCD.
13.4 LVD Test
Procedure: Reduce pack voltage artificially by connecting a resistive load until V_pack < 11.5V.
Expected result: LVD relay opens; display shows “LVD TRIP”; load disconnects. Pack voltage stabilizes (no load). Apply charger; verify load does not reconnect until V_pack > 12.5V and SOC > 20%.
13.5 EKF SOC Accuracy Test
Procedure: 1. Fully charge pack; set SOC = 100% via web interface. 2. Discharge at constant 5A load for exactly 10 Ah (stop when coulomb counter reads 50%). 3. Let pack rest for 2 hours. 4. Record EKF SOC estimate. 5. Compare to expected: 100% − (10 Ah / Q_rated × 100%) = expected SOC.
Acceptance: EKF SOC within ±5% of expected after rest period. Coulomb counting alone within ±8% acceptable. If EKF drifts > 10% from expected, check ADCGAIN calibration and INA226 offset.
13.6 Charge Efficiency Measurement
Procedure: 1. Reset energy counters (web interface:
/api/reset). 2. Charge pack from 50% to 100% at constant 5A
rate. Record Ah_in and Wh_in from display. 3. Discharge pack from 100%
to 50% at constant 5A rate. Record Ah_out and Wh_out. 4. Calculate: η_Q
= Ah_out / Ah_in; η_E = Wh_out / Wh_in.
Expected results (LiFePO4): - Coulombic efficiency η_Q: 97–99% - Round-trip energy efficiency η_E: 92–96%
Values below 90% for η_Q indicate: - Current sensor error (recheck INA226 calibration) - High self-discharge (check for balance resistors left enabled) - Cell internal resistance too high (aging or damaged cell)
14. FAULT ISOLATION AND TROUBLESHOOTING
14.1 Troubleshooting Philosophy — The Electron’s Path
Trace the electron from cell negative, through the BMS FET stack, to the load. At each node, verify expected voltage and current. Where voltage or current is wrong, the fault is nearby.
For BMS faults: isolate whether the fault is in the sensing path (wrong reading triggers false protection) or in the switching path (true fault exists but is not being cleared).
14.2 Fault Table
| Symptom | Probable Cause | Diagnostic |
|---|---|---|
| No output; no fault flags | BMS FETs off at startup; SYS_CTRL2 not written | Read BQ_SYS_CTRL2; write 0x43 to re-enable |
| OV fault; all cells normal | Noise on VC pin; missing bypass cap | Add 0.1µF from affected VC pin to V− |
| UV fault; cells all > 3.0V | Wrong UV_TRIP register; ADCOFFSET error | Re-read ADCGAIN/ADCOFFSET; recalculate |
| OV fault fires at wrong voltage | Incorrect ADCGAIN calibration | Measure actual cell V; compare to BQ76920 reading; correct calibration |
| FETs won’t re-enable after fault | SYS_STAT flag not cleared; fault condition still present | Check SYS_STAT register; fix fault; write 0xFF to SYS_STAT |
| Balance resistors burning up | Balance FETs left on continuously | Check CELLBAL1 register; verify firmware disables after balance |
| SOC drifts > 10% per hour | INA226 offset error; wrong shunt resistance programmed | Disconnect load; measure I at zero current; should be < 5 mA |
| EKF never converges | Pack never rests long enough (60 s) | Ensure load is off for > 60 s; check rest detection threshold |
| BLE not connecting | BLE advertising stopped after client disconnect | Power cycle ESP32; verify BLEDevice::startAdvertising() in onDisconnect |
| MPPT not responding to setpoints | UART wiring; baud rate mismatch; ESP32 not sending | Check UART wire (TX→RX, RX←TX); verify mpptSerial.begin(9600) |
| LVD trips at wrong voltage | Divider resistors incorrect; comparator reference | Measure V at LM393 (+) and (−) pins with known V_pack |
| Charge efficiency < 90% | Balance resistor left enabled during discharge | Disable balance FETs when not in top-balance; check bal_mask |
14.3 I2C Communication Debug
Use the ESP32 serial port (115200 baud) for diagnostic output. Add temporary code:
// I2C device scan
for (uint8_t addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.printf("Found device at 0x%02X\n", addr);
}
}
// Expected: 0x08 (BQ76920), 0x40 (INA226), 0x41 (INA226), 0x48 (ADS1115)If BQ76920 (0x08) is not found: - Verify 3.3V on BQ76920 REG pin (requires > 1.5V between cell taps) - Check 10Ω resistor from VC4 (top cell) to REG pin - Check V− pin (should be tied to CELL1−, not a floating ground) - Verify 4.7 kΩ I2C pull-ups to 3.3V on both SDA and SCL
15. PREVENTIVE MAINTENANCE
15.1 Quarterly Inspection
Cell inspection: - Visual: look for swollen cells (pouch/prismatic) or protruding top buttons (18650) - Swelling indicates gas generation — cell is failing; isolate and dispose properly - Check bus bar connections for oxidation; clean and re-torque if needed
BMS inspection: - Check balance resistors for discoloration or burned smell (overheating) - Verify terminal screws are tight (heat cycling loosens terminals) - Clean ventilation openings; remove any insect nests or debris
Software: - Review charge/discharge efficiency trend; declining η_E indicates aging - Check balance log: cells that require > 2 hours to balance at 90% SOC are diverging - Reset session energy counters; start fresh efficiency baseline
15.2 Annual Capacity Test
A full capacity test provides the most accurate assessment of pack health:
- Charge to 100% SOC using standard CC/CV profile
- Rest 1 hour
- Discharge at C/5 rate (10A for 50 Ah pack) to UV cutoff
- Record discharged Ah from INA226 accumulator
- Compare to rated capacity: Health % = Measured Ah / Rated Ah × 100%
Action thresholds: - > 90%: Pack is healthy; continue operation - 80–90%: Monitor quarterly; plan replacement - < 80%: Replace pack; capacity loss is significant for field use - Any cell with V_max < 3.4V at full charge: isolate that cell; replace pack
15.3 Storage Preparation
For storage > 2 weeks: 1. Charge to 50% SOC (approximately 13.1V for 4S LiFePO4) 2. Disconnect all loads including ESP32 (prevents slow self-discharge through BMS quiescent current) 3. Store in cool, dry location (15–25°C ideal; avoid > 35°C or freezing) 4. Check voltage monthly; recharge to 50% if voltage drops below 12.5V (4S LiFePO4) 5. Do NOT store Li-Ion cells fully charged — store at 40–60% SOC
APPENDIX A: COMPLETE PARTS LISTS
See individual schematic files for complete per-circuit parts lists:
- sch_lifepo4_4s_bms.txt — BQ76920 primary BMS, FET stage -
sch_liion_bms.txt — BQ76930 and S-8254 Li-Ion BMS -
sch_cell_balancing.txt — Passive and active balance
circuits - sch_protection_lvd.txt — TL431/LM393 backup
protection, LVD, pre-charge - sch_mppt_integration.txt —
Source ORing diodes, UART interface, INA226
APPENDIX B: BQ76920 REGISTER REFERENCE
| Register | Address | Description | Default |
|---|---|---|---|
| SYS_STAT | 0x00 | Status flags (OV/UV/SCD/OCD/OVRD/XREADY/WAKE) | 0x00 |
| CELLBAL1 | 0x01 | Balance FET enable (bits 0–4) | 0x00 |
| SYS_CTRL1 | 0x04 | ADC_EN, TEMP_SEL, SHUT_A, SHUT_B | 0x00 |
| SYS_CTRL2 | 0x05 | CHG_ON, DSG_ON, DELAY_DIS, CC_EN, CC_ONESHOT | 0x00 |
| PROTECT1 | 0x06 | SCD_THRESH[2:0], SCD_DELAY[1:0] | — |
| PROTECT2 | 0x07 | OCD_THRESH[3:0], OCD_DELAY[2:0] | — |
| PROTECT3 | 0x08 | OV_DELAY[1:0], UV_DELAY[1:0] | — |
| OV_TRIP | 0x09 | Overvoltage threshold | — |
| UV_TRIP | 0x0A | Undervoltage threshold | — |
| VC1_HI/LO | 0x0C/0D | Cell 1 voltage (14-bit) | — |
| VC2_HI/LO | 0x0E/0F | Cell 2 voltage | — |
| VC3_HI/LO | 0x10/11 | Cell 3 voltage | — |
| VC4_HI/LO | 0x12/13 | Cell 4 voltage | — |
| ADCGAIN1 | 0x50 | ADC gain calibration bits[7:5] | OTP |
| ADCOFFSET | 0x51 | ADC offset (signed, mV) | OTP |
| ADCGAIN2 | 0x59 | ADC gain calibration bits[2:1] | OTP |
| CC_HI/LO | 0x32/33 | Coulomb counter (signed 16-bit) | — |
APPENDIX C: KALMAN FILTER MATHEMATICS
Full derivation for the scalar EKF (single state):
State transition: x(k) = x(k-1) + u(k) + w(k)
where u(k) = η_c × I_net × Δt / Q_nom (control input: coulomb count increment)
w(k) ~ N(0, Q) (process noise)
Observation model: y(k) = h(x(k)) + v(k)
where h(x) = SOC_from_OCV(x) (nonlinear OCV-SOC mapping)
v(k) ~ N(0, R) (measurement noise)
Prediction:
x̂⁻(k) = x̂(k-1) + u(k)
P⁻(k) = P(k-1) + Q
Update (at rest periods only):
H(k) = ∂h/∂x |at x̂⁻(k) (Jacobian: slope of OCV-SOC table)
S(k) = H(k)² P⁻(k) + R
K(k) = P⁻(k) H(k) / S(k)
x̂(k) = x̂⁻(k) + K(k)[y(k) - x̂⁻(k)]
P(k) = [1 - K(k) H(k)] P⁻(k)
Noise covariances (empirically tuned):
Q = 1 × 10⁻⁵ (small: current sensor is accurate)
R = 0.01 (larger: OCV-SOC table has uncertainty near flat region)
APPENDIX D: BLE GATT SERVICE DEFINITION
Service: BMS Monitor Service
UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
Characteristics:
Cell Voltages
UUID: beb5483e-36e1-4688-b7f5-ea07361b26a8
Properties: READ | NOTIFY
Format: 4× IEEE-754 float32 LE (bytes 0–3: cell1, 4–7: cell2, 8–11: cell3, 12–15: cell4)
Unit: Volts
State of Charge (EKF)
UUID: beb5483e-36e1-4688-b7f5-ea07361b26a9
Properties: READ | NOTIFY
Format: float32 LE
Unit: Percent (0.0 – 100.0)
Current (Charge / Load)
UUID: beb5483e-36e1-4688-b7f5-ea07361b26aa
Properties: READ | NOTIFY
Format: 2× float32 LE (bytes 0–3: I_charge, 4–7: I_load)
Unit: Amperes
Temperature (Cell / FET)
UUID: beb5483e-36e1-4688-b7f5-ea07361b26ab
Properties: READ | NOTIFY
Format: 2× float32 LE (bytes 0–3: T_cell, 4–7: T_FET)
Unit: Celsius
Status Flags
UUID: beb5483e-36e1-4688-b7f5-ea07361b26ac
Properties: READ | NOTIFY
Format: uint8
Bits: 0=OV, 1=UV, 2=OC, 3=OT, 4=CHG_EN, 5=DSG_EN, 6=LVD, 7=spare
Efficiency
UUID: beb5483e-36e1-4688-b7f5-ea07361b26ad
Properties: READ | NOTIFY
Format: 2× float32 LE (bytes 0–3: coulombic_eff, 4–7: energy_eff)
Unit: Percent
APPENDIX E: FILE INDEX
/ant_gear/bms/
├── schematics/
│ ├── sch_lifepo4_4s_bms.txt BQ76920 4S LiFePO4 BMS, FET stage, calibration
│ ├── sch_liion_bms.txt BQ76930, S-8254, 3S/4S Li-Ion, cell matching
│ ├── sch_cell_balancing.txt Passive (R+FET), active (JK BMS), algorithm
│ ├── sch_protection_lvd.txt TL431 OV, LM393 UV/OC, SCD, LVD, pre-charge
│ └── sch_mppt_integration.txt Solar integration, charge arbitration, efficiency
├── firmware/
│ └── bms_monitor_esp32.ino CYD BMS monitor: BQ76920 driver, EKF SOC,
│ BLE GATT server, LVD, MPPT UART, web UI
├── openscad/
│ ├── enclosure_bms.scad Controller housing, 18650 holders, prismatic frame
│ └── mounting_brackets_bms.scad Panel mount, cell tray, mast clamp, DIN clip,
│ shunt block, NTC clip, terminal covers, handle
└── MANUAL_BMS.md This document (TM-BMS-001 Rev A)
TM-BMS-001 Rev A — End of Document
Portable Battery Management System — Field Reference for Amateur
Radio Operation
Downloads
- OpenSCAD Model — enclosure_bms.scad [SCAD]
- OpenSCAD Model — mounting_brackets_bms.scad [SCAD]
- Arduino Firmware — bms_monitor_esp32.ino [INO]
- Schematic — sch_cell_balancing.txt [TXT]
- Schematic — sch_lifepo4_4s_bms.txt [TXT]
- Schematic — sch_liion_bms.txt [TXT]
- Schematic — sch_mppt_integration.txt [TXT]
- Schematic — sch_protection_lvd.txt [TXT]