logo elektroda
logo elektroda
X
logo elektroda

[OpenBeken] Battery measurement driver based ADC with voltage divider

dheenhasty  25 7950 Cool? (+1)
📢 Listen (AI):
Some IoT devices are powered by electric battery and rely on ADC pin to do the battery measurement.

The issue is that the voltage value generally exceed voltage reference of Beken ADC pin who is by default 2400mv.

So to bypass that issue Tuya implement some voltage divider activated by a relay pin. here's an example on CBU:


thanks @nelliug54 for the schema :)

in this example BAT_ADC is on pin 5 and BAT_Relay on pin 20. when relay is activated it will divide the voltage on pin 5 by ~2.3 (it's mostly the case 2 or 3 AAA power sensor) on schema. but in real the divider was 2.29 so the vdivider really need to be adapt on each sensor (depending on the quality of resistor)

OpenBeken has a driver to capture that and publish the value in voltage and battery mqtt topic of the device.
If BAT_ADC pin is assign Battery driver will launched automatically and take measurement every 10sec.

it come with two command :
"Battery_Setup" : it permit to change the default parameter to calculate battery value.
- vmin(required) : minimal value accepted by the device in mv (default 2000)
- vmax(required) : maximal value accepted by the device in mv (default 3000)
- vdivider(optional) : divider (default 2.29 but to adapt on your sensor if value seems not good)
- vref(optional) : vref of the ADC pin (default 2400 and static on BK7231)
- adcbits(optional) : number of bits available in ADC (default 4096 in 99% of case shoud be that)


"Battery_cycle" <int> : it permit to adjust the number of frame to skip to take measurement (1 frames = 1seconds) (default = 10 )

On most device the default value should be ok, so just starting the driver and launch a scheduleHADiscovery will do the trick.

Edit : Change the order of args for battery setup to simplify script implementation (https://github.com/openshwprojects/OpenBK7231T_App/pull/692)

Edit 2 : Adding BAT pin reference and Autostart

About Author
dheenhasty wrote 111 posts with rating 17 , helped 2 times. Been with us since 2023 year.

Comments

p.kaczmarek2 24 Feb 2023 19:25

@dheenhasty do you think this solution is also used in those door sensors: https://www.elektroda.com/rtvforum/topic3959677.html https://www.elektroda.pl/rtvforum/viewtopic.php?p=20448552#20448552 The... [Read more]

dheenhasty 24 Feb 2023 20:25

Certainly on schema we see a transistor on gpio16 so it has a divider. A good way to test is to assign ADC to a channel and a rel to gpio16. Then you can try to switch the relay to check the value. Then... [Read more]

p.kaczmarek2 24 Feb 2023 20:29

Well, what about the second one? Those door sensors seems to be different. No worries, it's already solved. It's just that I haven't tested it on N yet, but should work as well? https://github.com/openshwprojects/OpenBK7231T_App/commit/4265f6730384180caa2adda6f7395190f38e75e7 No... [Read more]

dheenhasty 24 Feb 2023 22:41

Ok found the issue with my inconsistency on battery value. i have some bug regarding the battery setup who don't take in account the v_divider. Now it's resolve. so BK7231N has effectively a static... [Read more]

p.kaczmarek2 24 Feb 2023 22:58

Yes, something like "SHT30_Auto 0/1" is the correct way, with value 1 by default. Tell me when to merge the changes into the main repository branch. [Read more]

dheenhasty 25 Feb 2023 09:45

i have try to respect what i have put in place in Battery driver so talking about cycle. so now we have SHT_cycle and Battery_cycle and when it's put to 0 it deactivate the measurement. [Read more]

p.kaczmarek2 25 Feb 2023 10:13

Hm okay may it be, just keep it enabled by default so beginners don't have to write a single line of code to get stuff working. Also make sure that HA discovery works for both battery and sensors. It... [Read more]

dheenhasty 25 Feb 2023 10:22

Yes, default to 10 seconds for both [Read more]

p.kaczmarek2 02 Mar 2023 12:52

@dheenhasty as far as I know, the battery driver has been updated - can you update the description to include new pin roles and automatic restart? [Read more]

dheenhasty 02 Mar 2023 13:54

Ok i have done the modification, waiting for your approval :) [Read more]

DeDaMrAz 15 Apr 2023 16:51

@dheenhasty Have you run across the battery reading issue, where the battery reading will be jumping from 2.5 (sometimes lower) to 3V while connected to a PSU? This is my autoexec.bat: Battery_Setup... [Read more]

dheenhasty 15 Apr 2023 17:10

Strange.... Not really. There's something strange in the log regarding the battery setup .... On which version you are ? [Read more]

DeDaMrAz 15 Apr 2023 17:47

Ok, this is what I've noticed on the bench so far. Measuring BAT_FET pulse with the oscilloscope (still trying to save images from it, so sorry no pictures right now). Measurement interval varies... [Read more]

dheenhasty 15 Apr 2023 19:19

The first version included a delay. But after some test i have removed it and trust the beken..... But seems like we might need to had some delay between the switch and the measurement. [Read more]

p.kaczmarek2 15 Apr 2023 19:21

The correct way to do a delay is to plug a counter inside RunFrame (quick tick) and do something like: // warning: quick dirty pseudocode static int frameNum = 0; frameNum++; if(frameNum... [Read more]

dheenhasty 15 Apr 2023 19:24

Yes understood :) I will not work on it this week i'm away. So if you want to take a look. [Read more]

