espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.26k stars 7.34k forks source link

Light sleep and BLE, crash on the 29th wake up #4616

Closed SarahDDSp closed 3 years ago

SarahDDSp commented 3 years ago

Hardware:

Board: TTGO-LORA32-V1
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/ttgo-lora32-v1.html PLATFORM: Espressif 32 (2.1.0) > TTGO LoRa32-OLED V1 HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash (ESP32-D0WDQ6 (revision 1)) Core Installation version: 2.1.0, (ESP32 BLE Arduino 1.0.1) IDE name: Platform.io Flash Frequency: 40Mhz PSRAM enabled: no Upload Speed: automatic one Computer OS: Ubuntu

Description:

I am currently working on an iOT project. My goal is to save as much power as possible so my product can run as long as possible on battery. Thus I would like to make my system sleep for 7 to 10 sec and then wake up for the same amount of time. But after 29 wake up, the BLE is crashing when calling startAdvertising. The bug I am reporting happens either the board is powered through USB or a 1S Li-ion battery (with TL1963A LPO). I am not even connecting to the BLE in the meanwhile so I am not doing anything than putting the board to sleep and waking it up. I am using properly the whole disable deinit process and init enable one.

My BLEsetup funtion is using the BLEDevice::init() function and then define Server, Services, and characteristics as in the setup loop of arduino example for BLE. It ends with BLEDevice::startAdvertising();. According to the back trace, it is where it fails at the 29th wake up.

I try to just let more time (a cycle of wake up/sleep without connecting) after the 28th so that it won't fail, but it had no effect.

I really have no idea of how to solve this issue.

Sketch:

void setup() {
  Serial.begin(115200);
  Serial.printf("Use Lora = %d, Use light sleep = %d \n", USE_LORA, USE_LIGHT_SLEEP);

  if(VERBOSE && VERBOSE_MAIN) Serial.println("============= Init Setup =============");
  // ================ INIT SPIFFS ================ //
  bool SPIFFS_init = SPIFFS.begin();
  if (VERBOSE && VERBOSE_MAIN_INIT)
  {
    if(!SPIFFS_init)
    {if(VERBOSE && VERBOSE_MAIN_INIT) Serial.println("An Error has occurred while mounting SPIFFS");}
    else
    {if(VERBOSE && VERBOSE_MAIN_INIT) Serial.println("SPIFFS init sucessful");}

    listDir(SPIFFS, "/", 2);
  }

  // ================ BLE ================ //
  if(VERBOSE && VERBOSE_MAIN_INIT)Serial.println("Before ble instialisation");
  BLESyst.setupBLE(serial_ID_ble,"1234abcd");

  // ================ Lora ================ //
  if(VERBOSE && VERBOSE_MAIN_INIT)Serial.println("Before Lora instialisation");
  if (USE_LORA)
  { 
    System.updateMessageToSendBLEandLora(checkFrequency);
    setMsgLora(System.getMessageLora());
    setupLoRaWAN();}

  // ================ LIGHT SLEEP ================ //
  if(VERBOSE && VERBOSE_MAIN_INIT)Serial.println("Before Deep sleep instialisation");
  if(USE_LIGHT_SLEEP) 
    {esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);}

  checkFrequency=(int)(1000/MAINFREQUENCY);

  if(!USE_LORA) lightsleep=true;
  timeLightSleepInit=millis();
}

