I am trying to develop a small 9-button BLE keyboard on the ESP32 with a rotary encoder as a volume knob. My question involves the low power modes and the time it takes for them to wake up.

My system enters sleep mode after 5 seconds of inactivity from the user. The issue is when the ESP wakes up from light sleep - it takes around 1 to 2 seconds for bluetooth to reconnect, and the keystroke or action that woke it up isn't processed.

How can I address the issue of a faster reconnect? I want the system to save power when it is not in use, but I also wish for it to be responsive when coming out of this low-power state to process user requests.

Here is the processing block:

while (true) {
    //Begin sleep if user has not interacted for >= 5 seconds
    current_sys_time = millis();
    if (current_sys_time - last_sys_event_time > MAX_ALLOWED_IDLE_TIME)

    //Play/pause media when rotary encoder switch is pressed
    if (digitalRead(PIN_SW) == LOW && play_pause_btn == NOT_PRESSED) {
        if (digitalRead(PIN_SW) == LOW)
            play_pause_btn = WAS_PRESSED;
        last_sys_event_time = millis();
    else if (digitalRead(PIN_SW) == HIGH && play_pause_btn == WAS_PRESSED) {
        last_sys_event_time = millis();
        play_pause_btn = NOT_PRESSED;

    //Turn volume up or down when encoder is turned clockwise or ocunter-clockwise, respectively 
    if (encoder_read()) {
        if (encoder_4bit_sample == CLOCKWISE)
        else if (encoder_4bit_sample == COUNTER_CLOCKWISE)

And here is my sleep function:

void light_sleep_begin()
    gpio_wakeup_enable(GPIO_NUM_33, GPIO_INTR_LOW_LEVEL); //Encoder SW pin
    gpio_wakeup_enable(GPIO_NUM_35, GPIO_INTR_LOW_LEVEL); //Encoder CLK pin
    gpio_wakeup_enable(GPIO_NUM_32, GPIO_INTR_LOW_LEVEL); //Encoder DT pin


Board: ESP32 DevkitC \ IDE: PlatformIO \ Module: ESP32 WROOM

  • I don't think the failure to process the input is due to any bluetooth reconnection issue. Have you tried placing a print within your IF block so that you know as soon as the ESP observes a button press? – SoreDakeNoKoto May 4 at 22:19
  • @TisteAndii Yeah, the thing is that when light sleep is called, I see the ESP disconnect from the slave device, and when it wakes up it takes ~2 seconds to re-establish the connection. There has to be a quicker wake-up time :/ – jm567 May 5 at 20:48
  • Waking up likely isn't what is taking 2 seconds. That's why I'm saying you should time it, to narrow down exactly what's going on. Place a print(millis()) immediately before and after light_sleep_begin() so you know how long that's taking. Place another inside the IF block so you know when the button press gets noticed, BLE connection or not. Then post what you find. – SoreDakeNoKoto May 5 at 23:09
  • Hey, sorry I was being ambiguous with my use of the phrase "wake up". I was talking about the time it takes for BLE to re-connect the ESP to the computer after sleeping. Anyways, I took your advice and placed a Serial.println(millis()); before and after light_sleep_begin(); The difference between the first and second print is how long it was sleeping before being waken up. It changes each time depending on how long I let it sleep. The button press gets noticed instantly. – jm567 May 7 at 14:22
  • Okay, that's good news. The button events are instantly noticed, problem is sending them ASAP after waking up. When you enter light sleep, the radios are turned off so upon waking up, I expect it'll take a while for the radio to resume advertising and for your PC (or whatever your client is) to connect to the ESP32. All these small delays add up and represent the cost of going to sleep in the first place. You can try saving the button press event(s) in some array until the connection is up (isConnnected()) and then send them. Or raise an issue on the library's Github, seems responsive. – SoreDakeNoKoto May 7 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.