How to wake ESP32 from deep sleep with timer, touch, or GPIO
ESP32 deep sleep only wakes from certain sources. The key detail: wake pins must be RTC-capable (not every GPIO works).
Timer wake (easiest, always works)
#include <esp_sleep.h>
void setup() {
Serial.begin(115200);
delay(200);
// Wake in 10 seconds
esp_sleep_enable_timer_wakeup(10ULL * 1000000ULL);
Serial.println("Sleeping for 10 seconds...");
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}GPIO wake (EXT0 and EXT1)
There are two common GPIO wake modes:
- EXT0: one RTC pin, wake on a specific level (HIGH or LOW)
- EXT1: a mask of RTC pins, wake when ANY or ALL hit a level
EXT0 example (single pin)
This wakes when the pin goes LOW (great for a button to GND). Pick an RTC-capable pin for your board.
#include <esp_sleep.h>
// Example: wake on GPIO33 going LOW (RTC-capable on classic ESP32)
static const gpio_num_t wakePin = GPIO_NUM_33;
void setup() {
Serial.begin(115200);
delay(200);
pinMode((int)wakePin, INPUT_PULLUP); // button to GND
esp_sleep_enable_ext0_wakeup(wakePin, 0); // 0 = LOW, 1 = HIGH
Serial.println("Sleeping. Press button to wake.");
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}EXT1 example (multiple pins)
EXT1 uses a bitmask. This example wakes when ANY of the selected pins is LOW.
#include <esp_sleep.h>
void setup() {
Serial.begin(115200);
delay(200);
// Choose RTC-capable pins on your board
const uint64_t mask =
(1ULL << GPIO_NUM_32) |
(1ULL << GPIO_NUM_33);
pinMode(GPIO_NUM_32, INPUT_PULLUP);
pinMode(GPIO_NUM_33, INPUT_PULLUP);
esp_sleep_enable_ext1_wakeup(mask, ESP_EXT1_WAKEUP_ANY_LOW);
Serial.println("Sleeping. Pull GPIO32 or GPIO33 LOW to wake.");
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}Touch wake (nice for “tap to wake” builds)
Touch wake also requires compatible touch pins. Touch thresholds vary by board and wiring, so expect to tune it.
#include <esp_sleep.h>
// Example touch pad: T0 is usually GPIO4 on classic ESP32
static const touch_pad_t touchPad = TOUCH_PAD_NUM0;
void setup() {
Serial.begin(115200);
delay(200);
// Set a wake threshold. You may need to tune this.
touchSleepWakeUpEnable(touchPad, 40);
Serial.println("Sleeping. Touch the pad to wake.");
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}Know why you woke up
This helps when debugging “it wakes instantly” vs “it never wakes.”
#include <esp_sleep.h>
void setup() {
Serial.begin(115200);
delay(200);
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
Serial.print("Wake cause: ");
Serial.println((int)cause);
}
void loop() {}Timer wake is the easiest baseline. For GPIO wake, use RTC-capable pins and choose EXT0 (one pin) or EXT1 (multiple pins). If wake is flaky, add pullups/pulldowns and print the wake reason.
Related: Deep sleep basics · ESP32 not waking up · ESP32 safe pins