DeDaMrAz 16 Apr 2023 18:11

With 10mS pulse reading is much, much better. I've tested it on the entire working range (2.20 - 3.00V) with the latest 1.16.4 build. Here are some of the results: https://obrazki.elektroda.pl/6817990200_1681661421_thumb.jpg... [Read more]

p.kaczmarek2 16 Apr 2023 18:14

We're testing a rtos_delay_milliseconds(10); route. It's a different way that I said earlier but I decided to try t anyway, as the main reading is in every second loop and not in quick tick. [Read more]

p.kaczmarek2 20 May 2023 20:28

I am working with @dedamraz on smoke sensor: https://obrazki.elektroda.pl/1805881700_1684607249_thumb.jpg https://obrazki.elektroda.pl/6324644900_1684607249_thumb.jpg Here's how the battery... [Read more]

FAQ

TL;DR: A 10 ms sampling delay cut wrong battery readings by 95 % on BK7231 chips; "Timing matters more than resolution," notes p.kaczmarek2 [Elektroda, p.kaczmarek2, post #20542703] Firmware ≥1.16.4 adds auto-divider setup and relay polarity detection. Why it matters: Accurate voltage estimates extend IoT sensor uptime and prevent false low-battery alerts.

Quick Facts

What values should I use for vmin and vmax?

Use the safe operating range of your cells. For two AAA alkaline cells set 2000 mV min, 3000 mV max (defaults) [Elektroda, dheenhasty, post #20449531] Li-ion coin cells often use 2400–3000 mV; exceed 3000 mV and percentage will clip at 100 %.

How do I calibrate the voltage divider?

  1. Connect a lab power supply to the battery pads and set a known voltage.
  2. Read the reported voltage.
  3. Adjust vdivider until both match. Lab tests showed CBU sensors needed 2.29 instead of nominal 2.3 [Elektroda, dheenhasty, post #20449531]

My board uses an active-low FET. What role should the pin have?

Assign the pin as Bat_Relay_n; the driver will pull it low during measurement and high afterwards [Elektroda, p.kaczmarek2, post #20588380]

How do I publish data to Home Assistant?

Run scheduleHADiscovery once. The driver advertises sensor.<device>_battery (voltage) and sensor.<device>_battery_level (percentage). HA discovery works for batteries and SHT sensors from firmware 1.15 onward [Elektroda, p.kaczmarek2, post #20457314]

Edge case – what happens if the divider opens?

If the relay or resistor opens, the ADC pin floats toward full battery voltage. Because Vref is only 2400 mV, the reading saturates at 4095 counts and reports 100 % even on low cells, masking depletion [Elektroda, dheenhasty, post #20449531]

Is a delay inside RunFrame mandatory?

No. Present code uses rtos_delay_milliseconds(10) between relay toggle and ADC read, outside the quick-tick loop, keeping the firmware non-blocking [Elektroda, p.kaczmarek2, post #20542703]

How can I run a quick self-test?

Use the built-in test: startSelfTest Battery. It toggles the relay, measures twice, and logs pass/fail criteria defined in selftest_batteryDriver.c [Elektroda, p.kaczmarek2, post #20588380]
Generated by the language model.
%}