Wake up ESP32C6 from light sleep using a BT button

daniel_3in
Posts: 1
Joined: Wed Jun 19, 2024 10:28 am

Wake up ESP32C6 from light sleep using a BT button

Postby daniel_3in » Thu Jun 20, 2024 7:43 am

Hi, I'm developing a project with VSCode and ESP-IDF for a ESP32-C6. I want to preserve as much battery as possible, so I'm trying to keep it in light sleep and use a Shelly BLU button ( https://shellyspain.com/shelly-blu-button1-blanco.html ) as a BlueTooth wake up source, but no luck so far.

In my code, I set the scan parameters to only accept devices from the white list:
  1. #define TARGET_ADDR "90:ab:96:a0:85:86" //Shelly BLU button public address
  2.  
  3. static esp_ble_scan_params_t ble_scan_params = {
  4.     .scan_type              = BLE_SCAN_TYPE_ACTIVE,
  5.     .own_addr_type          = BLE_ADDR_TYPE_PUBLIC,
  6.     .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ONLY_WLST,
  7.     .scan_interval          = 0x50,
  8.     .scan_window            = 0x30,
  9.     .scan_duplicate         = BLE_SCAN_DUPLICATE_DISABLE
  10. };
The callback function looks like this:
  1. void gap_callback(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
  2.     switch (event) {
  3.         case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
  4.             esp_ble_gap_start_scanning(0); //Scan forever
  5.             break;
  6.         }
  7.         case ESP_GAP_BLE_SCAN_RESULT_EVT: {
  8.             esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
  9.             switch (scan_result->scan_rst.search_evt) {
  10.                 case ESP_GAP_SEARCH_INQ_RES_EVT: {
  11.                    
  12.                     char addr_str[18];
  13.                     sprintf(addr_str, "%02x:%02x:%02x:%02x:%02x:%02x",
  14.                             scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2],
  15.                             scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], scan_result->scan_rst.bda[5]);
  16.  
  17.                     if (strcmp(addr_str, TARGET_ADDR) == 0)
  18.                     {
  19.                         if(scan_result->scan_rst.ble_adv[scan_result->scan_rst.adv_data_len - 1] != 0)
  20.                         {
  21.                             ESP_LOGI(TAG_BLE, "Advertised Device: %s", addr_str);
  22.                         }              
  23.                     }
  24.                     break;
  25.                 }
  26.                 case ESP_GAP_SEARCH_INQ_CMPL_EVT: {
  27.                     ESP_LOGI(TAG_BLE, "Scan complete");
  28.                     scan_complete = true;
  29.                     break;
  30.                 }
  31.                 default:
  32.                     break;
  33.             }
  34.             break;
  35.         }
  36.         default:
  37.             break;
  38.     }
  39. }
Before starting the main loop, I call this function to initialize Bluetooth and start it:
  1. void ScanBT() {
  2.     esp_err_t ret;
  3.  
  4.     // Initialize NVS
  5.     ret = nvs_flash_init();
  6.     if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  7.         ESP_ERROR_CHECK(nvs_flash_erase());
  8.         ret = nvs_flash_init();
  9.     }
  10.     ESP_ERROR_CHECK(ret);
  11.  
  12.     ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  13.  
  14.     esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  15.     ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
  16.     ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
  17.     ESP_ERROR_CHECK(esp_bluedroid_init());
  18.     ESP_ERROR_CHECK(esp_bluedroid_enable());
  19.  
  20.     esp_ble_gap_clear_whitelist();
  21.    
  22.     ESP_ERROR_CHECK(esp_ble_gap_register_callback(gap_callback));
  23.  
  24.     uint8_t whitelist_addr[6] = {0x90, 0xab, 0x96, 0xa0, 0x85, 0x86}; //Shelly BLU button public address
  25.     esp_ble_gap_update_whitelist(true, whitelist_addr, BLE_WL_ADDR_TYPE_PUBLIC);
  26.  
  27.     ESP_ERROR_CHECK(esp_ble_gap_set_scan_params(&ble_scan_params));
  28.  
  29.     esp_sleep_enable_bt_wakeup();
  30.  
  31.     ESP_LOGI(TAG_BLE, "Scanning...");
  32.     scan_complete = false;
  33.  
  34.     esp_ble_gap_update_whitelist(true, whitelist_addr, BLE_WL_ADDR_TYPE_RANDOM);
  35. }
With this setup, I can detect the press of the button if the chip is not in sleep mode but nothing else. For some reason, sometimes the C6 wakes up from the sleep mode with ESP_SLEEP_WAKEUP_BT as the reason, but it's not because of the button.

I have tried to set the automatic light mode, adding this code:
  1. esp_pm_config_t pm_config = {
  2.             .max_freq_mhz = 80,
  3.             .min_freq_mhz = 10,
  4.             .light_sleep_enable = true
  5.     };
  6.     ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
and in sdkconfig, activating support for power management, FreeRTOS tickless idle support and External 32KHz crystal as RTC clock source (although I don't have one currently).

But then the C6 keeps resetting itself everytime it tries to go to light sleep.

Can anyone offer some guide, please? I also attached the current sdkconfig file of the project, just in case someone sees something wrong there (right now there's no automatic light sleep configuration active)
Thank you in advance!
Attachments
sdkconfig.txt
(85.47 KiB) Downloaded 44 times

Who is online

Users browsing this forum: Bing [Bot] and 82 guests