Skip to content

uPesy only delivers currently in France.

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

Save energy on ESP32 with Deep Sleep

The ESP32 has a power-saving mode called Deep Sleep which allows you to “put the ESP32 to sleep”. It’s a bit like putting a computer to sleep to save energy. The ESP32 can perform simple tasks during this mode and be woken up to perform more complex tasks.

What’s the point?

This power-saving mode is useful when the ESP32 is battery powered and the ESP32 “works” occasionally. (For example, reading a value from a sensor and sending it over Wi-Fi every 10 minutes). If the ESP32 is switched on 24 hours a day, the battery will be discharged very quickly. With Deep Sleep mode, the batteries will last much longer.

Deep Sleep mode put the ESP32 into a pristine state

Indeed, in Deep Sleep mode, the 2 CPUs of the ESP32 no longer work and it is the ULP (Ultra Low Processor) that takes over. It is a processor that consumes very little power and can perform specific actions. Flash and RAM are no longer powered either. Only RTC memory is still powered and can be used. Wi-Fi and Bluetooth are of course also disabled. Thanks to this RTC memory, you can always access peripherals, interrupts, timers and internal sensors.

Wake-up sources

After putting the ESP32 into Deep Sleep mode, there are several ways to wake it up:
  • Use an internal timer (stopwatch) to wake up the ESP32 at a chosen time (internal alarm clock)

  • Use capacitive touch sensors

  • Use RTC pins

Note

You can combine different wake-up sources.

Warning

It is also possible to activate Deep Sleep mode without having configured any wake-up sources. In this case, the ESP32 will be in Deep Sleep mode indefinitely until a manual reset (or by reflashing the board). We cannot therefore “brick” the ESP32 with Deep Sleep mode.

Use

When you want to use Deep Sleep mode, you have to think about:
  • Configure the ESP32 wake-up sources

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

  • Use the esp_deep_sleep_start() function to enter 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 source_reveil;

   source_reveil = esp_sleep_get_wakeup_cause();

   switch(source_reveil){
      case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Réveil causé par un signal externe avec RTC_IO"); break;
      case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Réveil causé par un signal externe avec RTC_CNTL"); break;
      case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Réveil causé par un timer"); break;
      case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Réveil causé par un touchpad"); break;
      default : Serial.printf("Réveil pas causé par le Deep Sleep: %d\n",source_reveil); break;
   }
}

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

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

   //Affiche la raison du réveil
   print_wakeup_reason();

   //Configuration du timer
   esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
   Serial.println("ESP32 réveillé dans " + String(TIME_TO_SLEEP) + " seconds");

   //Rentre en mode Deep Sleep
   Serial.println("Rentre en mode Deep Sleep");
   Serial.println("----------------------");
   delay(100);
   esp_deep_sleep_start();
   Serial.println("Ceci ne sera jamais affiché");
}

void loop(){
}

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

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

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
 ----------------------
 1st Boot
 Waking up not caused by Deep Sleep: 0
 ESP32 woken up in 5 seconds
 Enter 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
 ----------------------
 2nd Boot
 Wake up caused by a timer
 ESP32 woken up in 5 seconds
 Enter Deep Sleep mode
 ----------------------

Use a Touchpad as a wake-up call source

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

#define seuil 30 //Seuil de détection pour le capteur capacitif

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)+ "eme Boot ");

   //Affiche la source du reveil et le numéro du touchpad
   print_wakeup_reason();
   print_wakeup_touchpad();

   //Configuration d'une interruption pour le touchpad T0 (GPIO4)
   touchAttachInterrupt(T0, fonction_isr, seuil);

   //Active le réveil par les touchpads
   esp_sleep_enable_touchpad_wakeup();

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

void loop(){
}

void print_wakeup_reason(){
   esp_sleep_wakeup_cause_t source_reveil;

   source_reveil = esp_sleep_get_wakeup_cause();

   switch(source_reveil){
      case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Réveil causé par un signal externe avec RTC_IO"); break;
      case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Réveil causé par un signal externe avec RTC_CNTL"); break;
      case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Réveil causé par un timer"); break;
      case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Réveil causé par un touchpad"); break;
      default : Serial.printf("Réveil pas causé par le Deep Sleep: %d\n",source_reveil); break;
   }
}

void print_wakeup_touchpad(){
   touch_pad_t pin;
   touchPin = esp_sleep_get_touchpad_wakeup_status();
   switch(touchPin){
      case 0  : Serial.println("Fil touché au GPIO 4"); break;
      case 1  : Serial.println("Fil touché au GPIO 0"); break;
      case 2  : Serial.println("Fil touché au GPIO 2"); break;
      case 3  : Serial.println("Fil touché au GPIO 15"); break;
      case 4  : Serial.println("Fil touché au GPIO 13"); break;
      case 5  : Serial.println("Fil touché au GPIO 12"); break;
      case 6  : Serial.println("Fil touché au GPIO 14"); break;
      case 7  : Serial.println("Fil touché au GPIO 27"); break;
      case 8  : Serial.println("Fil touché au GPIO 33"); break;
      case 9  : Serial.println("Fil touché au GPIO 32"); break;
      default : Serial.println("Réveil pas causé les touchpads"); break;
   }
}

The print_wakeup_reason() function displays the wake-up source of the ESP32 and the print_wakeup_touchpad() function displays the number of the touchpad used. We add 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 Deep Sleep but by “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
 ----------------------
 1st Boot
 Waking up not caused by Deep Sleep: 0
 Alarm clock not caused the touchpads
 Enter 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
 ----------------------
 2nd Boot
 Waking up caused by a touchpad
 Wire affected at GPIO 4
 Enter Deep Sleep mode
 -------------

Use a GPIO pin as a wake-up source

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

Warning

You can only use the RTC_GPIO pins (light blue inset)

My beautiful legend0

Pinout of the uPesy ESP32 Wroom Devkit board

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

My beautiful legend0

Wake up ESP32 with a button

RTC_DATA_ATTR int bootCount = 0;

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

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

   //Affiche la source du reveil
      print_wakeup_reason();

   //Configure le GPIO33 comme source de réveil quand la tension vaut 3.3V
   esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,HIGH);

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

void loop(){}

void print_wakeup_reason(){
   esp_sleep_wakeup_cause_t source_reveil;

   source_reveil = esp_sleep_get_wakeup_cause();

   switch(source_reveil){
      case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Réveil causé par un signal externe avec RTC_IO"); break;
      case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Réveil causé par un signal externe avec RTC_CNTL"); break;
      case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Réveil causé par un timer"); break;
      case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Réveil causé par un touchpad"); break;
      default : Serial.printf("Réveil pas causé par le Deep Sleep: %d\n",source_reveil); break;
   }
}

We get in the serial monitor:

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
 ----------------------
 1st Boot
 Waking up not caused by Deep Sleep: 0
 Enter 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
 ----------------------
 2nd Boot
 Waking up caused by an external signal with RTC_IO
 Enter Deep Sleep mode
 -----------------

Erasing RAM

When Deep Sleep mode is activated, the CPU and RAM are no longer powered. This implies that when the ESP32 wakes up from Deep Sleep, all the variables contained in the RAM are erased. Luckily, there is 8KB RTC RAM that stays 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 examples 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