ESP32/Power/75. Battery and power budget
Your chip
Your language
Power · 75 of 81

Battery and power budget

The battery is rarely the problem. The regulator between it and the board is - a linear one throws away a third of the pack as heat, and a dev board draws milliamps while the chip sleeps at ten microamps.

/esp32/battery-and-power-budget · arduino · S3

What the regulator costs

18650 Li-ion → AMS1117 (on most dev boards)
11% wasted
Pack
Regulator
Average current your project needs20 mA
Taken from the pack
22 mA
Runtime
5 d
Usable to
4.1 V
This regulator needs 4.4 V in, and the pack drops below that while it still has charge left. The board browns out and resets while the battery meter says there is capacity — the most confusing battery failure there is. A low-dropout part, or a buck-boost, reaches the bottom of the discharge curve instead of abandoning it.

Two numbers, not one

Average current decides how long the battery lasts. Peak current decides whether the board resets. They are hundreds of times apart on this chip — 10 µA asleep, 350 mA in a transmit burst — and a design that only considers the average browns out.

The peak is handled with capacitance: 100 µF close to the module, plus whatever the board already has.

A checklist for a battery build

  • A cell whose voltage stays above the regulator's dropout for most of its life.
  • A low-dropout or buck regulator, not the AMS1117 on the dev board.
  • A bare module, or a dev board with the power LED removed.
  • A divider for battery sense that is switched, not permanent.
  • Everything else on the board switched off in sleep — sensors included.
On your S3
ChipXtensa LX7 · 2 × 240 MHz
Board settingESP32S3 Dev Module
Default I2CSDA 8 · SCL 9
Watch out forThe port vanishes after upload

The code

Two resistors and an ADC1 pin. The MOSFET is what makes it a battery design rather than a demonstration - a permanently connected divider drains the pack for years.

battery_monitor.ino
const int BATT = 35;        // ADC1, so Wi-Fi does not disturb it
const int ENABLE = 25;      // gate of a MOSFET in series with the divider

float readBattery() {
  digitalWrite(ENABLE, HIGH);
  delay(10);                              // let it settle
  long sum = 0;
  for (int i = 0; i < 16; i++) sum += analogReadMilliVolts(BATT);
  digitalWrite(ENABLE, LOW);              // stop draining the pack
  return (sum / 16) * 2.0 / 1000.0;       // two equal resistors = /2
}

void setup() {
  Serial.begin(115200);
  pinMode(ENABLE, OUTPUT);
  analogSetPinAttenuation(BATT, ADC_11db);
  Serial.printf("%.2f V\n", readBattery());
}

void loop() {}

Use an ADC1 pin. On the classic ESP32 the ADC2 pins stop working the moment Wi-Fi starts, and a battery monitor that reads zero once connected is a confusing bug.

When it does not work

The board resets when Wi-Fi transmits

The rail sags under a 350 mA burst. A 100 µF capacitor across 3.3 V close to the module fixes most of these, and a thicker cable or a better regulator fixes the rest.

The battery meter says half full and the board is dead

The regulator ran out of headroom. An AMS1117 needs about 4.4 V in to give 3.3 V out, so it abandons a lithium cell at half charge. Use a low-dropout part or a buck-boost.

Sleep current is milliamps on a battery-powered board

The dev board, not the chip. Power LED, USB-serial chip, regulator quiescent current. For a real battery product, use a bare module and your own regulator.

The reading drifts as the battery drains

You are measuring against a reference derived from the supply. analogReadMilliVolts uses the internal reference and is far more stable.

Where this goes next

Every number on this page is a guess until you measure it, and measuring microamps is harder than it looks.

Measuring current draw

Edit this page — content/esp32/battery-and-power-budget.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.

Browse ESP32 on the forum