Skip to content

uPesy only delivers currently in France.

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Save energy on the ESP32 with Deep Sleep

The ESP32 has a power-saving mode called Deep Sleep which allows to “put the ESP32 to sleep”. This is similar to putting a computer to sleep to save power. During this mode, the ESP32 can perform simple tasks and be woken up to perform more complex tasks.

What is it for?

This power-saving mode is useful when the ESP32 is battery powered, and the ESP32 “works” punctually. (For example, reading a value from a sensor and sending it via WiFi every 10 minutes). The battery will be discharged quickly if the ESP32 is on 24 hours a day. With the Deep Sleep mode, the batteries will last much longer.

Deep Sleep mode puts the ESP32 in a rudimentary state.

Indeed, in Deep Sleep mode, the 2 CPUs of the ESP32 do not work anymore, and it is the ULP (Ultra Low Processor) processor which takes over. This processor consumes very little power and can perform specific actions. The Flash and RAM are not powered anymore; only the RTC memory is still powered and can be used. WiFi and Bluetooth are, of course, also disabled. Thanks to this RTC memory, you can still access the peripherals, interrupts, timers and internal sensors.

Wake-up sources

After putting the ESP32 in Deep Sleep mode, there are several ways to wake it up:

  • Use an internal timer to wake up the ESP32 at a selected time (internal wake-up)

  • Using capacitive touch sensors

  • Use the RTC pins

Note

We can combine different wake-up sources.

Warning

It is also possible to activate the Deep Sleep mode without configuring any wake-up sources. In this case, the ESP32 will remain in Deep Sleep mode until a manual reset (or reflashing the board). Therefore, it is impossible to “brick” the ESP32 with the Deep Sleep mode.

Usage

When you want to use the Deep Sleep mode, you have to think about :

  • Configure the ESP32 wake-up sources

  • Eventually, choose which peripherals you want to turn off or keep on during Deep Sleep mode. By default, the ESP32 turns off all peripherals that are not needed to detect the wake-up request.

  • Use the function esp_deep_sleep_start() to enter the Deep Sleep mode.

Use a Timer as a wake-up source

Here is the code used to test the timer as a wake-up source:

#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP  5

RTC_DATA_ATTR int bootCount = 0;

void print_wakeup_reason(){
   esp_sleep_wakeup_cause_t wake_up_source;

   wake_up_source = esp_sleep_get_wakeup_cause();

   switch(wake_up_source){
      case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wake-up from external signal with RTC_IO"); break;
      case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wake-up from external signal with RTC_CNTL"); break;
      case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wake up caused by a timer"); break;
      case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wake up caused by a touchpad"); break;
      default : Serial.printf("Wake up not caused by Deep Sleep: %d\n",wake_up_source); break;
   }
}

void setup(){
   Serial.begin(115200);

   ++bootCount;
   Serial.println("----------------------");
   Serial.println(String(bootCount)+ "th Boot ");

   // Displays the reason for the wake up
   print_wakeup_reason();

   //Timer Configuration
   esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
   Serial.println("ESP32 wake-up in " + String(TIME_TO_SLEEP) + " seconds");

   // Go in Deep Sleep mode
   Serial.println("Goes into Deep Sleep mode");
   Serial.println("----------------------");
   delay(100);
   esp_deep_sleep_start();
   Serial.println("This will never be displayed");
}

void loop(){
}

The function print_wakeup_reason() displays the ESP32 wake-up source. During the first ESP32 boot, the wake-up was not caused by the Deep Sleep but by the “Hard resetting via RTS pin…” on the Arduino IDE. Then during the next boots, the ESP32 is woken up from deep sleep thanks to a timer every 5 seconds.

You can change the Deep Sleep duration by modifying the timer with the function esp_sleep_enable_timer_wakeup() .

ets Jun 8 2016 00:22:57

rst: 0x10 (RTCWDT_RTC_RESET), boot: 0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP: 0xee
clk_drv: 0x00, q_drv: 0x00, d_drv: 0x00, cs0_drv: 0x00, hd_drv: 0x00, wp_drv: 0x00
mode: DIO, clock div: 1
load: 0x3fff0018, len: 4
load: 0x3fff001c, len: 1216
ho 0 tail 12 room 4
load: 0x40078000, len: 9720
ho 0 tail 12 room 4
load: 0x40080400, len: 6352
entry 0x400806b8
----------------------
1th Boot
Wake up not caused by Deep Sleep: 0
ESP32 wake-up in in 5 seconds
Goes into Deep Sleep mode
----------------------
ets Jun 8 2016 00:22:57

