Deep Power Management Development with ESP32: Wake Source Configuration

The deep sleep mode of the ESP32 allows for ultra-low power consumption (in the microamp range) by configuring wake sources, making it suitable for IoT devices that require long standby times. Below are the methods for configuring wake sources in the ESP32 deep sleep mode along with code examples:

1. Types of Wake Sources

The ESP32 supports the following wake sources (which can be used individually or in combination):

  • Timer Wakeup (RTC Timer)
  • External GPIO Wakeup (EXT0/EXT1)
  • Touch Wakeup (Touch Pad)
  • ULP Coprocessor Wakeup
  • UART Wakeup (requires configuration for serial data reception)

2. Wake Source Configuration Methods

2.1 Timer Wakeup

Set the wakeup time using the RTC timer, with the unit in microseconds (maximum support for 584942 years).

#include "esp_sleep.h"

void setup() {
    // Set to wake up after 10 seconds (10 seconds = 10,000,000 microseconds)
    esp_sleep_enable_timer_wakeup(10 * 1000000);
    esp_deep_sleep_start(); // Enter deep sleep
}

void loop() {
    // Program restarts from setup() after deep sleep
}

2.2 External GPIO Wakeup (EXT0/EXT1)

  • EXT0 triggers wakeup from a single GPIO pin level change.
  • EXT1 triggers wakeup from multiple GPIO pins level change.
EXT0 Example (Single Pin Wakeup)
#include "esp_sleep.h"

void setup() {
    // Configure GPIO 33 to wake up on low level
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); // 0: low level wakeup
    esp_deep_sleep_start();
}

void loop() {}
EXT1 Example (Multiple Pins Combination Wakeup)
#include "esp_sleep.h"

void setup() {
    // Configure GPIO 25 and 26 to wake up on high level simultaneously
    uint64_t pin_mask = (1ULL << GPIO_NUM_25) | (1ULL << GPIO_NUM_26);
    esp_sleep_enable_ext1_wakeup(pin_mask, ESP_EXT1_WAKEUP_ALL_LOW); // All pins low level wakeup
    esp_deep_sleep_start();
}

void loop() {}

2.3 Touch Wakeup (Touch Pad)

Wake up by touching a specified pin (requires configuration of touch threshold).

#include "esp_sleep.h"
#include "driver/touch_pad.h"

void setup() {
    // Enable touch wakeup (e.g., touch GPIO 4)
    esp_sleep_enable_touchpad_wakeup();
    touch_pad_config(TOUCH_PAD_NUM_4, 50); // Configure touch threshold
    esp_deep_sleep_start();
}

void loop() {}

2.4 ULP Coprocessor Wakeup

The ULP coprocessor can run low-power programs, such as sensor sampling.

#include "esp_sleep.h"
#include "ulp.h"

void setup() {
    // Enable ULP wakeup
    esp_sleep_enable_ulp_wakeup();
    esp_deep_sleep_start();
}

void loop() {}

3. Getting Wakeup Reason

After waking up, you can determine the wake source using <span>esp_sleep_get_wakeup_cause()</span>:

#include "esp_sleep.h"
#include "Arduino.h"

RTC_DATA_ATTR int bootCount = 0; // RTC memory variable, retained after deep sleep

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

    // Configure wake source (example: timer wakeup)
    esp_sleep_enable_timer_wakeup(5 * 1000000); // Wake up after 5 seconds

    bootCount++;
    Serial.printf("Wakeup count: %d\n", bootCount);

    esp_deep_sleep_start();
}

void loop() {}

// Wakeup reason query (can be added in setup)
void print_wakeup_reason() {
    esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
    switch (cause) {
        case ESP_SLEEP_WAKEUP_TIMER:
            Serial.println("Wakeup reason: Timer");
            break;
        case ESP_SLEEP_WAKEUP_EXT0:
            Serial.println("Wakeup reason: EXT0 (Single Pin)");
            break;
        case ESP_SLEEP_WAKEUP_EXT1:
            Serial.println("Wakeup reason: EXT1 (Multiple Pins)");
            break;
        case ESP_SLEEP_WAKEUP_TOUCHPAD:
            Serial.println("Wakeup reason: Touch");
            break;
        default:
            Serial.println("Other wakeup reasons");
    }
}

4. Key Considerations

  1. RTC Memory:

  • Use the <span>RTC_DATA_ATTR</span> macro to declare variables, ensuring data retention after deep sleep.
  • Example:<span>RTC_DATA_ATTR int bootCount = 0;</span>
  • Behavior After Wakeup:

    • After waking from deep sleep, the program will restart from <span>setup()</span> (similar to a reboot).
    • You need to reconfigure the wake source in <span>setup()</span>.
  • Power Consumption Optimization:

    • Turn off unused peripherals (e.g., LEDs, sensors).
    • Select appropriate wakeup intervals (avoid frequent wakeups).

    5. Comprehensive Example: Multiple Wake Source Configuration

    #include "esp_sleep.h"
    #include "Arduino.h"
    
    void setup() {
        Serial.begin(115200);
        delay(1000);
    
        // Configure multiple wake sources (timer + external pin)
        esp_sleep_enable_timer_wakeup(10 * 1000000); // Wake up after 10 seconds
        esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); // GPIO33 low level wakeup
    
        Serial.println("Entering deep sleep...");
        esp_deep_sleep_start();
    }
    
    void loop() {
        // Restart from setup() after waking up
    }

    6. Applicable Scenarios

    • Timer Wakeup for periodic data collection (e.g., reporting sensor data every hour).
    • External GPIO Wakeup for button-triggered operations (e.g., remote control).
    • Touch Wakeup for gesture-controlled devices (e.g., smart wristbands).
    • ULP Wakeup for low-power sensor monitoring (e.g., ambient light detection).

    By properly configuring wake sources, the ESP32 can achieve ultra-low power consumption in deep sleep mode while meeting the wakeup needs of practical applications.

    ESP32 Development Board Three Days to Master Microcontrollers Arduino Development Board

    STM32 Development Board

    Leave a Comment