logo elektroda
logo elektroda
X
logo elektroda

BK7231N Battery Voltage Reading Unstable: SAR-ADC Sensitivity, RF Noise, Firmware Delay Fix

User question

Why is battery voltage measurement in BK7231N unstable?

Artificial Intelligence Response

Direct answer to the question

– On BK7231N the battery-voltage reading is usually “unstable” because the SoC’s SAR-ADC is very sensitive to source impedance, supply-rail dips produced by the on-board Wi-Fi radio, and a small firmware timing erratum: the first conversion taken within ~1 ms of enabling the ADC almost always returns a wrong value.
– The instability disappears when you
• use a low-impedance, RC-filtered divider close to the pin,
• sample while the RF is idle and/or average several samples,
• wait ≈1000 µs after calling the ADC-initialisation routine (OpenBeken / BK SDK) and
• calibrate the divider with the Battery_Setup (or equivalent) command.

Detailed problem analysis

  1. Signal-conditioning chain
    • High-value dividers (> 500 kΩ total) + no shunt capacitor ⇒ input node impedance >> ADC sampling capacitor (≈50 pF) ⇒ charge gets stolen during sampling, giving jitter of tens of LSBs.
    • Fix: Rtotal 100 k–470 k Ω, add 47–220 nF from pin to ground –3 dB around a few hundred Hz (fast enough for battery, slow enough for RF noise).

  2. ADC reference & supply-rail dynamics
    • BK7231N uses an internal 2.4 V band-gap reference, but conversions are still affected when VDD droops; the RF TX burst can pull 200–300 mA and cause > 60 mV sag on a thin trace, modulating the ADC front-end.
    • Brown-out occurs at ~3.19 V (measured by users), so any dip near this will truncate conversions.
    • Fix: ≥10 µF + 100 nF right at VDD_RF/VDD_DIG pins, short return to battery, star-ground.

  3. Firmware-specific issues (current community findings)
    • GitHub issue #5201 (ESPhome) and OpenBK issue #1000: first reading after adc_open() is often stuck at 2.048 V; root cause traced to internal settling. Empirically solved by delaying 1000 µs or discarding first sample.
    Pseudocode:

     adc_open(ch); // enable channel
    rtos_delay_us(1000); // allow internal buffer to settle
    discard = adc_read(); // throw away
    sum = 0; for(i=0;i<16;i++){ sum += adc_read(); }
    volts = adc_calibrate(sum/16); 

    • OpenBeken ≥1.18 exposes Battery_Setup min max dividerRatio to linearise and %-scale readings.

  4. Genuine battery behaviour
    • Li-ion/Li-Po cells show ESR-related sag; what looks like “noise” can be real 80–150 mV drops during Wi-Fi beacons. Decide whether you want open-circuit (OCV) or under-load voltage; sample during idle if OCV is required.

  5. PCB layout influences
    • Keep divider & C <1 cm from pin; guard-ring or solid pour, route away from antenna and DC/DC switcher; single-point ground to minimise ground-lift.

  6. Software filtering
    • Simple moving-average (8–32 samples) or median-of-N; Kalman unnecessary.
    • Report only every few seconds with Battery_cycle to reduce RF-induced aliasing.

Current information and trends

– Community firmware (OpenBeken 1.18+, tasmota-bk) already integrates a 1 ms delay + optional multi-sample averaging patch.
– Several open-hardware designs switching to a dedicated 1.2 V reference (REF3330 + op-amp buffer) when precise SoC-side fuel-gauging is needed.
– Upcoming Beken SDK (road-map Q3-2024) exposes SARADC “settling time” register, allowing firmware to reduce the 1 ms workaround.

Supporting explanations and details

Analogy: think of the ADC input as a water glass (50 pF capacitor) that must be filled from a thin straw (your high-value divider). If you open the tap only briefly (2 µs sampling window) the glass level will depend on how fast water can flow; adding a reservoir (capacitor) at the straw’s end makes sure enough water is already there.

Noise model:
\[ V{error} = \frac{Q}{C{sample}} = \frac{V{in}\,C{in}}{C{sample}} \]
With \(C
{in}=50 \text{pF}, C_{sample}=5 \text{pF}\) an impedance of 1 MΩ causes >1 LSB variation for T_s<2 µs.

Ethical and legal aspects

– Incorrect battery estimation can lead to over-discharge of Li-ion packs, creating fire risk; follow IEC 62133-2 limits and cut off below 2.8 V cell voltage.
– CE/FCC compliance: avoid RF emissions leaking into analog lines; maintain PCB shielding guidelines.

Practical guidelines

  1. Hardware
    • Divider 220 k / 100 k (ratio 3.2 : 1) + 100 nF, placed next to pin.
    • 10 µF + 0.1 µF on VDD; optional ferrite bead between digital 3V3 and analog island.
  2. Firmware
    • Add 1 ms delay after adc_open.
    • Discard first sample, average ≥16, or median-of-5.
    • Schedule sampling in bk_pause_rf() window or after beacon.
    • Calibrate once per device: Battery_Setup 3000 4200 3.20.
  3. Validation
    • Feed a precision 3.000 V reference through the divider, log 100 readings; σ should be <2 mV.

Possible disclaimers or additional notes

– Values above assume default 12-bit ADC; if SDK sets 10-bit, expect ±3 mV/LSB.
– Internal reference (+/-2 %) varies with temperature; high-accuracy designs still need external VREF.

Suggestions for further research

– Characterise ADC INL/DNL over temperature; publish a correction LUT.
– Evaluate oversampling + decimation to obtain 14-bit effective resolution.
– Explore dual-range measurement (MOSFET-switched divider) for 1-cell vs 2-cell packs.

Brief summary

The BK7231N’s battery-voltage “instability” is a compound effect of high divider impedance, RF-induced supply dips, an internal ADC-settling quirk, and lack of filtering/averaging. A 100 nF-filtered 100–300 kΩ divider, solid decoupling, 1 ms firmware delay with sample discard, and proper calibration reliably reduce the spread to a few millivolts, giving repeatable battery readings without excessive current drain.

Ask additional question

Wait...(2min)
Disclaimer: The responses provided by artificial intelligence (language model) may be inaccurate and misleading. Elektroda is not responsible for the accuracy, reliability, or completeness of the presented information. All responses should be verified by the user.