Why a development board empties the battery
In deep sleep the ESP32 chip draws about 10 µA, the ESP32-C3 about 5 µA and the ESP32-S3 about 7 µA, according to Espressif (our ESP32 comparison has every chip). A development board adds parts around the chip that never sleep:
- The regulator. Many boards use an AMS1117, whose quiescent current is about 5 mA (up to 11 mA): five hundred times what an ESP32 draws in deep sleep.
- The power LED. It stays lit as long as the board has power. Its current depends on its resistor; our LED resistor calculator works it out.
- The USB-serial chip. On boards that feed it from the 3.3 V rail, it stays powered with or without a USB cable. The board’s schematic tells you.
- Pull-ups, dividers and sensors tied to the 3.3 V rail, drawing current day and night.
Together they add up quickly. The battery-life calculator’s “ESP32 DevKit as-is” preset (an AMS1117, plus an indicative 3 mA for the LED and the USB-serial chip) would empty a 3000 mAh 18650 cell in about 13 days at best, while the same cell runs the bare module of our worked example for about 13 months. See the DevKit case in the calculator. Even that is optimistic: an AMS1117 drops about 1 V, so on a Li-ion cell the 3.3 V rail sinks below the module’s 3.0 V minimum long before the cell is empty.
For a battery project, use a bare module on your own board, or a low-power board whose maker publishes a figure for the whole board. Seeed, for example, gives 44 µA in deep sleep for the XIAO ESP32C3 (see our XIAO ESP32C3 pinout). Removing a board’s LED and regulator works too, but then you supply the 3.3 V yourself.
Choosing the battery
An ESP32 module needs 3.0–3.6 V, and 3.6 V is also its absolute maximum. Few batteries stay inside that window from full to empty, which decides whether you need a regulator, and which kind.
- One Li-ion or LiPo cell (1S). The usual choice: plenty of energy, rechargeable, cheap. It goes from 4.2 V full down to about 3.0 V, so it needs a regulator, either an LDO (low-dropout linear regulator) or a buck-boost (next section). Use cells with a protection circuit or add one (see Safety).
- One LiFePO4 cell. It spends most of its discharge around 3.2–3.3 V, so it can feed the module directly, with no regulator and no quiescent current. A standard charge, though, ends at 3.65 V, above the module’s 3.6 V maximum: charge it to below 3.6 V. Below about 3.0 V, hold the module in reset with a supply supervisor (a reset IC) on EN, as Espressif’s schematic checklists recommend for supplies that rise slowly or are unstable, such as batteries and solar panels. The supervisor only stops the module: the cell still needs its own protection against over-discharge (a BMS or protection board). It stores less energy than Li-ion for the same size.
- Three AA cells. Fresh alkaline cells give about 4.5 V and their datasheet tests run down to 0.8 V per cell, 2.4 V in all; NiMH cells go from about 4.2 V freshly charged down to 2.7 V. Neither stays in the window, so use a buck-boost.
- Coin cells (CR2032). Not for the ESP32’s radio: Renata rates its CR2032 for 3 mA continuous, while Espressif asks for a supply that can deliver 500 mA. TI’s note on coin cells and peak current finds that a capacitor in parallel is the most effective way to help them through the short peaks of radios designed for them, and those peaks are still far below what an ESP32 draws.
- Lithium thionyl chloride (Li-SOCl₂). Very low self-discharge, so it suits sensors that wake rarely for years. But a Saft LS14500 (AA size) is rated for 50 mA continuous and 250 mA pulses, so Wi-Fi needs a capacitor to supply the peaks, which Saft itself says may be needed. After storage a passivation layer raises its resistance: in a test by Qoitech, a stored cell showed more than 100 Ω and its voltage dropped by up to 1.8 V on the first pulses. Its open-circuit voltage, 3.67 V, is also slightly above the module’s maximum.
Our battery comparison has the details of each chemistry, and the battery voltage chart turns a measured voltage into the charge left.
The regulator: low quiescent current, enough current for Wi-Fi
In deep sleep the regulator’s own quiescent current often matters more than the chip. During a Wi-Fi transmission it is the other way round: Espressif’s hardware design guidelines ask for a 3.3 V supply that delivers no less than 500 mA. A regulator for a battery node needs both.
| Regulator | Type | Quiescent current | Rated current | Wi-Fi peaks |
|---|---|---|---|---|
| AMS1117 | LDO | 5 mA | 900 mA | Yes, but it drains the battery |
| MCP1700 | LDO | 1.6 µA | 250 mA | No: below 500 mA |
| HT7333 | LDO | 4 µA | 250 mA | No: below 500 mA |
| TLV755P | LDO | 25 µA | 500 mA | Yes, only just |
| AP2112K | LDO | 55 µA | 600 mA | Yes |
| TPS63802 | Buck-boost | 11 µA | 2 A (3.3 V from 2.3 V) | Yes |
Typical quiescent current and rated output current from the datasheets, the same figures as in our regulator calculator.
The MCP1700 and HT7333 are popular for their tiny quiescent current, but at 250 mA they are rated for half of what Espressif asks. The TLV755P and AP2112K meet it for a few tens of microamps. The TLV755P does it with no margin, though: it is rated for exactly 500 mA, and at that current its dropout can reach 238 mV, so during Wi-Fi peaks it stops regulating once the cell is below about 3.54 V. For more headroom choose the AP2112K, rated for 600 mA, and with either one fit the bulk capacitor Espressif recommends (see below).
With a Li-ion cell, an LDO stops regulating when the cell falls to 3.3 V plus its dropout, and from then on passes the cell voltage minus the dropout. The module keeps working down to 3.0 V, and by our battery voltage chart a Li-ion cell resting at 3.6 V has only about 7% left (0–40% across the makers’ tables), so a good LDO uses most of the battery. Under Wi-Fi peaks the cell sags and the dropout grows, so the runtime ends a little sooner than the resting voltage suggests; at that point a supervisor on EN set to about 3.0 V, as Espressif recommends, keeps the module in reset while the supply is too low. A buck-boost such as the TPS63802 holds 3.3 V whether the battery is above or below that, and it is the right choice for three AA cells, which start above 3.6 V and end below 3.0 V.
Check a regulator against your battery (dropout, heat and quiescent current), here a TLV755P on a Li-ion cell.Open the regulator calculator
Capacitors: Espressif’s design guidelines recommend at least 10 µF at the main power entry and 0.1 µF close to the chip’s supply pins. With a battery that can’t deliver the peaks itself, such as a Li-SOCl₂ cell, a capacitor has to supply them.
Deep sleep in practice
In deep sleep the CPUs, most of the RAM and the digital peripherals are off, and so are Wi-Fi and Bluetooth; the RTC controller and the RTC memory stay on. Waking up restarts the program from the beginning, so in Arduino everything happens in setup().
Wake-up sources
- Timer, on every chip: the RTC timer wakes it after a set time.
- Pins. The ESP32 and ESP32-S3 wake on one RTC pin at a set level (ext0) or on several (ext1). The ESP32-C3 wakes only on pins in its RTC power domain, GPIO0–5, enabled with
esp_deep_sleep_enable_gpio_wakeup()(see our ESP32-C3 SuperMini pinout). - Touch pads, on the ESP32 and ESP32-S3.
- The ULP coprocessor, on the ESP32 and ESP32-S3: a small core that can read a sensor while the main CPUs sleep and wake them when something happens.
Keeping data across sleep
Ordinary variables are lost at each wake-up. Declare the ones you need with RTC_DATA_ATTR: they live in RTC memory, which stays powered in deep sleep by default.
Arduino-ESP32
#define SLEEP_MINUTES 15
RTC_DATA_ATTR int bootCount = 0; // kept in RTC memory
void setup() {
bootCount++;
// read the sensor, connect, send the data...
esp_sleep_enable_timer_wakeup(SLEEP_MINUTES * 60ULL * 1000000ULL); // microseconds
esp_deep_sleep_start(); // does not return
}
void loop() {} // never reached
The code is for Arduino-ESP32 3.x, whose stable 3.3 series is built on ESP-IDF 5.5. The timer takes microseconds, hence the conversion. To wake on a pin, the ESP32 and ESP32-S3 use esp_sleep_enable_ext0_wakeup(pin, level); after the restart, esp_sleep_get_wakeup_cause() tells you why the chip woke. In ESP-IDF 6, on which Arduino-ESP32 4.x is built, that function is deprecated in favour of esp_sleep_get_wakeup_causes(), which returns every wake-up source as a bitmap, and the ESP32-C3’s esp_deep_sleep_enable_gpio_wakeup() is replaced by esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown().
ESPHome
deep_sleep:
run_duration: 10s
sleep_duration: 15min
run_duration is how long the node stays awake, sleep_duration how long it sleeps; on the ESP32, wakeup_pin adds a wake-up pin. Our ESPHome generator can add this block, and a static IP, for you.
Pins during sleep
A pin that must keep its level while the chip sleeps, such as the gate of a MOSFET that keeps a sensor off, needs a hold: gpio_hold_en() before sleeping and gpio_hold_dis() after waking. On the ESP32, ESP32-C3 and ESP32-S3 that is enough only for RTC pins: pins outside the RTC domain (GPIO1, 3, 5, 16–19 and 21–23 on the ESP32, GPIO6 and up on the ESP32-C3, GPIO22 and up on the ESP32-S3) also need gpio_deep_sleep_hold_en(). Watch for current through pull-ups and dividers as well. Espressif’s own example is GPIO12 on the ESP32-WROVER, with an external pull-up and an internal pull-down: it leaks until you isolate it with rtc_gpio_isolate() before sleeping.
Shortening the time awake
In the worked example Wi-Fi accounts for most of the average current, so every second saved while awake counts:
- A static IP. It skips DHCP; ESPHome’s documentation says it “can dramatically improve connection times”. In Arduino, call
WiFi.config(ip, gateway, subnet, dns)beforeWiFi.begin(). - Remember the access point.
WiFi.begin(ssid, password, channel, bssid)takes the channel and BSSID you saved in RTC memory after the first connection. ESPHome’sfast_connectskips the initial scan and stores the BSSID and channel too. - ESP-NOW instead of Wi-Fi and MQTT. ESP-NOW is Espressif’s connectionless protocol: no access point, no IP address, no broker. Packets carry up to 250 bytes (1470 with ESP-NOW v2), and sender and receiver must be on the same channel. A mains-powered ESP32 can receive the data and pass it on to MQTT.
- Power sensors only when needed. Feed a sensor from a GPIO if it draws little, or switch it with a MOSFET; our transistor switch calculator checks the part. Include the sensor’s start-up time in the awake phase.
We don’t quote connection times: they depend on the access point and the network. Measure yours, as described next.
Measuring the current properly
A multimeter in series is fine for the sleep current, with two caveats. Its shunt drops a voltage, the burden voltage, which on the microamp ranges can be enough to starve the board when it wakes up; and it shows a slow reading, so it can’t follow Wi-Fi bursts that last a fraction of a second.
Instruments made for the job:
- Nordic Power Profiler Kit II (PPK2): measures from 200 nA to 1 A at 100,000 samples per second, and can power the board itself at 0.8–5 V.
- Joulescope JS220: samples current and voltage together at 2 million samples per second, with a resolution down to 0.5 nA.
- EEVblog µCurrent GOLD: an adapter that turns a multimeter into a low-burden current meter, 1 mV per nA, µA or mA.
Whatever you use, measure the average over at least one full cycle, sleep and wake-up included, power the board at the battery voltage you’ll really use, and unplug USB, which powers the board from another source.
Monitoring the battery voltage
A Li-ion cell (4.2 V full) is above what the ADC can read, so feed it through a divider. With 1 MΩ + 1 MΩ, the divider halves the voltage and draws 2.1 µA from a full cell. Add a 100 nF capacitor from the ADC pin to ground, so the ADC sees a low-impedance source while it samples. To draw nothing in sleep, switch the divider on its high side: a P-MOSFET between the cell and the divider, turned on through a small N-MOSFET driven by a GPIO. A low-side N-MOSFET alone won’t do, because when it is off the top resistor pulls the ADC pin up to the cell voltage, 4.2 V when full, above the chip’s 3.6 V limit; and a P-MOSFET driven straight from a 3.3 V GPIO can’t switch fully off with 4.2 V on its source. Our transistor switch calculator checks both parts.
See it in our divider calculator: 1 MΩ + 1 MΩ from a full Li-ion cell into an ESP32-C3.Open the divider calculator
Keep the divider output within the range where the ADC is specified: up to about 2.45 V on the ESP32 and 2.5 V on the ESP32-C3 at the highest attenuation, according to Espressif’s datasheets. In Arduino, analogReadMilliVolts() returns a calibrated reading in millivolts. On the ESP32 use an ADC1 pin: ADC2 can’t be read reliably while Wi-Fi is on. Then turn the voltage into a charge level with our battery voltage chart; with LiFePO4, the voltage says little in the middle of the discharge.
A worked example
A sensor node on a bare ESP32-C3 module, a TPS63802 buck-boost and a 3000 mAh 18650 Li-ion cell, waking every 15 minutes to send one reading over Wi-Fi:
| Item | Value | Source |
|---|---|---|
| Deep sleep | 5 µA | Espressif, ESP32-C3 |
| Regulator | 11 µA | TI, TPS63802 quiescent current |
| Battery divider | 2 µA | 1 MΩ + 1 MΩ: 2.1 µA full, 1.5 µA at 3.0 V |
| Awake, CPU | 25 mA for 0.4 s | Battery-life calculator, ESP32-C3 preset (indicative) |
| Awake, Wi-Fi | 95 mA for 1.5 s | Battery-life calculator, ESP32-C3 preset (indicative) |
| Battery | 3000 mAh, 85% usable, 2% self-discharge a month | Battery-life calculator, 18650 preset |
The awake figures are the calculator’s indicative values: replace them with what you measure.
The average current comes to about 270 µA, which gives about 13 months. Wi-Fi takes the largest share, then the cell’s own self-discharge; deep sleep is almost negligible.
Waking once an hour instead brings the average down to about 142 µA and stretches the runtime to about 2 years (see it in the calculator), with self-discharge now the largest share. The same cell in an unmodified DevKit lasts about 13 days at best.
One caveat: the calculator models a linear regulator, so the battery supplies the circuit’s current plus the regulator’s quiescent current. A buck-boost such as the TPS63802 passes on power instead: the battery current is the circuit current × 3.3 V ÷ (battery voltage × efficiency). At about 90% efficiency (the figure our regulator calculator assumes for the TPS63802), that comes to about the circuit current at 3.7 V, a Li-ion cell’s nominal voltage: a little less on a full cell and about a fifth more near 3.0 V, so for this example the estimate roughly holds. With three AA cells near the end of their discharge, around 2.7 V, the battery supplies about a third more than the circuit draws.
Open the example in the battery-life calculator, then replace the indicative figures with the currents you measured.Open the battery-life calculator
Charging, and solar
The ubiquitous TP4056 charges one Li-ion cell at up to 1 A to 4.2 V, and ends the charge when the current falls to a tenth of the set value. It has no power path: the ESP32 stays connected to the cell during charging, and if it draws more than that tenth the charge may never end. It is only a charger, so protection against over-discharge and short circuits must come from the cell or a separate circuit. It does have a TEMP input for the battery’s thermistor, but grounding that pin turns the check off, and the common modules come with it grounded.
Chargers with power-path management feed the load and charge the cell at the same time. The TI BQ24074 does (up to 1.5 A, with input power management that backs off when the source sags) and has a battery temperature input that suspends charging outside its window; TI’s example sets 0–50 °C. For solar, the Consonance CN3791 is a switch-mode charger for one Li-ion cell, up to 4 A. What it calls MPPT is a fixed set-point: the chip holds its MPPT pin at 1.205 V, so a resistor divider from the panel sets the voltage at which it keeps the panel, chosen once from the panel’s datasheet. It has no battery temperature input.
To size the panel and the battery for a node that has to get through the winter, use our off-grid solar calculator.
Safety
- Protection. A Li-ion or LiPo cell needs protection against over-charge, over-discharge and short circuits, in the cell, on the board or in a separate module.
- Polarity. Two-pin JST PH plugs on LiPo cells have no standard polarity: check + and − with a multimeter before plugging a battery into a board (see our JST PH page).
- Bigger packs. Several cells together can deliver very high currents: fit a BMS and a fuse on the main lead. Our battery pack calculator gives the BMS rating.
- LiFePO4 straight to the module. Only with a charger that stops below 3.6 V.
Frequently asked questions
How long can an ESP32 run on a battery?
It depends mostly on how often it wakes up and how long Wi-Fi stays on. In our worked example, a bare ESP32-C3 module waking every 15 minutes lasts about 13 months on a 3000 mAh 18650 cell, and about 2 years if it wakes once an hour; an unmodified DevKit lasts about 13 days at best. Try your own figures in the battery-life calculator.
Can I power an ESP32 straight from a Li-ion cell?
No: a full cell gives 4.2 V and the module’s absolute maximum is 3.6 V. Use a low-dropout regulator or a buck-boost. A LiFePO4 cell can feed it directly if it is charged to below 3.6 V.
Which regulator should I use?
One that delivers at least 500 mA, as Espressif asks, with a low quiescent current: among LDOs the AP2112K (55 µA, rated for 600 mA) or the TLV755P (25 µA, rated for exactly 500 mA), or a buck-boost such as the TPS63802 (11 µA) to use the whole cell or run from three AA cells. The MCP1700 and HT7333 draw even less but are rated for only 250 mA.
Why is my deep-sleep current so high?
Usually because of the board, not the chip: a regulator such as the AMS1117 (about 5 mA), a power LED, a USB-serial chip, or current through pull-ups, dividers and sensors. Measure with USB unplugged, then remove or isolate parts one at a time.
Is a CR2032 coin cell enough?
Not for Wi-Fi or Bluetooth on an ESP32: a CR2032 is rated for a few milliamps continuous, and Espressif asks for a supply that can deliver 500 mA.
Deep sleep or light sleep?
Deep sleep draws the least (about 10 µA on the ESP32) but restarts the program at every wake-up. Light sleep keeps the RAM and resumes faster, at a higher current: about 0.8 mA on the ESP32, 130 µA on the ESP32-C3 and 240 µA on the ESP32-S3, according to Espressif. For a node that wakes every few minutes, deep sleep usually wins.
Do I need a capacitor?
Espressif recommends at least 10 µF at the power entry and 0.1 µF close to the chip’s supply pins. With a battery that can’t deliver the Wi-Fi peaks on its own, such as a Li-SOCl₂ cell, a larger capacitor has to supply them.
Can I charge from USB while the ESP32 runs?
With a power-path charger such as the BQ24074, yes. With a plain TP4056 the ESP32 stays connected to the cell during charging, and if it draws more than a tenth of the charge current, the charge may not end.
Sources
- Espressif: ESP32 Series Datasheet (deep sleep 10 µA)
- Espressif ESP Techpedia: ESP low-power introduction (ESP32-C3 5 µA, ESP32-S3 7 µA)
- Espressif: ESP32-C3 Series Datasheet
- Espressif: ESP32-WROOM-32E datasheet (3.0–3.6 V, 3.6 V absolute maximum)
- Espressif: ESP32 hardware design guidelines, schematic checklist
- Espressif: ESP32-C3 hardware design guidelines, schematic checklist
- ESP-IDF: sleep modes (ESP32)
- ESP-IDF: sleep modes (ESP32-S3)
- ESP-IDF: sleep modes (ESP32-C3)
- ESP-IDF v6.0 migration guide: system (sleep API changes)
- ESP-IDF API: gpio_hold_en (documentation comment)
- Arduino-ESP32: Deep Sleep
- Arduino-ESP32: Wi-Fi API
- Arduino-ESP32: ADC API
- Arduino-ESP32: releases (3.3 series on ESP-IDF 5.5)
- ESP-IDF: ESP-NOW
- ESPHome: Deep Sleep component
- ESPHome: WiFi component
- Seeed Studio wiki: XIAO ESP32C3
- AMS1117 datasheet summary
- Microchip: MCP1700 datasheet
- Holtek: HT73xx datasheet
- TI: TLV755P datasheet
- Diodes: AP2112 datasheet
- TI: TPS63802
- LG: INR18650 MJ1 specification
- EVE: LF280K specification
- Energizer: NiMH handbook
- Energizer: E91 AA alkaline
- Renata: CR2032 datasheet
- TI: Coin cells and peak current draw (SWRA349)
- Saft: LS14500 datasheet (2023)
- Saft: LS14500 datasheet (open-circuit voltage)
- Qoitech: Li-SOCl₂ passivation test
- NanJing Top Power: TP4056 datasheet
- NanJing Top Power: TP4056 datasheet, full version (TEMP pin)
- TI: BQ2407x datasheet (BQ24074)
- Consonance: CN3791 datasheet (Chinese, Rev 1.0)
- Nordic Semiconductor: Power Profiler Kit II
- Jetperch: Joulescope JS220 datasheet
- EEVblog: µCurrent GOLD