Skip to content
IoT

ESP32 Deep Sleep Modes and Wake Sources: A Power Optimization Guide

30 June 20267 min read0 views
ESP32 Deep Sleep Modes and Wake Sources: A Power Optimization Guide
Reduce ESP32 current consumption from 240mA active to under 15μA using deep sleep, RTC memory, and timer or GPIO wake sources.

The Power Problem in Battery IoT

An ESP32 running at full CPU speed with Wi-Fi active consumes ~240mA. A 3000mAh lithium-ion battery at this rate lasts roughly 12 hours. For a solar-powered soil moisture sensor or a wildlife camera trap that must run for months unattended, this is completely impractical. Deep Sleep drops current consumption to 10-15μA, extending battery life by up to 1000×.

Understanding ESP32 Power States

| Mode | CPU | Wi-Fi/BLE | RTC | Current | | :--- | :--- | :--- | :--- | :--- | | Active | On | On | On | ~240 mA | | Modem Sleep | On | Off | On | ~15 mA | | Light Sleep | Paused | Off | On | ~0.8 mA | | Deep Sleep | Off | Off | On | ~10–15 μA |

Entering Deep Sleep with Timer Wake

This is the most common pattern: take a reading, transmit it, then sleep for a fixed interval.

#include <esp_sleep.h>

#define SLEEP_DURATION_SECONDS 300  // Wake every 5 minutes

void setup() {
  // Do sensor reads and upload here...
  readAndUploadSensorData();

  // Configure timer wake source
  esp_sleep_enable_timer_wakeup(SLEEP_DURATION_SECONDS * 1000000ULL);

  // Enter deep sleep immediately
  esp_deep_sleep_start();
}

void loop() {
  // Never runs — device wakes as a fresh boot after sleep
}

Persisting State Across Sleep Cycles with RTC Memory

Normal SRAM is cleared during deep sleep. RTC memory (8KB on ESP32) survives sleep cycles:

RTC_DATA_ATTR int bootCount = 0;  // Persists across resets
RTC_DATA_ATTR float lastTemperature = 0.0f;

void setup() {
  bootCount++;
  Serial.printf("Boot number: %d\n", bootCount);
  // bootCount persists even after deep sleep
}

GPIO Wake Source (External Interrupt)

For event-driven devices (door sensors, motion detectors), wake on pin state change instead of a timer:

// Wake when GPIO 33 goes HIGH (e.g. PIR motion sensor output)
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
esp_deep_sleep_start();

Battery Life Estimation

For a sensor that wakes every 5 minutes, spends 3 seconds active (Wi-Fi connect + transmit), then deep sleeps:

  • Active: 3s × 240mA = 0.2mAh
  • Sleep: 297s × 0.015mA = 0.0012mAh
  • Per cycle: ~0.2mAh
  • Daily: 0.2 × 288 cycles = 57.6mAh
  • 3000mAh battery → ~52 days runtime

Designing power-efficient IoT hardware? Let's talk →

Frequently Asked Questions

Q:Does Wi-Fi reconnect after deep sleep take extra time?

Yes, full Wi-Fi association takes 1-3 seconds. To reduce this, store the channel and BSSID in RTC memory and use wifi_config_t fast-connect to skip the channel scan.

Q:What is the maximum RTC memory size on ESP32?

The ESP32 provides 8KB of RTC SLOW memory (for data) and 8KB of RTC FAST memory (for code). Data marked RTC_DATA_ATTR goes into slow memory and persists across deep sleep.

Working on something similar?

Let's collaborate to design custom PCB schematics, write deterministic FreeRTOS threads, or configure secure Next.js databases.

Let's talk →