rst: 0x5 (DEEPSLEEP_RESET), boot: 0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP: 0xee
clk_drv: 0x00, q_drv: 0x00, d_drv: 0x00, cs0_drv: 0x00, hd_drv: 0x00, wp_drv: 0x00
mode: DIO, clock div: 1
load: 0x3fff0018, len: 4
load: 0x3fff001c, len: 1216
ho 0 tail 12 room 4
load: 0x40078000, len: 9720
ho 0 tail 12 room 4
load: 0x40080400, len: 6352
entry 0x400806b8
----------------------
2th Boot
Wake up caused by a timer
ESP32 wake-up in in 5 seconds
Goes into Deep Sleep mode
----------------------

Use a Touchpad as a wake-up source

Here is the code used to wake up the ESP32 with the touchpads:

#define seuil 30 //Detection threshold for the capacitive sensor

RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;

void fonction_isr(){
}

void setup(){
   Serial.begin(115200);

   ++bootCount;
   Serial.println("----------------------");
   Serial.println(String(bootCount)+ "th Boot ");

   //Displays the source of the wake-up call and the touchpad number
   print_wakeup_reason();
   print_wakeup_touchpad();

   //Configuration of an interrupt for the T0 touchpad (GPIO4)
   touchAttachInterrupt(T0, fonction_isr, seuil);

   //Activate wake up by touchpads
   esp_sleep_enable_touchpad_wakeup();

   //Goes into Deep Sleep mode
   Serial.println("Goes into Deep Sleep mode");
   Serial.println("----------------------");
   esp_deep_sleep_start();
}

void loop(){
}

void print_wakeup_reason(){
   esp_sleep_wakeup_cause_t wake_up_source;

   wake_up_source = esp_sleep_get_wakeup_cause();

   switch(wake_up_source){
      case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wake-up from external signal with RTC_IO"); break;
      case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wake-up from external signal with RTC_CNTL"); break;
      case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wake up caused by a timer"); break;
      case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wake up caused by a touchpad"); break;
      default : Serial.printf("Wake up not caused by Deep Sleep: %d\n",wake_up_source); break;
   }
}

void print_wakeup_touchpad(){
   touch_pad_t pin;
   touchPin = esp_sleep_get_touchpad_wakeup_status();
   switch(touchPin){
      case 0  : Serial.println("Wire touched at GPIO 4"); break;
      case 1  : Serial.println("Wire touched at GPIO 0"); break;
      case 2  : Serial.println("Wire touched at GPIO 2"); break;
      case 3  : Serial.println("Wire touched at GPIO 15"); break;
      case 4  : Serial.println("Wire touched at GPIO 13"); break;
      case 5  : Serial.println("Wire touched at GPIO 12"); break;
      case 6  : Serial.println("Wire touched at GPIO 14"); break;
      case 7  : Serial.println("Wire touched at GPIO 27"); break;
      case 8  : Serial.println("Wire touched at GPIO 33"); break;
      case 9  : Serial.println("Wire touched at GPIO 32"); break;
      default : Serial.println("Wake up not caused the touchpads"); break;
   }
}

The print_wakeup_reason() function displays the ESP32 wake-up source and the print_wakeup_touchpad() displays the number of the touchpad used. We added an interrupt on the touchpad T0 (GPIO4) with the function touchAttachInterrupt() . During the 1st boot of the ESP32, the wake-up was not caused by the Deep Sleep but by the “Hard resetting via RTS pin…” on the Arduino IDE.

ets Jun 8 2016 00:22:57

rst: 0x10 (RTCWDT_RTC_RESET), boot: 0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP: 0xee
clk_drv: 0x00, q_drv: 0x00, d_drv: 0x00, cs0_drv: 0x00, hd_drv: 0x00, wp_drv: 0x00
mode: DIO, clock div: 1
load: 0x3fff0018, len: 4
load: 0x3fff001c, len: 1216
ho 0 tail 12 room 4
load: 0x40078000, len: 9720
ho 0 tail 12 room 4
load: 0x40080400, len: 6352
entry 0x400806b8
----------------------
1th Boot
Wake up not caused by Deep Sleep: 0
Wake up not caused the touchpads
Goes into Deep Sleep mode
----------------------
ets Jun 8 2016 00:22:57

