logo elektroda
logo elektroda
X
logo elektroda

OpenESP32-C3 Bluetooth testing for OpenBeken as BT Coordinator

DeDaMrAz 1221 32
Best answers

Can OpenBeken be turned into a Bluetooth proxy/coordinator on ESP32-C3 or similar devices, and what is the practical implementation path?

Yes, but the workable result in this thread is a scan-only Bluetooth proxy, not a full coordinator with active connections. The implementation was ported to OpenBK7231T as a BT proxy with passive and active scan support, exposed through `BLEScan` and `BLEScanMode`, and the BT scan API was extended with an `active` flag in `scan_param` so `GAPM_SCAN_PROP_ACTIVE_1M_BIT` can be enabled when needed [#21850611][#21849822] Advertisement forwarding was changed to send data to Home Assistant almost immediately using a non-blocking socket plus a short delay, instead of batching 10 ads every 40 seconds, which reduced drops and improved visibility of devices [#21849822][#21847558] The working initialization flow became `BTInit` → `BTSetWindowInterval [window] [interval]` → `BTSetScanMode [isActive]` → `BTStartScan` → `startDriver ESPHomeAPI`, and the proxy can expose itself to HA when BTInit is used [#21852129] ESP support was disabled for now because it needs more rewriting, while the proxy was enabled by default on RTL8720D and in btproxy variants on RTL87X0C, BK7238, and BK7231N_ALT [#21850947] Later testing showed BK7238 and LN882H can receive coded-channel advertisements, while RTL8720C/D cannot; the code also bypassed nanopb and mapped PSRAM into heap when present to handle larger advertisements [#21857230]
Generated by the language model.
ADVERTISEMENT
  • #1 21846290
    DeDaMrAz
    Level 22  
    Info:MAIN:Rebooting...
    Info:I (36704) wifi:flush txq
    I (36704) wifi:stop sw txq
    I (36714) wifi:lmac stop hw txq
    MAIN:Main_OnWiFiStatusChange - WIFI_STA_DISCONNECTED - 2
    Info:MAIN:WiFi Disconnected
    ESP-ROM:esp32c3-api1-20210207
    Build:Feb  7 2021
    rst:0xc (RTC_SW_CPU_RST),boot:0xd (SPI_FAST_FLASH_BOOT)
    Saved PC:0x403874d6
    SPIWP:0xee
    mode:DIO, clock div:1
    load:0x3fcd5820,len:0x15c4
    load:0x403cbf10,len:0xc84
    load:0x403ce710,len:0x2fd0
    entry 0x403cbf1a
    I (15) boot: ESP-IDF v5.5.2 2nd stage bootloader
    I (15) boot: compile time Feb 23 2026 02:46:51
    I (16) boot: chip revision: v0.4
    I (16) boot: efuse block revision: v1.3
    I (19) boot.esp32c3: SPI Speed      : 80MHz
    I (23) boot.esp32c3: SPI Mode       : DIO
    I (27) boot.esp32c3: SPI Flash Size : 4MB
    I (30) boot: Enabling RNG early entropy source...
    I (35) boot: Partition Table:
    I (38) boot: ## Label            Usage          Type ST Offset   Length
    I (44) boot:  0 otadata          OTA data         01 00 00009000 00002000
    I (50) boot:  1 nvs              WiFi data        01 02 0000b000 00005000
    I (57) boot:  2 app0             OTA app          00 10 00010000 000f0000
    I (63) boot:  3 app1             OTA app          00 11 00100000 000f0000
    I (70) boot:  4 lfs              Unknown data     01 82 001f0000 00010000
    I (76) boot: End of partition table
    I (80) esp_image: segment 0: paddr=00100020 vaddr=3c0a0020 size=24a54h (150100) map
    I (111) esp_image: segment 1: paddr=00124a7c vaddr=3fc94a00 size=03570h ( 13680) load
    I (114) esp_image: segment 2: paddr=00127ff4 vaddr=40380000 size=08024h ( 32804) load
    I (121) esp_image: segment 3: paddr=00130020 vaddr=42000020 size=961f4h (614900) map
    I (220) esp_image: segment 4: paddr=001c621c vaddr=40388024 size=0c89ch ( 51356) load
    I (230) esp_image: segment 5: paddr=001d2ac0 vaddr=50000000 size=00034h (    52) load
    I (237) boot: Loaded app from partition at offset 0x100000
    I (237) boot: Disabling RNG early entropy source...
    I (248) cpu_start: Unicore app
    I (256) cpu_start: GPIO 20 and 21 are used as console UART I/O pins
    I (256) cpu_start: Pro cpu start user code
    I (256) cpu_start: cpu freq: 160000000 Hz
    I (258) app_init: Application information:
    I (262) app_init: Project name:     OpenBeken
    I (266) app_init: App version:      dev_20260223_025831
    I (271) app_init: Compile time:     Feb 23 2026 02:58:50
    I (276) app_init: ELF file SHA256:  2fa82e7b6...
    I (281) app_init: ESP-IDF:          v5.5.2
    I (284) efuse_init: Min chip rev:     v0.3
    I (288) efuse_init: Max chip rev:     v1.99 
    I (292) efuse_init: Chip rev:         v0.4
    I (296) heap_init: Initializing. RAM available for dynamic allocation:
    I (302) heap_init: At 3FCA1530 len 0001EAD0 (122 KiB): RAM
    I (307) heap_init: At 3FCC0000 len 0001C710 (113 KiB): Retention RAM
    I (314) heap_init: At 3FCDC710 len 00002950 (10 KiB): Retention RAM
    I (320) heap_init: At 50000034 len 00001FB4 (7 KiB): RTCRAM
    I (325) spi_flash: detected chip: generic
    I (329) spi_flash: flash io: dio
    I (332) sleep_gpio: Configure to isolate all GPIO pins in sleep state
    I (338) sleep_gpio: Enable automatic switching of GPIO sleep configuration
    I (356) pm: Frequency switching config: CPU_MAX: 160, APB_MAX: 80, APB_MIN: 40, Light sleep: DISABLED
    I (356) main_task: Started on CPU0
    I (356) main_task: Calling app_main()
    I (356) temperature_sensor: Range [-10°C ~ 80°C], error < 1°C
    BT proxy: ESP-IDF phase1 stub active
    Entering initLog()...
    Commands registered!
    initLog() done!


    Super early tests but I want to test if this is feasible at all an implement it as a BT proxy that can be enabled with a flag for testing proposes. If all the test pass I'll look into adding it to other platforms but since ESP gave me most problems before I am starting with the "biggest" fish first 😁 will update this once some progress is made, stay tuned.

    Added after 2 [hours] 31 [minutes]:

    Browser screenshot showing JSON data with Bluetooth scan results

    Some progress but with a lot of struggle... not sure it is worth it but I'll explore more....

    Added after 33 [minutes]:

    Screenshot of OpenESP32C3_test status page with system info and buttons: Config, Restart, Launch Web Application, About

    Added after 3 [minutes]:

    ESPHome screenshot showing the OpenBeken device page with device info and empty panels.

    Info:MAIN:Time 65, idle 209/s, free 82912, MQTT 0(4), bWifi 1, secondsWithNoPing -1, socks 0/0 
    Info:MAIN:Time 66, idle 216/s, free 83040, MQTT 0(4), bWifi 1, secondsWithNoPing -1, socks 0/0 
    Info:MAIN:Time 67, idle 216/s, free 82224, MQTT 0(4), bWifi 1, secondsWithNoPing 1, socks 0/0 
    Info:NTP:Seconds since Jan 1 1900 = 3980817267
    Info:NTP:Unix time  : 1771828467 - local Time 2026-02-23 06:34:27
    Info:MAIN:Time 68, idle 218/s, free 82868, MQTT 0(4), bWifi 1, secondsWithNoPing 2, socks 0/0 
    Info:MAIN:Time 69, idle 211/s, free 82868, MQTT 0(4), bWifi 1, secondsWithNoPing 3, socks 0/0 
    Info:DRV:BTProxy: Received API Msg 5 (Len: 0)
    Info:DRV:BTProxy: Handshake -> DisconnectRequest
    Info:DRV:BTProxy: Client disconnected or error
    Info:DRV:BTProxy: Client connected (sock 57)
    Info:DRV:BTProxy: Received API Msg 1 (Len: 29)
    Info:DRV:BTProxy: Handshake -> HelloRequest
    Info:DRV:BTProxy: Received API Msg 3 (Len: 0)
    Info:DRV:BTProxy: Handshake -> ConnectRequest
    Info:DRV:BTProxy: Received API Msg 9 (Len: 0)
    Info:DRV:BTProxy: Handshake -> DeviceInfoRequest
    Info:DRV:BTProxy: Received API Msg 11 (Len: 0)
    Info:DRV:BTProxy: Handshake -> ListEntitiesRequest (Sending Done)
    Info:DRV:BTProxy: Received API Msg 20 (Len: 0)
    Info:DRV:BTProxy: Received API Msg 34 (Len: 0)
    Info:DRV:BTProxy: Received API Msg 38 (Len: 0)
    Info:MAIN:Time 70, idle 231/s, free 83036, MQTT 0(4), bWifi 1, secondsWithNoPing 4, socks 0/0 
    Info:MAIN:Time 71, idle 200/s, free 83036, MQTT 0(4), bWifi 1, secondsWithNoPing 5, socks 0/0 
    Info:MAIN:Time 72, idle 209/s, free 83036, MQTT 0(4), bWifi 1, secondsWithNoPing 6, socks 0/0 
    Info:MQTT:mqtt_host empty, not starting mqtt
    Info:MAIN:Time 73, idle 212/s, free 83036, MQTT 0(5), bWifi 1, secondsWithNoPing 7, socks 0/0 
    Info:MAIN:Time 74, idle 219/s, free 82864, MQTT 0(5), bWifi 1, secondsWithNoPing 8, socks 0/0 
    Info:MAIN:Time 75, idle 217/s, free 70720, MQTT 0(5), bWifi 1, secondsWithNoPing 9, socks 0/0


    Weird mashup....

    Added after 1 [hours]:


    Bluetooth network graph: OpenBeken BT Proxy linked to Home Assistant and node “BT Proxy 1”

    Proof of concept is working...


    Since I've been digging through Bluetooth entire night and made this proof of concept work I came to the conclusion that it is a lot of work for somewhat little benefit. Every platform has it's own BT API so no one BTProxy driver is strictly plausible and binaries required are often large so that will most likely exclude 2Mb platforms (not tested - just a guess).

    Overall - not impossible but problematic and cost to benefit ratio is significant so I am going to stop this experiment here unless there is a viable usage case and a need for such a driver. The current device will remain as a test in my setup just to collect data and observe overall stability and behavior.

    Added after 21 [minutes]:

    If anybody is interested in playing around and experimenting more I am attaching latest build I made for ESP32-C3 module
    Attachments:
    • OpenESP32C3_BT_test_17.factory.bin (1.35 MB) You must be logged in to download this attachment.
  • ADVERTISEMENT
  • #2 21846584
    insmod
    Level 31  
    This is much more complex than what i've thought of doing.
    But this is better.
    Are you using NimBLE or bluedroid?
  • #3 21846587
    DeDaMrAz
    Level 22  
    bluedroid as ESPHome was the base and easiest to implement.

    my initial idea was to "restore" BT proxy option to the zigbee gateway with RTL8720D but I started by what I had on the table atm - EPS32-C3.... most issues stem from the different IDF versions and support for BT 4.2 vs BT5 and BLE.... on top of that I had a bug in the docker local build tool so I spent a good amount of time figuring that out - turns out it was my error all along in parsing the partitions.csv.... not proud of that.

    As soon as I find my 8720 dev board I'll try to port it to RTL.
  • #4 21846591
    insmod
    Level 31  
    Can you push it into some branch on github?
  • #7 21847063
    DeDaMrAz
    Level 22  
    Nice, same ESP route? I see you have mac "problem" that I came across on the first go :D


    Screenshot showing a device list: “ESPHome”, OpenBeken BT Proxy firmware, and a MAC address.

    And what is your coexistence ratio? I used 40 for WiFi and 60 for BT
  • ADVERTISEMENT
  • Helpful post
    #8 21847064
    insmod
    Level 31  
    Nope, fixed it first thing

    Dark UI showing Device info for RTL8720D with firmware and MAC, plus Controls and Connected devices sections

    Added after 2 [minutes]:

    Not configurable (i think?) It's enabled just via bt_coex_init and wifi_btcoex_set_bt_on.
    Or are you talking about window/interval?
  • ADVERTISEMENT
  • #10 21847067
    insmod
    Level 31  
    I'm currently building without berry, at 1053kb. It was about 1157 with it. Still more than enough free space.
  • #11 21847075
    DeDaMrAz
    Level 22  
    Nice so we got a working "solution" basically, did you look at the docker local build in my fork, it helps speed up the process a ton! Maybe you can add TCPuart and BTProxy to the RTL and test that gateway 😎

    I am still to find time for that....
  • #13 21847084
    DeDaMrAz
    Level 22  
    insmod wrote:
    Seems to miss most advertisements once wifi is connected.


    this

    DeDaMrAz wrote:
    And what is your coexistence ratio? I used 40 for WiFi and 60 for BT


    had that issue on ESP, play around with that ratio
  • #14 21847085
    insmod
    Level 31  
    >>21847084
    Tried, and eventually reverted to default sdk default.
  • #15 21847088
    DeDaMrAz
    Level 22  
    I started ariston driver writing and tests, once finished I'll get back to this for sure.

    You can play with scan timing as well, that helped me on ESP home....
  • #16 21847558
    insmod
    Level 31  
    After some time online it started to catch a LOT of advertisements. So much, that most of them are dropped. I'm not even sure if they're valid. 157k total after 2.5 hours uptime.
    {
      "init": 1,
      "scan": 1,
      "total": 157695,
      "dropped": 155560,
      "buffered": 32,
      "entries": [
        {
          "mac": "18:7b:a5:db:28:3d",
          "rssi": -72,
          "adv_len": 31,
          "evt_type": 3,
          "age_ms": 50
        },
        {
          "mac": "e5:3c:11:d3:69:11",
          "rssi": -86,
          "adv_len": 31,
          "evt_type": 3,
          "age_ms": 75
        },
        {
          "mac": "e6:be:83:a0:ca:4a",
          "rssi": -82,
          "adv_len": 0,
          "evt_type": 4,
          "age_ms": 75
        },
        {
          "mac": "e6:be:83:a0:ca:4a",
          "rssi": -82,
          "adv_len": 17,
          "evt_type": 0,
          "age_ms": 75
        },
        {
          "mac": "18:7b:a5:db:28:3d",
          "rssi": -72,
          "adv_len": 31,
          "evt_type": 3,
          "age_ms": 150
        },
        {
          "mac": "e5:3c:11:d3:69:11",
          "rssi": -86,
          "adv_len": 31,
          "evt_type": 3,
          "age_ms": 175
        },
        {
          "mac": "18:7b:a5:db:28:3d",
          "rssi": -72,
          "adv_len": 31,
          "evt_type": 3,
          "age_ms": 275
        },
        {
          "mac": "e5:3c:11:d3:69:11",
          "rssi": -86,
          "adv_len": 31,
          "evt_type": 3,
          "age_ms": 275
        },
        {
          "mac": "e6:be:83:a0:ca:4a",
          "rssi": -84,
          "adv_len": 0,
          "evt_type": 4,
          "age_ms": 350
        },
        {
          "mac": "e6:be:83:a0:ca:4a",
          "rssi": -84,
          "adv_len": 17,
          "evt_type": 0,
          "age_ms": 350
        }
      ]
    }

    In log i see a lot of
    hciuart_irq: LSR 00000063 interrupt
    hciuart_irq: LSR over run interrupt
    

    (during ota, and once during normal operation)

    Disabling duplicates helped, but sending advs to HA is done once every 40 seconds.
    I've bumped ringbuffer limit to 256 and send all advs instead of just ten, see more advs in HA (including my bthome sensor), but a lot of them are still dropped.

    And with a simple dedup in callback, none are dropped.
  • #17 21849725
    insmod
    Level 31  
    @DeDaMrAz
    I've got 2 days uptime for RTL8720D with no problems.
    Do you think it should be cleaned up and pushed to main branch?
    I think without ESP for now, and scan only, without active connections.
  • #18 21849730
    DeDaMrAz
    Level 22  
    I got my running for 3 days but haven't paid attention to the dropped packets, so no idea but I vote for the push that way we get more eyes on it and better feedback.

    I will revisit ESP BT on another chip maybe as I have finished the Ariston saga just today... maybe even use it as a coordinator for zigbee just for fun
  • Helpful post
    #19 21849822
    insmod
    Level 31  
    https://github.com/openshwprojects/OpenBK7231T_App/pull/2003
    RTL8720D - scan only, no active connections.

    Main change to original code - advertisements are sent almost immediately (non-blocking socket + 100ms delay), instead of 10 per ping from HA (40 sec).

    Added turning on/off active scan, turn on/off scan, setting window/interval.
    Disabled on ESP for now.
  • #21 21849838
    insmod
    Level 31  
    Works on RTL C, almost no changes were required. Disabled by default, ir and berry must be disabled to enable it (not enough flash otherwise).
  • ADVERTISEMENT
  • #24 21850611
    DeDaMrAz
    Level 22  
    It looks like it was never "finished" but it's in the app_ble.c just never used, as the passive scan is hardcoded - and that active comment sent me for a wild spin...

    ble_err_t app_ble_start_scaning(uint8_t actv_idx, uint16_t scan_intv, uint16_t scan_wd)
    {
       ble_err_t ret = ERR_SUCCESS;
    
       BLE_APP_CHECK_ACTVS_IDX(actv_idx);
    
       if (app_ble_actv_state_get(actv_idx) == ACTV_SCAN_CREATED) {
          // Prepare the GAPM_ACTIVITY_START_CMD message
          struct gapm_activity_start_cmd *p_cmd = KERNEL_MSG_ALLOC(GAPM_ACTIVITY_START_CMD,
                               TASK_BLE_GAPM, TASK_BLE_APP,
                               gapm_activity_start_cmd);
    
          if (p_cmd) {
             p_cmd->operation = GAPM_START_ACTIVITY;
    
             p_cmd->u_param.scan_param.type = GAPM_SCAN_TYPE_OBSERVER;//GAPM_SCAN_TYPE_GEN_DISC;//GAPM_SCAN_TYPE_OBSERVER;//;
             p_cmd->u_param.scan_param.prop = GAPM_SCAN_PROP_PHY_1M_BIT ;//| GAPM_SCAN_PROP_ACTIVE_1M_BIT;
             p_cmd->u_param.scan_param.scan_param_1m.scan_intv = scan_intv;
             p_cmd->u_param.scan_param.scan_param_1m.scan_wd = scan_wd;
             p_cmd->u_param.scan_param.dup_filt_pol = 0;
             p_cmd->u_param.scan_param.duration = 0;
             p_cmd->u_param.scan_param.period = 10;
    
             p_cmd->actv_idx = app_ble_env.actvs[actv_idx].gap_advt_idx;



    Info:CMD:BLEScan set to 0
    Info:MAIN:Time 820, idle 175266/s, free 69288, MQTT 0(51), bWifi 1, secondsWithNoPing 753, socks 2/24 
    Info:GEN:dhcp=0 ip=192.168.0.79 gate=192.168.0.1 mask=255.255.255.0 mac=38:1f:8d:e2:50:03
    Info:GEN:sta: 1, softap: 0, b/g/n
    Info:GEN:sta:rssi=-39,ssid=Ordinacija,bssid=70:3a:cb:7d:90:9b,channel=1,cipher_type:CCMP
    Info:MAIN:Time 821, idle 190526/s, free 60008, MQTT 0(51), bWifi 1, secondsWithNoPing 754, socks 3/24 
    Info:MAIN:Time 822, idle 179503/s, free 72632, MQTT 0(51), bWifi 1, secondsWithNoPing 755, socks 2/24 
    Info:MAIN:BLE scan mode set to passive
    Info:CMD:BLEScanMode set to 0
    Info:MAIN:Time 823, idle 191055/s, free 72632, MQTT 0(51), bWifi 1, secondsWithNoPing 756, socks 2/24 
    Info:MAIN:Time 824, idle 187593/s, free 72632, MQTT 0(51), bWifi 1, secondsWithNoPing 757, socks 2/24 
    Info:MAIN:BLE passive scan started (idx=0, intv=100, win=30)
    Info:CMD:BLEScan set to 1
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -60 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:Time 825, idle 190604/s, free 70952, MQTT 0(51), bWifi 1, secondsWithNoPing 758, socks 2/24 
    Info:MAIN:BLE adv 83:68:79:50:23:DC rssi -68 evt 57 len 28 data 020106030201A20C1601A200616A72686631616A0000000000000000
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -60 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 5C:5E:34:F1:29:17 rssi -55 evt 57 len 29 data 0201021916F1FC049CEDA91EFEE92CA9F4E3FEE7FC77E8477F48B39197
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -63 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -59 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 71:DA:1D:3A:22:4C rssi -68 evt 57 len 31 data 0201021BFF7500021861B16963C9FE471E7A6283404B8F0F5BD2F2E869AEEA
    Info:MAIN:BLE adv E4:69:79:50:23:DC rssi -59 evt 57 len 28 data 020106030201A20C1601A200616A72686631616A0000000000000000
    Info:MAIN:BLE adv B0:9F:84:89:13:4F rssi -66 evt 57 len 31 data 02010403025AFD17165AFD152007037CEBEE4AF1011F76B7000000D4D360C5
    Info:MQTT:mqtt_host empty, not starting mqtt
    Info:MAIN:Time 826, idle 175623/s, free 64328, MQTT 0(52), bWifi 1, secondsWithNoPing 759, socks 2/24 
    Info:MAIN:BLE adv 87:FD:31:38:C1:A4 rssi -53 evt 57 len 18 data 0201060E16D2FC4000F7015A02580903140E
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -60 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 5C:5E:34:F1:29:17 rssi -59 evt 57 len 29 data 0201021916F1FC049CEDA91EFEE92CA9F4E3FEE7FC77E8477F48B39197
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -62 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 71:DA:1D:3A:22:4C rssi -59 evt 57 len 31 data 0201021BFF7500021861B16963C9FE471E7A6283404B8F0F5BD2F2E869AEEA
    Info:MAIN:Time 827, idle 181091/s, free 70960, MQTT 0(52), bWifi 1, secondsWithNoPing 760, socks 2/24 
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -62 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -60 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -60 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 5C:5E:34:F1:29:17 rssi -57 evt 57 len 29 data 0201021916F1FC049CEDA91EFEE92CA9F4E3FEE7FC77E8477F48B39197
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -62 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:Time 828, idle 178752/s, free 70960, MQTT 0(52), bWifi 1, secondsWithNoPing 761, socks 2/24 
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -59 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 71:DA:1D:3A:22:4C rssi -54 evt 57 len 31 data 0201021BFF7500021861B16963C9FE471E7A6283404B8F0F5BD2F2E869AEEA
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -60 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:BLE adv 87:FD:31:38:C1:A4 rssi -62 evt 57 len 17 data 0201060D16D2FC4000F80C6B0B10001101
    Info:MAIN:BLE adv CD:A1:3D:4D:A0:23 rssi -59 evt 9 len 31 data 1EFF060001092022912EF1AF8380CF15DB6139A5DDAA2016EFD34D2015B23C
    Info:MAIN:Time 829, idle 186737/s, free 72440, MQTT 0(52), bWifi 1, secondsWithNoPing 762, socks 2/24 
    Info:MAIN:BLE passive scan stopped
    Info:CMD:BLEScan set to 0
    Info:MAIN:Time 831, idle 184116/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 764, socks 2/24 
    Info:MAIN:Time 832, idle 187659/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 765, socks 2/24 
    Info:MAIN:Time 833, idle 192467/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 766, socks 2/24 
    Info:MAIN:Time 834, idle 192364/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 767, socks 2/24 
    Info:MAIN:Time 835, idle 197125/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 768, socks 2/24 
    Info:MAIN:Time 836, idle 189198/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 769, socks 2/24 
    Info:MAIN:Time 837, idle 200379/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 770, socks 2/24 
    Info:MAIN:Time 838, idle 189865/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 771, socks 2/24 
    Info:MAIN:Time 839, idle 194219/s, free 72544, MQTT 0(52), bWifi 1, secondsWithNoPing 772, socks 2/24 
    Info:MAIN:Time 840, idle 189270/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 773, socks 2/24 
    Info:GEN:dhcp=0 ip=192.168.0.79 gate=192.168.0.1 mask=255.255.255.0 mac=38:1f:8d:e2:50:03
    Info:GEN:sta: 1, softap: 0, b/g/n
    Info:GEN:sta:rssi=-40,ssid=Ordinacija,bssid=70:3a:cb:7d:90:9b,channel=1,cipher_type:CCMP
    Info:MAIN:Time 841, idle 192863/s, free 72632, MQTT 0(52), bWifi 1, secondsWithNoPing 774, socks 2/24 
    Info:MQTT:mqtt_host empty, not starting mqtt
    Info:MAIN:Time 842, idle 187985/s, free 72632, MQTT 0(53), bWifi 1, secondsWithNoPing 775, socks 2/24 


    Added after 1 [hours] 56 [minutes]:

    Still no clear path in my head how to use this but here we go, extend the SDK scan_parameter in ble_api_5_x.h

    struct scan_param {
        uint8_t  filter_en;
        uint8_t  channel_map;
        uint16_t interval;
        uint16_t window;
        uint8_t  active;      // 0 = passive, 1 = active
        uint8_t  filter_type;
        uint8_t  filter_param[32];
    };


    hardcoded passive in app_ble.c is replaced with a conditional

    p_cmd->u_param.scan_param.prop = GAPM_SCAN_PROP_PHY_1M_BIT;
    if (app_ble_env.actvs[actv_idx].param.scan.active) {
        p_cmd->u_param.scan_param.prop |= GAPM_SCAN_PROP_ACTIVE_1M_BIT;
    }


    declare it in hal_generic helper

    void HAL_BTScan_SetActive(int bActive);
    int HAL_BTScan_GetActive();


    add week stubs with log messaging

    void __attribute__((weak)) HAL_BTScan_SetEnabled(int bEnabled)
    {
       (void)bEnabled;
       ADDLOG_INFO(LOG_FEATURE_MAIN, "BLE scan weak HAL active (platform-specific backend not linked)");
    }
    
    int __attribute__((weak)) HAL_BTScan_GetEnabled()
    {
       return 0;
    }
    
    void __attribute__((weak)) HAL_BTScan_SetActive(int bActive)
    {
       (void)bActive;
       ADDLOG_INFO(LOG_FEATURE_MAIN, "BLE scan mode weak HAL active (platform-specific backend not linked)");
    }
    
    int __attribute__((weak)) HAL_BTScan_GetActive()
    {
       return 0;
    }


    Should be platform agnostic - not tested beyond N!!

    AT BLE path should have a propagation for this

            scan_info.channel_map = 7;
            scan_info.interval = hal_ble_env.scan.scan_intvl;
            scan_info.window = hal_ble_env.scan.scan_wd;
            scan_info.active = hal_ble_env.scan.scan_type ? 1 : 0; // are we active or not?
            scan_info.filter_type = filter_type;


    and expose it to the command layer in cmd_main, I used BLEScan 0/1 and BLEScanMode 0/1 (passive/active)

    Added after 35 [minutes]:

    just to make a note as I just noticed it now BLEMode 0 does not have full deinit so heap can drop low if MQTT is involved, just to be aware of it.
  • #26 21850645
    DeDaMrAz
    Level 22  
    Great!!

    insmod wrote:
    Will need TLSR825x sensor with atc firmware for that.


    All my BT sensors are MI converted to ATC firmware, sorry for not mentioning that.

    Off topic - might be interesting to test converting them to ZigBee.
  • Helpful post
    #27 21850646
    insmod
    Level 31  
    >>21850645
    I have one LYWSD03MMC with ZigbeeTLc.
    Don't recommend if sensor is using CR2032.
    I replaced the battery 31 july, and it's now at 57%.
  • #28 21850647
    DeDaMrAz
    Level 22  
    Thanks for the info, will leave it alone then.

    I think this is valid milestone for me to move on to something else now. Thank you for testing and validation.

    @p.kaczmarek2 feel free to chime in and test out, this can be a valid next big feature for OBK?
  • #29 21850716
    p.kaczmarek2
    Moderator Smart Home
    Very good, so it now can find BT IoT devices? How can I help with testing?

    Can it be enabled by default on 4 MB > ESPs?
    Helpful post? Buy me a coffee.
  • #30 21850947
    insmod
    Level 31  
    >>21850716
    It's disabled on ESPs for now (some code must be rewritten). Enabled by default on RTL8720D, and enabled in btproxy variants on RTL87X0C, BK7238 and BK7231N_ALT.
    Only scan is supported (both passive and active), no active connections.

Topic summary

✨ The discussion centers on Bluetooth testing using the ESP32-C3 as a Bluetooth coordinator for the OpenBeken project. The implementation is based on the bluedroid stack, chosen for compatibility with ESPHome and ease of integration. Challenges include differences in ESP-IDF versions, Bluetooth 4.2 versus Bluetooth 5 and BLE support, and build environment issues such as parsing errors in partitions.csv and Docker build bugs. A working solution has been developed and is available on a GitHub fork, though the code requires cleanup. The conversation also covers coexistence settings between WiFi and Bluetooth, with coexistence ratios like 40% WiFi and 60% Bluetooth discussed. Binary sizes for the RTL8720D platform are noted, with builds around 1053kb without Berry and 1157kb with it. Build system limitations for the RTL8720D, such as the inability to use parallel make (-j), are mentioned. There is interest in adapting the ESPHome API as an alternative to MQTT for communication. Overall, the thread highlights practical issues and solutions in integrating Bluetooth proxy functionality on ESP32-C3 and RTL8720D platforms within the OpenBeken ecosystem.
Generated by the language model.

FAQ

TL;DR: Early ESP32‑C3 BT Proxy for OpenBeken boots on ESP‑IDF v5.5.2 with 4 MB flash; “Proof of concept is working…”. It targets coordinator‑style BLE relaying, but author paused pending real use cases. [Elektroda, DeDaMrAz, post #21846290]

Why it matters: Makers testing BLE gateways on low‑cost ESP32‑C3/RTL8720D need clear build notes, limits, and quick fixes.

Quick Facts

Quick Facts

What is OpenBeken?

OpenBeken is a lightweight open-source firmware for smart devices, focused on Wi‑Fi/IoT control and driver extensibility. The ESP32‑C3 BT Proxy test runs inside an OpenBeken build, identified in boot logs as Project “OpenBeken.” [Elektroda, DeDaMrAz, post #21846290]

Does the ESP32‑C3 BT Proxy proof of concept actually work?

Yes. The author confirmed, “Proof of concept is working…”. It boots on ESP‑IDF v5.5.2 and exchanges API messages, indicating a functional handshake and entity listing. This is an experiment parked until clear use cases appear. [Elektroda, DeDaMrAz, post #21846290]

Which Bluetooth stack is used: NimBLE or Bluedroid?

Bluedroid. The author chose Bluedroid because ESPHome was the base and easiest to integrate for this prototype. “bluedroid as ESPHome was the base and easiest to implement.” [Elektroda, DeDaMrAz, post #21846587]

Where can I get the experimental code?

A work‑in‑progress branch is shared: a BT_proxy branch on the author’s fork. It’s noted as messy but usable for experimentation pending cleanup. [Elektroda, DeDaMrAz, post #21846593]

I miss BLE advertisements once Wi‑Fi connects—how do I fix that?

This symptom was observed. Tuning Wi‑Fi/BLE coexistence and BLE scan timing helped on ESP. Try a 40/60 Wi‑Fi/BT split and adjust scan intervals/windows to recover advertisements. “play around with that ratio.” [Elektroda, DeDaMrAz, post #21847084]

What coexistence ratio worked during tests?

A 40% Wi‑Fi and 60% BT split was reported during ESP tests. This improved advertisement capture under contention. Treat as a starting point and validate in your RF environment. [Elektroda, DeDaMrAz, post #21847063]

How big is the RTL8720D build, and does flash size matter?

A minimal RTL8720D build measured ~1053 KB without Berry, about 1157 KB with it. Devices with only 2 MB flash may struggle once BT components inflate binaries. Leave overhead for OTA and filesystem. [Elektroda, insmod, post #21847067]

Will 2 MB flash devices be supported?

The author warns BT proxy binaries are often large, likely excluding 2 MB targets. Treat this as a constraint until further optimization or feature trimming lands. [Elektroda, DeDaMrAz, post #21846290]

Can I build RTL8720D firmware with parallel make jobs?

Avoid make -j on RTL8720D. Builds fail when parallelized. Use single‑job builds to stabilize toolchain behavior in current snapshots. [Elektroda, insmod, post #21847083]

Is MQTT required, or can I adapt the ESPHome API?

An alternative using the ESPHome API was proposed. This can simplify discovery and state sync versus MQTT, especially for Home Assistant setups. Evaluate API throughput against BLE scan load. [Elektroda, insmod, post #21847083]

How do I try the ESP32‑C3 BT Proxy build? (3 steps)

  1. Clone the author’s fork and checkout the BT_proxy branch.
  2. Build for ESP32‑C3 with ESP‑IDF v5.5.2, enabling the BT proxy flag.
  3. Flash, connect Wi‑Fi, then verify BLE handshake logs over UART. [Elektroda, DeDaMrAz, post #21846593]

I saw a MAC address issue—what’s the status?

One tester hit a MAC display issue initially and fixed it first. Ensure correct SDK config and init order when enabling BT coexistence. Validate with fresh logs after changes. [Elektroda, insmod, post #21847064]

Is there a Dockerized local build to speed iteration?

Yes. The author recommends the Docker local build from the fork to accelerate compile‑flash cycles. This helps when testing BTProxy and TCPuart combos. [Elektroda, DeDaMrAz, post #21847075]

What’s the project status and roadmap?

Development is paused due to cost‑benefit concerns. The test device will keep collecting stability data. A port to RTL8720D is planned when the dev board is available. [Elektroda, DeDaMrAz, post #21846290]

Will this use case extend to RTL8720D Zigbee gateways?

Yes, the initial goal was restoring BT proxy on a Zigbee gateway with RTL8720D. Work began on ESP32‑C3 first due to availability and prior hurdles. [Elektroda, DeDaMrAz, post #21846587]

Any other tuning tips beyond coexistence?

Yes. Tweak BLE scan timing (interval/window) for better capture under Wi‑Fi load. This improved results in ESPHome contexts during testing. [Elektroda, DeDaMrAz, post #21847088]
Generated by the language model.
ADVERTISEMENT