void loop ()
{

   if(RESTART)
     {
       delay(5);
      //setup BLE contains the init function of the arduino library for BLE
       BLESyst.setupBLE(serial_ID_ble,"1234abcd");
       RESTART=false;
       timeLightSleepInit=millis();
       Serial.println("Setting counter timer to 0");
       counterTimer = 0 ;
     }

//Some other stuffs in main loop from which counterTimer incrementation

/* Light sleep management */
  if ((!DEVICE_IS_CONNECTED)&&(counterTimer>=70)&&(lightsleep)) //  
  {
    counterTimer=0;
    RESTART=true;
    if(USE_LIGHT_SLEEP) 
    {
        if(VERBOSE && VERBOSE_MAIN) 
        {
          Serial.println("I am going to light sleep");
          delay(250);
        }
        BLEDevice::deinit();
        delay(200);
        // Enter sleep mode 
        esp_light_sleep_start();
    }    
  }

Debug Messages:

Guru Meditation Error: Core  1 panic'ed (StoreProhibited). Exception was unhandled.
17:21:58.200 > Core 1 register dump:
17:21:58.202 > PC      : 0x4000c2e4  PS      : 0x00060330  A0      : 0x80111ad1  A1      : 0x3ffc9fd0  
17:21:58.210 > A2      : 0x00000000  A3      : 0x3ffffac0  A4      : 0x000001e0  A5      : 0x00000000  
17:21:58.217 > A6      : 0x89abcdef  A7      : 0x01234567  A8      : 0x00000000  A9      : 0x3ffc9f70  
17:21:58.225 > A10     : 0x00000000  A11     : 0x00001800  A12     : 0x00000000  A13     : 0x00000003  
17:21:58.233 > A14     : 0x00060320  A15     : 0x00000000  SAR     : 0x00000018  EXCCAUSE: 0x0000001d  
17:21:58.241 > EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x0000001d  
17:21:58.248 > 
17:21:58.249 > Backtrace: 0x4000c2e4:0x3ffc9fd0 0x40111ace:0x3ffc9fe0 0x4010bdce:0x3ffca000 0x401092b9:0x3ffca030 0x400d6047:0x3ffca090 0x400d789a:0x3ffca0d0 0x400d2334:0x3ffca0f0 0x400d5091:0x3ffca130 0x400dcf8d:0x3ffca1c0 0x4008e94d:0x3ffca1e0
17:21:58.378 >   #0  0x4000c2e4:0x3ffc9fd0 in ?? ??:0
17:21:58.378 >   #1  0x40111ace:0x3ffc9fe0 in btc_gap_ble_arg_deep_copy at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c:1032
17:21:58.378 >   #2  0x4010bdce:0x3ffca000 in btc_transfer_context at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/btc/core/btc_task.c:155
17:21:58.378 >   #3  0x401092b9:0x3ffca030 in esp_ble_gap_config_adv_data at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/api/esp_gap_ble_api.c:517
17:21:58.378 >   #4  0x400d6047:0x3ffca090 in BLEAdvertising::start() at /home/sarah/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src/BLEAdvertising.cpp:485
17:21:58.378 >   #5  0x400d789a:0x3ffca0d0 in BLEDevice::startAdvertising() at /home/sarah/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src/BLEDevice.cpp:570
17:21:58.378 >   #6  0x400d2334:0x3ffca0f0 in BLEFunctions::setupBLE(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at src/BLEFunctions.cpp:304
17:21:58.378 >   #7  0x400d5091:0x3ffca130 in loop() at src/main.cpp:157 (discriminator 2)
17:21:58.378 >   #8  0x400dcf8d:0x3ffca1c0 in loopTask(void*) at /home/sarah/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:19
17:21:58.378 >   #9  0x4008e94d:0x3ffca1e0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

I hope my demand is sufficiently clear and furnished. Thanks in advance for any help you could provide about it.

chegewara commented 3 years ago

btc_gap_ble_arg_deep_copy at

To me it looks like short on memory, at least i think it is.

BTW very precise counting to 29

SarahDDSp commented 3 years ago

Thanks to your comment I was able to find similar topics about this issue : first, second , third. Did this memory leak was solved or is it still happening ?

Concerning the 29, it is happening with a surprising regularity. I guess the number will depend of the available memory on the board depending of each project.

Is there a way to not have to deinit BLE each time I want to go to light sleep, as technically memory, thus connection infos, is preserved in this sleep mode ? I have LoraWan running in parallel without issues.

Thank you for your time

chegewara commented 3 years ago

I have no knowledge about memory leak in ble library in init/deinit sequence, i didnt investigate it. I just remember that deep copy error may be related to short on memory.

I am wondering if you really need to deinit and init ble all the time. Did you try to stop advertising and not using ble scan? When radio is not used then should not drain power. Im not saying it is better than fixing eventual memory leak, but maybe worth to consider.

SarahDDSp commented 3 years ago

I achieved this time to make this start/stop advertising work. For that I needed to create a stop advertising function working as the start advertising function of BLEDevice Class from BLE arduino library for esp32, which means :

void stopAdvertising()
{
  BLEDevice::getAdvertising()->stop();
}

Maybe it will help someone in the future. I placed stopAdvertising where deinit stands and start advertising where init stands

I will test it on a longer period to see if some issues appears.

stale[bot] commented 3 years ago

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale[bot] commented 3 years ago

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.