rst: 0x5 (DEEPSLEEP_RESET), boot: 0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP: 0xee
clk_drv: 0x00, q_drv: 0x00, d_drv: 0x00, cs0_drv: 0x00, hd_drv: 0x00, wp_drv: 0x00
mode: DIO, clock div: 1
load: 0x3fff0018, len: 4
load: 0x3fff001c, len: 1216
ho 0 tail 12 room 4
load: 0x40078000, len: 9720
ho 0 tail 12 room 4
load: 0x40080400, len: 6352
entry 0x400806b8
----------------------
2th Boot
Wake up caused by a touchpad
Wire touched at GPIO 4
Goes into Deep Sleep mode
-------------

Use a GPIO pin as a wake-up source

We can also use the GPIO pins with a push button to wake up the Deep Sleep ESP32.

Warning

Only the RTC_GPIO pins can be used (in light blue insert on the pinout below)

pin diagram of the complete ESP32

Pinout of the uPesy ESP32 Wroom Devkit board

In this example, a push button with an external pulldown resistor connected to pin 33 is used:

Wiring diagram of a pull-down button

Wake up ESP32 with a button

Wiring diagram of a pull-down button

Wake up the ESP32 via a button (breadboard version)

RTC_DATA_ATTR int bootCount = 0;

void setup(){
   Serial.begin(115200);

    ++bootCount;
    Serial.println("----------------------");
    Serial.println(String(bootCount)+ "th Boot ");

    //Displays the wake-up source
    print_wakeup_reason();

    //Configure GPIO33 as a wake-up source when the voltage is 3.3V
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,HIGH);

    //Rentre en mode Deep Sleep
    Serial.println("Goes into Deep Sleep mode");
    Serial.println("----------------------");
    esp_deep_sleep_start();
}

void loop(){}

void print_wakeup_reason(){
   esp_sleep_wakeup_cause_t wake_up_source;

   wake_up_source = esp_sleep_get_wakeup_cause();

   switch(wake_up_source){
      case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wake-up from external signal with RTC_IO"); break;
      case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wake-up from external signal with RTC_CNTL"); break;
      case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wake up caused by a timer"); break;
      case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wake up caused by a touchpad"); break;
      default : Serial.printf("Wake up not caused by Deep Sleep: %d\n",wake_up_source); break;
   }
}

In the serial monitor, we obtain :

ets Jun 8 2016 00:22:57

rst: 0x10 (RTCWDT_RTC_RESET), boot: 0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP: 0xee
clk_drv: 0x00, q_drv: 0x00, d_drv: 0x00, cs0_drv: 0x00, hd_drv: 0x00, wp_drv: 0x00
mode: DIO, clock div: 1
load: 0x3fff0018, len: 4
load: 0x3fff001c, len: 1216
ho 0 tail 12 room 4
load: 0x40078000, len: 9720
ho 0 tail 12 room 4
load: 0x40080400, len: 6352
entry 0x400806b8
----------------------
1th Boot
Wake up not caused by Deep Sleep: 0
Goes into Deep Sleep mode
----------------------
ets Jun 8 2016 00:22:57

rst: 0x5 (DEEPSLEEP_RESET), boot: 0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP: 0xee
clk_drv: 0x00, q_drv: 0x00, d_drv: 0x00, cs0_drv: 0x00, hd_drv: 0x00, wp_drv: 0x00
mode: DIO, clock div: 1
load: 0x3fff0018, len: 4
load: 0x3fff001c, len: 1216
ho 0 tail 12 room 4
load: 0x40078000, len: 9720
ho 0 tail 12 room 4
load: 0x40080400, len: 6352
entry 0x400806b8
----------------------
2th Boot
Wake-up from external signal with RTC_IO
Goes into Deep Sleep mode
-----------------

Erasing RAM

When the Deep Sleep mode is activated, the CPU and the RAM are not powered anymore. This implies that when the ESP32 wakes up from Deep Sleep, all the variables contained in the RAM are erased. Fortunately, an 8 KB RTC RAM remains on during Deep Sleep. To store variables in this memory, you must add the attribute RTC_DATA_ATTR .

For example, the variable that stores the number of ESP32 restarts in the example is stored in this memory.

RTC_DATA_ATTR int bootCount = 0;

We use cookies to make your visit to the site as pleasant as possible. Privacy Policy