Battery

Deep sleep: months of battery life on an ESP32

Example code uses the Arduino core for ESP32

An ESP32 connected to WiFi draws tens to over a hundred mA on average, with transmit peaks above 300mA. That's not sustainable on a battery. The solution: sleep deeply most of the time, wake up only to measure and send, then go back to sleep.

Basic code

RTC_DATA_ATTR int bootCount = 0;   // survives deep sleep

void setup() {
  Serial.begin(115200);
  bootCount++;
  Serial.printf("Wake-up number %d\n", bootCount);

  // ... read sensors, send data ...

  esp_sleep_enable_timer_wakeup(10ULL * 60 * 1000000ULL);   // 10 minutes (µs)
  esp_deep_sleep_start();
}

void loop() {}

After deep sleep the chip restarts from setup(). Normal variables are lost; only RTC_DATA_ATTR variables are kept.

Waking up with a button (ext0/ext1)

// Wake when GPIO33 goes LOW (RTC GPIO pins only)
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0);

Only RTC pins can wake the chip (for example GPIO 0, 2, 4, 12–15, 25–27, 32–39 on the original ESP32). You can combine timer and button wake-up.

Real current draw depends on the board

The ESP32 chip needs only around ten µA in deep sleep, but on a DevKit the total is usually several mA because of:

To really save power, use a board designed for batteries (low-quiescent LDO, no LED), or build your own circuit around a bare ESP32 module and a low-quiescent LDO. Measure the current with a multimeter or a dedicated tool before trusting any estimate.

Tips to stay awake less

Quick battery life estimate

Average current = (awake current × awake time + sleep current × sleep time) / cycle. Example: awake 5 s at 120mA every 10 minutes, sleeping at 20µA, gives roughly 1mA average. A 2500mAh 18650 cell then lasts about 100 days in practice, before self-discharge and temperature losses. This is only an estimate, so measure the real device.

Watch out: reading battery voltage through a resistor divider draws current constantly. Use large resistors (for example 1MΩ + 1MΩ) with a small 100nF capacitor on the ADC, or use a MOSFET so the divider is only enabled during a measurement.

See a real application: ESP32 + BME280 weather station over MQTT.