ESP32 Deep Sleep Power Optimization for Always-On AI Agents
One of ESP-Claw’s key advantages is its low power consumption — just 0.5 watts when active. But what if you want to run your AI agent on a battery or solar panel? With the right sleep strategies, you can extend battery life from hours to weeks.
This guide covers everything from basic deep sleep to advanced wake-on-event patterns.
Understanding ESP32 Power States
The ESP32 has several power states, each with dramatically different current draw:
| State | ESP32-C3 Current | ESP32-S3 Current | Description |
|---|---|---|---|
| Active (Wi-Fi TX) | ~130mA | ~180mA | Full operation, transmitting data |
| Active (Wi-Fi RX) | ~95mA | ~120mA | Listening for data |
| Modem Sleep | ~15mA | ~20mA | CPU active, Wi-Fi radio off |
| Light Sleep | ~0.8mA | ~1.2mA | CPU paused, RAM retained, fast wake |
| Deep Sleep | ~5µA | ~7µA | Only RTC memory retained, slow wake |
| Hibernation | ~2.5µA | ~3µA | Minimal state, only RTC timer wake |
The difference between active and deep sleep is a factor of 25,000x. This is what makes battery-powered AI agents feasible.
Battery Life Calculator
With a common 1000mAh LiPo battery (3.7V):
| Strategy | Average Current | Battery Life |
|---|---|---|
| Always active (Wi-Fi on) | 130mA | ~7.7 hours |
| Active 10 sec/min, sleep rest | ~12mA | ~3.5 days |
| Active 10 sec/5 min, deep sleep | ~2.5mA | ~16.7 days |
| Active on motion only (PIR wake) | ~0.5mA avg | ~83 days |
| Deep sleep + RTC timer (hourly check) | ~0.05mA | ~2.3 years (theoretical) |
The key insight: an AI agent doesn’t need to be connected to Wi-Fi 100% of the time. If you’re primarily using Telegram or MQTT, the agent can sleep between interactions and wake periodically to check for messages.
Basic Deep Sleep Implementation
The simplest deep sleep pattern: sleep for a fixed duration, wake up, check for messages, respond, and go back to sleep.
#include "esp_sleep.h"#include "esp_wifi.h"
#define SLEEP_DURATION_US (5 * 60 * 1000000ULL) // 5 minutes
void app_main(void) { // Initialize hardware, connect Wi-Fi claw_agent_init(&config);
// Check for pending messages int messages = claw_check_messages();
if (messages > 0) { // Process all pending messages claw_process_pending();
// Stay awake for a bit to handle follow-up conversation vTaskDelay(pdMS_TO_TICKS(30000)); // 30 seconds }
// Disconnect Wi-Fi cleanly esp_wifi_disconnect(); esp_wifi_stop();
// Configure wake-up timer esp_sleep_enable_timer_wakeup(SLEEP_DURATION_US);
// Enter deep sleep esp_deep_sleep_start(); // Code after this line never executes}When the timer fires, the ESP32 reboots from scratch — app_main() runs again from the beginning. This is why deep sleep uses so little power: almost everything is powered off.
Wake-on-GPIO: Motion-Triggered Agent
A more intelligent approach: sleep until a PIR motion sensor detects someone, then wake up and be ready to interact.
#define PIR_GPIO GPIO_NUM_3#define BUTTON_GPIO GPIO_NUM_9
void configure_wake_sources(void) { // Wake on PIR motion (GPIO 3 goes high) esp_sleep_enable_ext0_wakeup(PIR_GPIO, 1); // 1 = wake on high
// Also wake on button press (GPIO 9 goes low) uint64_t button_mask = (1ULL << BUTTON_GPIO); esp_sleep_enable_ext1_wakeup(button_mask, ESP_EXT1_WAKEUP_ALL_LOW);
// Fallback: also wake every 30 minutes to check messages esp_sleep_enable_timer_wakeup(30 * 60 * 1000000ULL);}
void app_main(void) { esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
switch (cause) { case ESP_SLEEP_WAKEUP_EXT0: // PIR triggered — someone is nearby handle_motion_wake(); break; case ESP_SLEEP_WAKEUP_EXT1: // Button pressed — user wants to interact handle_button_wake(); break; case ESP_SLEEP_WAKEUP_TIMER: // Periodic check — look for pending messages handle_timer_wake(); break; default: // First boot or reset handle_initial_boot(); break; }
// Go back to sleep configure_wake_sources(); esp_deep_sleep_start();}This pattern gives you the best of both worlds: the agent is responsive when someone is present, and uses almost zero power when the room is empty.
Light Sleep: Faster Response at Higher Power
Deep sleep takes 300-500ms to wake (full reboot). If you need faster response times, use light sleep instead:
// Light sleep keeps RAM contents and wakes in ~1msesp_sleep_enable_timer_wakeup(100000); // 100msesp_light_sleep_start();// Execution continues here after wakeLight sleep uses ~0.8mA vs deep sleep’s ~5µA, but the agent wakes almost instantly and doesn’t need to reinitialize.
A practical pattern for light sleep:
- Connect to Wi-Fi
- Subscribe to MQTT topic
- Enter light sleep
- Wake periodically (every 100ms) to check for MQTT messages
- If a message arrives, process it and respond
- Go back to light sleep
This achieves ~1ms response latency while using only ~1mA average current.
Power Optimization Checklist
Beyond sleep modes, several other optimizations reduce power consumption:
Wi-Fi optimizations:
- Use static IP assignment instead of DHCP (saves ~2 seconds of connection time per wake)
- Store the Wi-Fi channel and BSSID in RTC memory to skip scanning on wake
- Use Wi-Fi power save mode (
esp_wifi_set_ps(WIFI_PS_MIN_MODEM)) - Reduce TX power if the router is nearby:
esp_wifi_set_max_tx_power(40)(10dBm instead of 20dBm)
Peripheral management:
- Power off sensors when not reading: control VCC via a GPIO pin through a MOSFET
- Disable Bluetooth if not used: saves ~10mA
- Turn off the onboard LED
- Use I2C clock stretching to let sensors sleep between reads
Firmware optimizations:
- Reduce log level in production:
ESP_LOG_NONEsaves CPU cycles and power - Use
menuconfigto disable unused components (CAN, Ethernet, etc.) - Optimize compiler flags:
-Osfor size (less flash reads = less power)
Solar-Powered Setup
With proper sleep management, an ESP-Claw agent can run indefinitely on solar power.
Hardware needed:
- 5V/1W mini solar panel (~$3)
- TP4056 charge controller with battery protection (~$0.50)
- 1000mAh LiPo battery (~$3)
- ESP32-C3 SuperMini
Power budget:
- Solar panel output: ~200mA for 4-5 hours/day = ~800-1000mAh/day
- Agent consumption (deep sleep + hourly check): ~50µA average = ~1.2mAh/day
- Even on cloudy days with 10% solar efficiency, the panel produces ~80-100mAh — vastly more than needed
The solar setup provides essentially infinite runtime. The battery serves as a buffer for nighttime and cloudy periods.
Measuring Power Consumption
To verify your optimizations are working, measure actual current draw:
Budget option (~$15): Use a USB power meter (like the YZXstudio ZY1280) between your power supply and the board. It shows real-time current and accumulated energy.
Precise option (~$30): Use a Nordic Power Profiler Kit II or a CurrentRanger. These can measure from microamps to hundreds of milliamps with high time resolution, letting you see exactly what happens during wake/sleep transitions.
Software estimation: ESP-IDF includes esp_pm_dump_locks() to see what’s preventing power saving, and esp_clk_tree_get_freq() to verify clock speeds are reduced during sleep.
Real-World Example: Mailbox Notifier
Here’s a complete real-world application combining deep sleep with AI intelligence:
A motion sensor in the mailbox detects when mail arrives. The ESP32-C3 wakes, connects to Wi-Fi, and sends a Telegram message: “You’ve got mail! Based on the time (2:15 PM), this is likely the regular postal delivery.”
Power consumption: ~5µA (waiting) + ~130mA for ~5 seconds (sending message) = average of ~15µA. A 1000mAh battery lasts over 7 years in theory (battery self-discharge becomes the limiting factor).
The AI adds value over a simple notification: it can learn patterns (“mail usually arrives between 2-3 PM on weekdays”), detect anomalies (“someone opened the mailbox at 11 PM — that’s unusual”), and correlate with other data (“you received a package notification from Amazon today, this might be it”).
Read Next
- ESP32-C3 vs ESP32-S3 for AI Projects — Compare power consumption between chips
- How to Build a $5 AI Assistant — The basic setup before optimizing power
- Schematics & Design — Solar power circuit details
- OTA Updates — Keep your sleeping device updated
- Building from Source — Compile with power optimization flags