ESP32 Timer Wake Up from Deep Sleep Mode with Arduino IDE

This tutorial shows how to put the ESP32 into deep sleep mode and then wake it up with a timer after a predetermined period. With the Arduino IDE, the ESP32 will be programmed.

Writing a Deep Sleep Sketch

To put your ESP32 into deep sleep mode and then wake it up, you need to write a sketch.

  1. Configure the wake-up sources first. Configuring what will wake up the ESP32 is what this means. Use one wake-up source alone or mix many. We'll show you how to set a timer to wake you up in this post.
  2. During deep sleep, you get to choose which peripherals to keep on or shut down. However, by default, the ESP32 powers down any peripherals that are not in use with the wake-up source you provide.
  3. Finally, you use the esp_deep_sleep_start() function to put your ESP32 into deep sleep mode.

Timer Wake Up

The ESP32 may enter deep sleep mode and then wake up at predefined times. This functionality is very useful if you are running projects that require time stamping or daily tasks while using little electricity.

timer wake up

The ESP32 RTC controller has a timer that may be used to wake up the ESP32 after a predefined amount of time.

Enable Timer Wake Up

It is quite simple to enable the ESP32 to wake up after a predefined amount of time. To specify the sleep time in microseconds in the Arduino IDE, just use the following function:

esp_sleep_enable_timer_wakeup(time_in_us)

Code

The Arduino IDE will be used to program the ESP32. As a result, you need to make sure you install the ESP32 add-on. If you haven't previously, install the ESP32 add-on using one of the tutorials listed next:

Using a library sample as an example, let's see how deep sleep with a timer wake up works. Open the Arduino IDE, go to File > Examples > ESP32 > Deep Sleep, and then open the TimerWakeUp sketch.

/*
Simple Deep Sleep with Timer Wake Up
=====================================
ESP32 offers a deep sleep mode for effective power
saving as power is an important factor for IoT
applications. In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

This code displays the most basic deep sleep with
a timer to wake it up and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
LEDEdit PRO <support@lededitpro.com>
*/

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");

  /*
  Next we decide what all peripherals to shut down/keep on
  By default, ESP32 will automatically power down the peripherals
  not needed by the wakeup source, but if you want to be a poweruser
  this is for you. Read in detail at the API docs
  http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html
  Left the line commented as an example of how to configure peripherals.
  The line below turns off all RTC peripherals in deep sleep.
  */
  //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");

  /*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  delay(1000);
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}

Take a look at the code. What is powered off during deep sleep with a timer wake up is described in the first comment.

In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

The RTC controller, RTC peripherals, and RTC memory will all be powered on when you use the timer to wake up the parts.

Define the Sleep Time

The first two lines of code define the period during which the ESP32 will be asleep.

#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ 
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */

To allow you to set the sleep time in seconds in the TIME_TO_SLEEP variable, this example uses a conversion factor from microseconds to seconds. The example will, in this instance, put the ESP32 into deep sleep mode for 5 seconds.

Save Data on RTC Memories

You may save data on the RTC memory of the ESP32. The ESP32 features 8kB SRAM on the RTC component, which is referred to as RTC fast memory. During deep sleep, the data kept here is not erased. It is, however, erased when you press the reset button (the EN button on the ESP32 board).

To save data on the RTC memory, just add RTC_DATA_ATTR before a variable declaration. The following example saves the bootCount variable to the RTC memory. This variable will keep track of how many times the ESP32 has woken up from deep sleep.

RTC_DATA_ATTR int bootCount = 0;

Wake Up Reason

The code then defines the print_wakeup_reason() function, which prints the reason why the ESP32 was awakened from sleep.

void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason){
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

The setup()

You should put your code in the setup() method. The sketch never reaches the loop() function while in deep sleep. As a result, you need to write all of the sketches in the setup().

This example starts by initializing the serial communication at a baud rate of 115200.

Serial.begin(115200);

The bootCount variable is then increased by one with each reboot, and the increased number is printed on the serial monitor.

++bootCount;
Serial.println("Boot number: " + String(bootCount));

The code then runs the print_wakeup_reason() function, but you may use any function to perform the necessary operation. For example, you may wish to wake up your ESP32 once a day to read a sensor value.

Next, the code defines the wake up source by using the following function:

esp_sleep_enable_timer_wakeup(time_in_us)

This function accepts as an argument the time to sleep in microseconds, as we’ve seen previously.

In our case, we have the following:

esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

Then, after all the tasks are performed, the ESP32 goes to sleep by calling the following function:

esp_deep_sleep_start()

The loop()

Because the ESP32 will go to sleep before reaching this part of the code, the loop() section is empty. As a result, you need to write up all of your sketches in the setup().

Testing the Timer Wake Up

On your ESP32, upload the example sketch. Ensure that the right board and COM port are chosen.

Open the Serial Monitor at a baud rate of 115200.

serial monitor

The ESP32 wakes up every 5 seconds, prints a message on the serial monitor, and then goes back to deep sleep.

The bootCount variable increases each time the ESP32 wakes up. As shown in the figure below, it also prints the wake up reason.

timer wake up serial monitor

However, notice that pressing the EN button on the ESP32 board resets the boot count to 1.

Conclusion

We hope you find this tutorial useful. Instead of printing a message, you may now modify the example given and instruct your ESP32 to do any other action.

If you like ESP32, you may also like:

We hope you find this tutorial useful. Thanks for reading.

Oh hi there It’s nice to meet you.

Sign up to receive awesome content in your inbox, every month.

We don’t spam! Read our privacy policy for more info.

Leave a Reply

Your email address will not be published. Required fields are marked *

Developing IoT Projects with ESP32

Automate your home or business with inexpensive Wi-Fi devices