Measuring current draw
Every battery estimate is a guess until you measure it, and measuring an ESP32 is genuinely hard - the interesting range spans ten thousand to one, and a multimeter on the microamp range browns the board out on every transmit.
What each instrument can see
Measure the time, not the current
If you own nothing but a multimeter, this still works: put a scope or even an LED on a marker pin, and measure how long the board is awake. Awake time multiplied by a datasheet figure of roughly 120 mA gets you within twenty percent, and it points at the right thing to fix.
The three findings that always come out of this
- The awake time is longer than you think. Usually the Wi-Fi join.
- Something did not go to sleep. A sensor, a display backlight, a pull-up through a switched-off device.
- The dev board is the load. Between one and twenty milliamps, permanently, regardless of your code.
The code
A pin that goes high while the board is awake turns any oscilloscope into a timing marker. Awake time is the number that decides battery life, and this is the cheapest way to see it.
#include <esp_sleep.h>
const int MARK = 27; // put a scope probe here
void setup() {
pinMode(MARK, OUTPUT);
digitalWrite(MARK, HIGH); // awake starts now
Serial.begin(115200);
// ... connect, read, send ...
unsigned long awake = millis();
Serial.printf("awake %lu ms\n", awake);
Serial.flush();
digitalWrite(MARK, LOW); // awake ends here
esp_sleep_enable_timer_wakeup(60ULL * 1000000);
esp_deep_sleep_start();
}
void loop() {}Set the marker before anything else in setup and clear it immediately before sleeping. Everything between those two lines is what the battery is paying for.
Same marker. Printing the awake time as well means you get a number even without a scope, and a number you can watch improve as you optimise.
from machine import Pin
import machine, time
mark = Pin(27, Pin.OUT, value=1) # awake
t0 = time.ticks_ms()
# ... connect, read, send ...
print('awake', time.ticks_diff(time.ticks_ms(), t0), 'ms')
mark.value(0)
machine.deepsleep(60_000)The single biggest saving is usually the Wi-Fi reconnect. Caching the channel and BSSID in RTC memory turns a three-second join into well under one.
When it does not work
Burden voltage. On the microamp range a multimeter is a kilohm in series, and a 350 mA burst across that is more than the whole supply. Measure sleep and awake on different ranges, or use an instrument built for it.
It is averaging, and the two halves differ by four decades. An average tells you nothing about which half to fix.
You are measuring the dev board. LED, USB chip and regulator quiescent add up to milliamps. Measure the module alone.
They will - a Wi-Fi join takes a variable time. Measure twenty cycles and take the mean, and record the worst case too, because the worst case is what flattens a battery.
Power settled. The last chapter is the system underneath: two cores, crashes, audio, camera and screens.
Dual core tasks →Edit this page — content/esp32/measuring-current-draw.mdx
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.