- esp32
- deep sleep
- rtc gpio
- embedded systems
- low power
ESP32 Deep Sleep Wakeup: Sources and Pin Limits

An ESP32 that wakes from deep sleep does not continue from the instruction that put it to sleep. It powers down most of the chip, waits for a small always-on section to detect a condition, then boots the application again. The hard part is choosing a wake source that exists on the exact chip and pin you built around.
What ESP32 deep sleep actually powers down
Deep sleep is a power-domain decision, not a low-speed version of normal execution. The main digital logic, CPUs, most RAM, and ordinary GPIO control are shut down or disconnected. The RTC controller, RTC slow-clock source, selected RTC memory, and the circuitry needed for the chosen wake source can remain powered.
That remaining circuitry watches time, a pin level, a touch measurement, or a program running in an available ultra-low-power coprocessor. When its condition is met, it asserts a wake event. The chip then goes through reset and boot, initializes clocks and peripherals, and starts the application from its entry point.
This is the key consequence: deep sleep wake is a reboot, not a return from esp_deep_sleep_start(). Code before sleep runs again unless the program records state in RTC memory, nonvolatile storage, or an external device. A boot counter in retained RTC memory can distinguish repeated wake cycles, but retained memory availability and behavior differ by chip and sleep configuration.
The RTC slow clock also matters. A timer wake is based on that clock, commonly an internal low-power oscillator or an external 32.768 kHz source where supported. The internal source trades hardware simplicity for drift with voltage and temperature. A wake scheduled for a rough interval is usually fine; a timed measurement or radio duty cycle may need calibration against a known reference.
The wake sources and their physical limits
The practical choice is to use the cheapest source that meets the timing and input requirements. A coprocessor is not an automatic improvement if a timer or one pin can solve the job.
| Wake source | Hardware kept active | Trigger tolerance | Common failure mode |
|---|---|---|---|
| RTC timer | RTC controller and slow clock | Clock drift sets the time error | Wake occurs earlier or later than expected as temperature and voltage change |
| External pin, ext0 | RTC logic and one RTC input | Level-sensitive; input must remain at the selected level | A button bounce, floating input, or wrong polarity causes immediate wake |
| External pins, ext1 | RTC logic and a mask of RTC inputs | Pin combination is evaluated using the selected logical mode | A non-RTC pin is included, or an unused input is left electrically undefined |
| Touch sensor | RTC touch circuitry and selected touch pads | Threshold changes with moisture, wiring, overlay, and noise | Threshold passes in the shop but fails after the enclosure or user interface changes |
| ULP or RTC coprocessor | RTC memory, RTC clock, and supported coprocessor | Depends on sensor sampling, clock drift, and program limits | The selected ESP32 variant or software release does not support the copied example |
A timer is the first choice for periodic sampling. It has no external wiring to disturb it and uses the least complicated application logic. Add a wake margin if the next action depends on a real-world deadline.
Use an external pin for a door contact, reed switch, pushbutton, comparator, or power-good signal when the signal can be held at a definite level. A pull-up or pull-down must remain effective during deep sleep. Internal pulls are not equivalent on every pin, and an external resistor is often easier to reason about once the board, cable, and enclosure are installed.
The ext0 form uses one RTC GPIO and a level condition. The ext1 form monitors a mask of RTC GPIOs and applies a logical condition such as any selected pin or all selected pins, depending on the target and the ESP-IDF API used. Do not infer the available logic from a code sample written for a different chip family.
Touch wake is useful for a concealed user interface, but it is a measurement problem rather than a digital switch. The pad, electrode, overlay, cable capacitance, humidity, and nearby grounded material all affect the reading. Calibrate the threshold after the mechanical parts are in their final positions, and provide hysteresis in the decision logic where the software supports it.
A ULP or RTC coprocessor can sample a sensor while the main CPU sleeps, which is useful when the wake decision requires more than a pin level. It costs design time, retained memory, and another clock-dependent behavior. If a comparator can produce a clean RTC GPIO signal, that external hardware is often the better engineering choice. Do not add a coprocessor to fix a problem that belongs in the signal conditioning.
RTC GPIO is a pin capability, not a GPIO number
Only RTC-capable pins can wake an ESP32 from deep sleep through an external GPIO wake source. A GPIO number that works for output, interrupts, or light sleep is not automatically usable for deep-sleep wake.
Common RTC GPIO sets include:
- Original ESP32: GPIO0, 2, 4, 12 through 15, 25 through 27, and 32 through 39.
- ESP32-S2 and ESP32-S3: RTC GPIOs are generally GPIO0 through GPIO21, subject to the specific datasheet and package exposure.
- ESP32-C3: RTC GPIOs are GPIO0 through GPIO5.
- ESP32-C6: RTC GPIOs are GPIO0 through GPIO7.
These lists describe chip capabilities, not what is physically available on a development board. A module can leave a pin unconnected, reserve it for flash or PSRAM, connect it to an onboard circuit, or expose it under a board-specific label. Check the target chip datasheet and the board schematic before assigning the wake input.
The original ESP32 has an additional trap: GPIO34 through GPIO39 are input-only and do not provide the usual internal pull-up or pull-down functions. If one of those pins is used for wake, the external circuit must establish a valid level. A floating input can look like a wake event, especially with a long wire near a switching load.
The same GPIO number can have different RTC status on another ESP32 family. This is why copied code can compile, flash, and then fail silently: the code may configure a normal GPIO successfully while the deep-sleep wake controller cannot see that pad. Use the target-specific pin capability definitions where available, then confirm the mapping in the datasheet.
Build the wake path before writing the sleep code
Start with the electrical state during sleep, not with the API call. For each wake input, document the level that means awake, the level that means asleep, the pull resistor that creates that state, and every other device connected to the net.
A useful check list is:
- Confirm the pin is RTC-capable on the exact silicon revision and board.
- Measure the pin level with the board powered and with the external switch in both states.
- Check whether the sensor or pull resistor remains powered during deep sleep.
- Add debounce for mechanical contacts; deep sleep does not remove contact bounce.
- Keep wake wires short or filtered where they leave the board.
- Confirm the selected wake level before calling the sleep function.
- Log the reset reason at boot so a timer wake is not confused with a brownout or watchdog reset.
- Test wake with the final enclosure, cable routing, and loads enabled.
For a button, a resistor and a small capacitor may reduce false triggers, but the capacitor also slows the edge. For a reed switch, inspect both the contact state and the magnetic arrangement. For a powered sensor, verify that its output does not become undefined before the ESP32 reaches sleep.
Software must also restore what deep sleep discarded. Initialize the display, buses, radio, and application state on every boot. Store only the small state that needs to cross the sleep boundary in RTC memory or another suitable store. If the device must resume a transaction exactly where it stopped, deep sleep is the wrong mental model; design an explicit checkpoint and recovery path.
Choosing the right API for the target
ESP-IDF has target-specific constraints and API changes across releases. The older external wake calls, such as esp_sleep_enable_ext0_wakeup() and esp_sleep_enable_ext1_wakeup(), are not a promise that every target exposes the same pins or the same ext1 behavior. Newer releases may add target-specific forms for configuring RTC GPIO wake. Read the API reference for the selected ESP-IDF version and target, then inspect the generated configuration rather than relying on a tutorial written for the original ESP32.
A reliable test sequence is:
- Print the reset reason and wakeup cause at boot.
- Configure one known RTC GPIO with a fixed external pull.
- Enable only that one wake source.
- Enter deep sleep and measure the pin at the chip.
- Change the input state, wake, and verify the reported cause.
- Repeat with the final firmware, power supply, cable, and enclosure.
For an esp32 deep sleep wakeup design, this test proves more than a successful compile. It checks the physical level, the RTC routing, the selected API, and the reset path together. If the result changes between an original ESP32 and an ESP32-C3, suspect the RTC GPIO map and wake API before suspecting the switch.
Frequently asked questions
Does ESP32 deep sleep resume where the code stopped?
No. A deep-sleep wake resets the application and starts execution from the beginning of the program. Retained RTC memory can carry selected variables across the reset, but peripherals and ordinary program state must be initialized again.
Can any ESP32 GPIO wake from deep sleep?
No. Only RTC-capable pins can wake the chip from deep sleep through an external GPIO source. The available RTC GPIOs differ between ESP32 variants, and a development board may expose only some of them.
Why does copied ext1 wake code compile but never wake?
The pin may not be an RTC GPIO on the target, the board may connect it to another circuit, the input may float during sleep, or the ext1 API and logic may differ in the ESP-IDF version or chip family. Check the target datasheet, board schematic, electrical level, and wake-cause log in that order.
The Boss Factory builds made-to-order ESP32 electronics and control software through Custom Electronics & Smart Systems and Software, Web & App Development; request a quote.
Related services
All services →Have a project in mind?
Tell us what you want built — we reply within 24–48 hours.