logo elektroda
logo elektroda
X
logo elektroda

[OpenBeken] Battery measurement driver based ADC with voltage divider

dheenhasty 7422 25
ADVERTISEMENT
📢 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:

    [OpenBeken] Battery measurement driver based ADC with voltage divider
    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

    Cool? Ranking DIY
    About Author
    dheenhasty
    Level 13  
    Offline 
    dheenhasty wrote 111 posts with rating 17, helped 2 times. Been with us since 2023 year.
  • ADVERTISEMENT
  • #2 20456638
    p.kaczmarek2
    Moderator Smart Home
    @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/topic3914412-30.html#20448552
    The second one linked seems to have schematic drawn:
    Spoiler:

    [OpenBeken] Battery measurement driver based ADC with voltage divider

    [url=https://obrazki.elektroda.pl/6586709700_1676894176.jpg][OpenBeken] Battery measurement driver based ADC with voltage divider
    Helpful post? Buy me a coffee.
  • #3 20456737
    dheenhasty
    Level 13  
    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 need to check the vref should be 2400 (based on beken documentation) but on cbu seems like it's more 2900....

    For the door detection, i will got with the pindeepsleep, but they will have a 30sec delay for detection..... Depending of the usecase it can be troublesome
  • ADVERTISEMENT
  • Helpful post
    #4 20456750
    p.kaczmarek2
    Moderator Smart Home
    Well, what about the second one? Those door sensors seems to be different.

    dheenhasty wrote:

    For the door detection, i will got with the pindeepsleep, but they will have a 30sec delay for detection..... Depending of the usecase it can be troublesome

    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/OpenBK7231...mmit/4265f6730384180caa2adda6f7395190f38e75e7
    No commands required.

    One important change that I had to do is to add dInput (and similar) pin handling to pin deep sleep, so it checks the current input state and wakes on transition to separate state.
    [OpenBeken] Battery measurement driver based ADC with voltage divider
    Here is my test setup (the old-school switch, which is older than me, is acting like a door sensors):
    [OpenBeken] Battery measurement driver based ADC with voltage divider
    Measurements:
    [OpenBeken] Battery measurement driver based ADC with voltage divider
    I will be posting guide in separate topic soon.
    Helpful post? Buy me a coffee.
  • #5 20456967
    dheenhasty
    Level 13  
    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 vref of 2400 (should be the same for the T .....)

    but the v_divider of the Generic Temperature sensor is 2.29 (due to some bad quality resistor i think....)

    i have push a merge with correction for that and correction for the SHT (to activate runframe)
  • #6 20456988
    p.kaczmarek2
    Moderator Smart Home
    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.
    Helpful post? Buy me a coffee.
  • #7 20457285
    dheenhasty
    Level 13  
    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.
  • #8 20457314
    p.kaczmarek2
    Moderator Smart Home
    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 works for my door sensors as well, right now.
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #9 20457323
    dheenhasty
    Level 13  
    Yes, default to 10 seconds for both
  • #10 20466008
    p.kaczmarek2
    Moderator Smart Home
    @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?
    Helpful post? Buy me a coffee.
  • #11 20466096
    dheenhasty
    Level 13  
    Ok i have done the modification, waiting for your approval :)
  • #12 20540936
    DeDaMrAz
    Level 21  
    @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 2000 3000 1.87 2400 4096
    Battery_cycle 20


    but this is what I got from my log upon boot:

    Info:CMD:CMD_StartScript: started autoexec.bat at the beginning
    Info:MAIN:Main_Init_After_Delay done
    Info:CMD:Battery Setup : Min 2130706432 Max 0 Vref 1084178432 adcbits 0 vdivider 1084715008
    Info:CMD:Battery Cycle : Measurement will run every 20 seconds
    Info:MAIN:Time 1, idle 278595/s, free 73512, MQTT 0(0), bWifi 0, secondsWithNoPing -1, socks 2/38 
    Info:DRV:DRV_BATTERY : Measure Battery volt en perc
    Info:GEN:CHANNEL_Set channel 0 has changed to 1 (flags 0)
  • #13 20540956
    dheenhasty
    Level 13  
    Strange.... Not really.

    There's something strange in the log regarding the battery setup .... On which version you are ?
  • #14 20541009
    DeDaMrAz
    Level 21  
    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 wildly from 1.35 to 11.1mS.
    Anything below 5ms is the wrong measurement and everything above that is valid and reassembles the input from my PSU.

    Is that time something that is configured in the driver or?

    EDIT:

    Tested on the latest fix 1.16.1

    EDIT 2: pictures added

    First two measurements (shorter pulse) are low, 72% and 76%, second two (>5ms pulse) are correct 96 and 99% respectively

    [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider
  • ADVERTISEMENT
  • #15 20541125
    dheenhasty
    Level 13  
    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.
  • #16 20541128
    p.kaczmarek2
    Moderator Smart Home
    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 == 2) {
      closeRelay();
    }
    if(frameNum == 10) {
      doADCMeasure();
    }
    if(frameNum == 12) {
     openRelay();
    }
    if(frameNum>30)
    frameNum=0; // loop
    

    the quick tick is supposed to be non-blocking, so please don't rtos_delay_microseconds there.
    Helpful post? Buy me a coffee.
  • #17 20541130
    dheenhasty
    Level 13  
    Yes understood :)

    I will not work on it this week i'm away. So if you want to take a look.
  • #18 20542697
    DeDaMrAz
    Level 21  
    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:

    [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider

    More testing is needed of course, but so far it looks promising. Pulse is floating around 10mS (in my case +/-0.5mS) but the reading is perfect.
  • #19 20542703
    p.kaczmarek2
    Moderator Smart Home
    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.
    Helpful post? Buy me a coffee.
  • #20 20588380
    p.kaczmarek2
    Moderator Smart Home
    I am working with @DeDaMrAz on smoke sensor:
    [OpenBeken] Battery measurement driver based ADC with voltage divider [OpenBeken] Battery measurement driver based ADC with voltage divider
    Here's how the battery measurement is done there:
    [OpenBeken] Battery measurement driver based ADC with voltage divider
    I had to introduce Bat_Relay_n for this purpose, because here, to do measurement, the P26 has to be low, so R7 and R8 form a voltage divider (divides voltage by two).

    So basically it works like it:
    - P26 is high by default
    - at measurement time, P26 is low, so battery divider works, current flows
    - after measurement P26 is high again

    I also introduced battery driver self test:
    https://github.com/openshwprojects/OpenBK7231...4ccb311/src/selftest/selftest_batteryDriver.c
    Helpful post? Buy me a coffee.
  • #21 21808566
    protectivedad
    Level 9  
    I've posted a pull request that enhances and fixes a few issues with the battery driver. Any testing and opinions are appreciated.

    What I initially wanted to do was, after setting my battery setup, take and post one "good" reading and stop reading the values. The problems I was having are that the command battery_cycle 0 would not stop the reading/cycles it would make them happen every 1 second. For my CBU device with a battery relay the first value was always garbage (~600 mV) which gets read and potentially posted. I was also confused that the battery module page asked for a channel number, but the channel no matter what I put never showed anything but 0.00. I know now that it was never used in the driver.

    The changes I've made:
    1) values less then a half of the minimum voltage are ignored;
    2) battery_cycle 0 stops the cycles after one reading that isn't ignored;
    3) instead of rereading pin assignments every cycle it now does it in the init;
    4) on init for devices with a relay it will take an initial reading without a pause;
    5) the driver doesn't use channels so it no longer ask for one on the module page.

    The number 1 enhancement might not be needed for me anymore because number 4 stops a bad reading from ever happening. It might be useful so I figured I'd leave it it.

    EDIT:
    6) post to queue if MQTT is not connected.
  • #22 21808624
    divadiow
    Level 37  
    protectivedad wrote:
    the driver doesn't use channels so it no longer ask for one on the module page


    yikes, never knew the battery driver didn't even need the channels!
  • #23 21808747
    p.kaczmarek2
    Moderator Smart Home
    Not bad, but this confuses me:
    protectivedad wrote:

    3) instead of rereading pin assignments every cycle it now does it in the init;

    So if I am looking for pins/experimenting, then now I have to restart driver with each change?
    Helpful post? Buy me a coffee.
  • #24 21808826
    protectivedad
    Level 9  
    p.kaczmarek2 wrote:
    So if I am looking for pins/experimenting, then now I have to restart driver with each change?

    The short answer is yes. I selected the approach that optimizes for "normal" use case, not the special "testing" use case. It's a personal thing. I find all the wasted MCU cycles doing something that a person only wants to do less then 1% of the time, well a waste. I picture hundreds/thousands of devices doing unneeded work draining batteries, eating power. It probably all ads up to almost nothing :), but for some reason I find it unnecessary.

    Or maybe an obkconfig flag to allow for optimized "normal" compile for and "testing" compile. This could then be used to trigger the same logic in other drivers.
    Or have the module screen unload and load a driver on pin change if already loaded. Will it unload a driver when it is deselected?

    Hopefully, we can have good automated systems (the GUI flash tool is great) that select the correct pin values and testing is not necessary.

    That said if people say they need the functionality, it is easy for me to add (I separated out the pin assignment logic).

    Let me know.
  • #25 21808943
    max4elektroda
    Level 23  
    I like the idea of getting the pin once on start, in fact most users won't change them during operation.
    Regarding the change of pins, what about a combined approach? Check if pin is still assigned the role and only if not start the searching loop again.
    But of course while saving some cycles almost every time it will cost some code/memory.
  • #26 21808992
    protectivedad
    Level 9  
    max4elektroda wrote:
    Regarding the change of pins, what about a combined approach? Check if pin is still assigned the role and only if not start the searching loop again.

    I never though of that, I like it. I just dislike looping through a 95% unused array to find the real values over and over but this works.

    EDIT:
    After looking at it there is a problem with the "optional" bat_relay and bat_relay_n pins. Is it sufficient just to check the bat_adc pin and reassign everything based on that changing? What if you change from bat_relay to bat_relay_n but no change to bat_adc?
📢 Listen (AI):

Topic summary

The discussion revolves around the implementation of a battery measurement driver using an ADC pin in IoT devices powered by batteries. The primary challenge is that the voltage often exceeds the Beken ADC's reference voltage of 2400mV. To address this, a voltage divider activated by a relay pin is utilized, as demonstrated in a schematic shared by a user. The OpenBeken driver captures the divided voltage and publishes it via MQTT every 10 seconds. Various users discuss testing methods, issues with battery value inconsistencies, and improvements to the driver, including the introduction of a self-test feature for the battery driver. Adjustments to the measurement cycle and handling of GPIO pins are also highlighted to enhance performance and reliability.
Summary generated by the language model.
ADVERTISEMENT