This example reads a DS18B20 temperature sensor and publishes the value via MQTT, then enters deep sleep for 5 minutes. It targets a 3.7 V LiPo battery.
| Phase | Duration | Current | Energy |
|---|---|---|---|
| Boot + WiFi connect | ~800 ms | 120 mA | 96 mJ |
| Read sensor | 200 ms | 20 mA | 4 mJ |
| MQTT publish | 300 ms | 80 mA | 24 mJ |
| Deep sleep | ~298.7 s | 0.05 mA | 14.9 mJ |
| Total per cycle | 300 s | 138.9 mJ |
Average current: 138.9 mJ / (300 s × 3.7 V) ≈ 0.125 mA → battery life ~666 days.
The full sketch is in examples/temp_sensor_mqtt/temp_sensor_mqtt.ino. Key patterns:
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR float lastTemp = 0.0f;
void setup() {
bootCount++;
// Configure static IP
WiFi.config(STATIC_IP, GATEWAY, SUBNET);
WiFi.begin(SSID, PASSWORD);
// Read sensor while WiFi connects (parallel)
float temp = readDS18B20();
// Wait for WiFi (with timeout)
waitForWiFi(5000);
// Publish and disconnect
publishMQTT(temp);
WiFi.disconnect(true);
lastTemp = temp;
esp_sleep_enable_timer_wakeup(5ULL * 60 * 1000000);
esp_deep_sleep_start();
}
Reading the sensor while WiFi is connecting saves ~200 ms of radio-on time.
This example logs analog sensor readings to EEPROM every 10 minutes and dumps the log over serial on button press. It runs on two AA batteries (3 V).
The AVR watchdog can only time 8 seconds maximum. For longer intervals, count watchdog wakes:
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <EEPROM.h>
volatile int wdtCount = 0;
const int TARGET_WAKES = 75; // 75 × 8s ≈ 10 minutes
ISR(WDT_vect) {
wdtCount++;
}
void enableWDT8s() {
MCUSR &= ~(1 << WDRF);
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // 8s
}
void sleepNWDT(int n) {
wdtCount = 0;
enableWDT8s();
while (wdtCount < n) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
wdt_disable();
}
Address 0: uint8_t logCount
Address 1..N: each entry = 2 bytes (uint16_t ADC value)
const int EEPROM_BASE = 1;
const int MAX_ENTRIES = 50;
void logReading(uint16_t val) {
uint8_t count = EEPROM.read(0);
if (count >= MAX_ENTRIES) count = 0; // ring buffer
EEPROM.put(EEPROM_BASE + count * 2, val);
EEPROM.update(0, count + 1);
}
| Phase | Duration | Current |
|---|---|---|
| Active (read + log) | ~50 ms | 8 mA |
| Power-down sleep | ~599.95 s | 0.0003 mA |
| Average | 600 s cycle | ~0.67 µA active portion + 0.3 µA sleep ≈ 1 µA |
Two AA batteries (2500 mAh) would last: 2500 mAh / 0.001 mA = 2,500,000 hours — effectively limited by battery self-discharge (~5 years).
A Python script that monitors ESP32 heap usage over serial, useful for detecting memory leaks during development.
The full script is in examples/heap_monitor.py.
import serial, re, time
PORT = "/dev/ttyUSB0"
BAUD = 115200
with serial.Serial(PORT, BAUD, timeout=1) as ser:
print("Monitoring heap... Ctrl+C to stop")
while True:
line = ser.readline().decode("utf-8", errors="ignore").strip()
m = re.search(r"Free heap: (\d+)", line)
if m:
ts = time.strftime("%H:%M:%S")
print(f"{ts} free={m.group(1)} bytes")
Add to your ESP32 sketch:
void loop() {
doWork();
Serial.printf("Free heap: %u bytes\n", ESP.getFreeHeap());
delay(1000);
}
If free heap decreases monotonically, you have a memory leak (likely a String not freed, a task not deleted, or a missing f.close()).
| Platform | Mode | Current | Wake Latency |
|---|---|---|---|
| ATmega328P | Active (16 MHz) | 12 mA | — |
| ATmega328P | Idle | 3 mA | <1 µs |
| ATmega328P | Power-down | 0.1 µA | ~65 µs |
| ESP32 | Active + WiFi TX | 240 mA | — |
| ESP32 | Active, no radio | 20–80 mA | — |
| ESP32 | Modem sleep | 3–20 mA | ~1 ms |
| ESP32 | Light sleep | 0.8 mA | ~1 ms |
| ESP32 | Deep sleep | 10–150 µA | ~350 ms |
| ESP32 | Deep sleep + ULP | ~100 µA | ~350 ms |
| Library | Platform | Purpose |
|---|---|---|
avr/sleep.h |
AVR | Sleep modes |
avr/power.h |
AVR | Peripheral power control |
avr/wdt.h |
AVR | Watchdog timer |
esp_sleep.h |
ESP32 | All sleep APIs |
Preferences.h |
ESP32 | NVS key-value store |
LittleFS.h |
ESP32 | Filesystem |
esp32-hal-cpu.h |
ESP32 | CPU frequency scaling |
| Previous: Power Optimization | Home |