Elektroda.com
Elektroda.com
X

[OpenBeken] Battery measurement driver based ADC with voltage divider

dheenhasty 2610 19
  • 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 16, helped 2 times. Been with us since 2023 year.
  • #2
    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/viewtopic.php?p=20448552#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
  • #3
    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
  • Helpful post
    #4
    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/OpenBK7231T_App/commit/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.
  • #5
    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
    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.
  • #7
    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
    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.
  • #9
    dheenhasty
    Level 13  
    Yes, default to 10 seconds for both
  • #10
    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?
  • #11
    dheenhasty
    Level 13  
    Ok i have done the modification, waiting for your approval :)
  • #12
    DeDaMrAz
    Level 13  
    @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
    dheenhasty
    Level 13  
    Strange.... Not really.

    There's something strange in the log regarding the battery setup .... On which version you are ?
  • #14
    DeDaMrAz
    Level 13  
    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
  • #15
    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
    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.
  • #17
    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
    DeDaMrAz
    Level 13  
    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
    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.
  • #20
    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/OpenBK7231T_App/blob/808f65c8ad6f2c1e308ab402e99e5b0f04ccb311/src/selftest/selftest_batteryDriver.c