Deep Sleep Power Optimization
Esta página aún no está disponible en tu idioma.
Deep Sleep Power Optimization
Overview
Section titled “Overview”This section covers ESP32 deep sleep mode configuration and optimization for achieving ultra-low power consumption in battery-powered IoT button applications. By the end of this section, you will be able to:
- Understand ESP32 power modes and their current consumption
- Configure deep sleep with wake-on-button-press
- Measure and optimize sleep current
- Explain the sleep/wake cycle for button applications
Prerequisites
Section titled “Prerequisites”Before starting this section, please ensure:
- Completed 04-04. Button Circuit Design
- Basic understanding of ESP32 power management features
- Access to a multimeter for current measurements
Key Concepts
Section titled “Key Concepts”ESP32 Power Modes
Section titled “ESP32 Power Modes”The ESP32 offers multiple power modes with significantly different current consumption:
| Mode | Current (ESP32-C3) | Description | Use Case |
|---|---|---|---|
| Active (WiFi on) | ~60-80 mA | CPU running, WiFi connected | Normal operation |
| Active (WiFi off) | ~15-25 mA | CPU running, no radio | Local processing |
| Modem Sleep | ~3-5 mA | CPU running, WiFi idle | Brief pauses |
| Light Sleep | ~0.5-1 mA | CPU paused, can wake quickly | Short idle periods |
| Deep Sleep | ~5-10 µA | CPU off, RTC peripheral only | Extended idle |
| Hibernation | ~2.5 µA | RTC memory off, only RTC timer | Maximum savings |
For the IoT button, deep sleep is the key mode — the device spends nearly all its life in this state, waking only briefly to send a message when the button is pressed.
Deep Sleep Architecture
Section titled “Deep Sleep Architecture”In deep sleep mode:
- CPU is powered off
- Most RAM loses content (RTC slow memory retains data)
- WiFi/BT are powered off
- RTC peripherals remain active (GPIO, timer, ULP coprocessor)
- Wake-up sources remain monitored (GPIO, timer, touch sensor)
┌─────────────────────────────────────────────────────────┐│ Deep Sleep State ││ ││ ┌──────────────────┐ ┌──────────────────────────┐ ││ │ CPU (OFF) │ │ WiFi/BT (OFF) │ ││ └──────────────────┘ └──────────────────────────┘ ││ ││ ┌──────────────────┐ ┌──────────────────────────┐ ││ │ RTC Memory │ │ RTC Peripherals │ ││ │ (Retains data) │ │ (GPIO wake, Timer) │ ││ └──────────────────┘ └──────────────────────────┘ ││ ││ ┌──────────────────────────────────────────────────┐ ││ │ Main Memory (SRAM) — Content lost │ ││ └──────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────┘Wake-Up Sources for Button Application
Section titled “Wake-Up Sources for Button Application”| Wake-Up Source | Configuration | Button Applicability |
|---|---|---|
| EXT0 | RTC GPIO → level change | ✅ GPIO 2 → LOW wakes (button press) |
| EXT1 | Multiple RTC GPIOs → pattern | ⚠️ For multiple buttons |
| Timer | RTC timer → time elapsed | ✅ Periodic wake for status check |
| Touch | Capacitive touch sensor | ❌ Not needed for button |
| ULP | Ultra-low-power coprocessor | ❌ Overkill for simple button |
Implementation Steps
Section titled “Implementation Steps”Step 1: Configure Deep Sleep with GPIO Wake-Up
Section titled “Step 1: Configure Deep Sleep with GPIO Wake-Up”#include <esp_sleep.h>
// Pin definitionsconst int BUTTON_PIN = 2; // GPIO 2 for button (wake source)const int LED_PIN = D10; // Built-in LED (GPIO 10 on XIAO)
void setup() { Serial.begin(115200); delay(100); // Allow serial to initialize
// Check wake-up reason esp_sleep_wakeup_cause_t wake_reason = esp_sleep_get_wakeup_cause();
switch (wake_reason) { case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Woke by button press"); break; case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Woke by timer (should not happen in button mode)"); break; default: Serial.println("First power-on or unknown wake source"); break; }
// Brief LED indication pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); delay(200); digitalWrite(LED_PIN, LOW);
// Execute button action performButtonAction();
// Go back to sleep Serial.println("Going to deep sleep..."); Serial.flush(); delay(100); // Allow serial output to complete
// Configure wake source esp_sleep_enable_ext0_wakeup((gpio_num_t)BUTTON_PIN, 0); // LOW = pressed
// Enter deep sleep esp_deep_sleep_start();}
void loop() { // Never reaches here}
void performButtonAction() { // Connect to WiFi and send MQTT message // This function will be detailed in sections 04-07 and 04-08 Serial.println("Button action executed");}Step 2: Configure RTC GPIO for Wake-Up
Section titled “Step 2: Configure RTC GPIO for Wake-Up”Not all GPIOs can wake the ESP32 from deep sleep. Compatible RTC GPIOs on XIAO ESP32-C3:
| GPIO | RTC Wake Compatible | Recommended For |
|---|---|---|
| GPIO 0 | Yes | BOOT button (not recommended) |
| GPIO 1 | Yes | Button |
| GPIO 2 | Yes | Button (recommended) |
| GPIO 3 | Yes | Button |
| GPIO 4 | Yes | Status LED |
| GPIO 5 | Yes | Status LED |
Step 3: Current Measurement Verification
Section titled “Step 3: Current Measurement Verification”To verify deep sleep current:
void setup() { // ... normal setup ...
// Measure and report before sleeping Serial.println("--- Power Report ---"); Serial.print("Active current: ~60-80 mA (WiFi on)\n"); Serial.print("Deep sleep current target: < 10 µA\n"); Serial.println("--------------------");
delay(50); esp_deep_sleep_start();}Measurement method:
- Set multimeter to µA range
- Disconnect power
- Connect multimeter in series between battery + and XIAO VIN
- Press button to wake; observe current during active period
- Wait for deep sleep; read µA value on multimeter
Expected measurement sequence:Time 0s: Wake → 60-80 mA (WiFi connect + MQTT publish)Time 3-5s: Action complete → preparing sleepTime 5s+: Deep sleep → ~5 µAPower Optimization Techniques
Section titled “Power Optimization Techniques”1. Disable Unused Peripherals
Section titled “1. Disable Unused Peripherals”void maximizePowerSaving() { // Disable WiFi before sleep (if not needed for next wake) WiFi.disconnect(true); WiFi.mode(WIFI_OFF);}2. Reduce Active Time
Section titled “2. Reduce Active Time”The most impactful optimization is minimizing the time spent in active mode:
// Fast path — minimize delays in active modevoid optimizedButtonAction() { unsigned long startTime = millis();
connectWiFi(); // ~1-3 seconds publishMQTT(); // ~500ms delay(10); // Allow MQTT to flush WiFi.disconnect(true);
Serial.print("Active time: "); Serial.print(millis() - startTime); Serial.println(" ms");
// Immediate deep sleep — no unnecessary delays}3. Use GPIO Pull-Down in Sleep
Section titled “3. Use GPIO Pull-Down in Sleep”For minimum sleep current, configure the button pin to avoid floating:
- Internal pull-up is sufficient for most cases
- For extremely low leakage, add a 10kΩ external pull-up resistor
4. Voltage Regulator Quiescent Current
Section titled “4. Voltage Regulator Quiescent Current”The XIAO’s onboard regulator has a quiescent current of approximately 2-3 µA. This is included in the total sleep current measurement and cannot be eliminated.
Verification
Section titled “Verification”- Deep sleep current measures < 10 µA
- Button press reliably wakes the device
- Active time is minimized (< 5 seconds per press)
- Device returns to deep sleep after action
- No spontaneous wake-ups without button press
Troubleshooting
Section titled “Troubleshooting”Issue 1: Higher Than Expected Sleep Current
Section titled “Issue 1: Higher Than Expected Sleep Current”Symptom: Sleep current > 50 µA
Possible Causes:
- GPIO floating (not configured as INPUT_PULLUP or OUTPUT)
- Serial monitoring enabled (some boards keep USB active)
- External components drawing current
- Capacitors leaking
Solution:
// Check all GPIOs are properly configured before sleepgpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);gpio_set_level(GPIO_NUM_4, 0); // Set LOW to minimize leakage
gpio_set_direction(GPIO_NUM_5, GPIO_MODE_OUTPUT);gpio_set_level(GPIO_NUM_5, 0);Issue 2: Device Does Not Wake
Section titled “Issue 2: Device Does Not Wake”Symptom: Device in deep sleep, button press does nothing
Possible Causes:
- Wrong GPIO number for wake source
- Button connected to non-RTC GPIO
- Level configuration reversed (waking on HIGH instead of LOW)
Solution: Verify GPIO is in RTC wake range and test with:
// Temporarily test with timer wake-up insteadesp_sleep_enable_timer_wakeup(10 * 1000000); // Wake every 10 secondsBest Practices
Section titled “Best Practices”- ✅ Minimize active time — connect WiFi, publish MQTT, sleep immediately
- ✅ Disconnect WiFi before entering deep sleep
- ✅ Use RTC GPIO pins for wake sources
- ✅ Add serial flush before sleep to ensure complete output
- ❌ Do not use
delay()in setup unless necessary - ❌ Avoid leaving GPIO pins unconfigured
Summary
Section titled “Summary”- Deep sleep reduces current to ~5 µA — the key to 100+ day battery life
- GPIO EXT0 wake-up allows the button press to wake the ESP32 instantly
- Minimizing active time is the most critical optimization
- Regular current measurement verifies power optimization is working
- All peripherals should be disabled before entering deep sleep
References
Section titled “References”Target Audience: Alibaba.com IoT Pre-sales Engineers
Status: ✅ Completed
We provide ESP32 ODM design-to-manufacturing services. From prototype to production — the team behind this tutorial can build it with you.
Talk to us →