Power and Low-Power Firmware

Sleep modes, duty cycling, battery life from a current profile, regulators, brown-out and wake-up design.

Average current and the energy budget

A battery holds a fixed amount of charge, measured in milliamp-hours (mAh). The life of a device is that capacity divided by the average current it draws, so a device that sleeps most of the time and wakes briefly can last for years on a small cell, and the average is dominated by whichever of the two states uses more charge.

Iavg = Σ (Istate × tstate) ÷ T    life (h) = usable capacity (mAh) ÷ Iavg (mA)

Current profile of a duty-cycled sensor node06012005101520time (s)current (mA)20 mA for 0.1 s20 mA for 0.1 saverage 0.043 mASleep current is 10 µA (0.01 mA), too small to see at this scale. The brief active bursts supply most of the energy.
A duty-cycled sensor node: brief 20 mA bursts once a minute, 10 µA in between. The short bursts supply most of the charge.

Worked example: a sensor node on a battery

  • The node wakes for 100.0 ms every 60 s at 20 mA (reading and transmitting) and sleeps the rest at 10 µA (0.01 mA).
  • Charge per cycle: active 20 mA × 0.10 s = 2.00 mA·s; asleep 0.01 mA × 59.9 s = 0.599 mA·s. Their sum ÷ 60 s gives Iavg = 0.0433 mA. The brief bursts supply 77 % of the charge.
  • Life: a 2 000 mAh battery, derated to 80 % for temperature, aging and cut-off voltage (1 600 mAh usable), lasts 1 600 ÷ 0.0433 = 36 937 h = 1 539 days, 4.2 years in theory.
  • Where to save: halving the sleep current saves 0.0050 mA of the 0.0433 mA average, while halving the awake time saves 0.0167 mA: here the burst is the thing to shorten. At longer intervals the sleep current takes over (see below).

Sleep modes

PlatformTypical sleep modes and currentsWake sources
ATmega328P (3 V)Idle ≈ 0.4 mA (CPU off, peripherals on); power-save ≈ 1 µA with a timer; power-down ≈ 0.1 µA (≈ 4 to 6 µA with the watchdog running)Pin change, external interrupt, watchdog, timer 2
STM32L4 / L0Sleep ≈ 1 to 3 mA; stop mode ≈ 1 to 3 µA with RAM retained; standby ≈ 0.3 µARTC alarm, pin, UART, low-power timer
nRF52 (BLE)System ON idle ≈ 2 µA; System OFF ≈ 0.3 µARTC, GPIO, radio events
ESP32Light sleep ≈ 0.8 mA; deep sleep ≈ 10 µA (RTC timer only); hibernation ≈ 5 µARTC timer, touch, EXT0 / EXT1 pins, ULP coprocessor
RP2040Dormant ≈ 0.8 mA board-level (more in practice on Pico boards because of the regulator and flash); dormant on bare chip tens of µAGPIO, RTC

These are chip figures from datasheets and vary with voltage, temperature and exactly what is left on. The board matters: a development board’s USB chip, power LED and regulator often draw milliamps and hide the chip’s microamps. Measure your own hardware.

Duty cycling: the biggest lever

The average current falls almost in proportion to the fraction of time the device is awake, until the sleep current becomes the floor. Using the node above (20 mA for 100.0 ms, 10 µA asleep, 1 600 mAh usable):

Wake intervalAverage currentCalculated life
1 s2.009 mA0.1 years
10 s0.210 mA0.9 years
60 s0.043 mA4.2 years
600 s0.013 mA13.7 years
3 600 s0.011 mA17.3 years

Beyond about ten years the battery’s own self-discharge (1 to 3 % a year for lithium primary cells, much more for rechargeables) and aging set the real limit, so there is no point in saving the last microamp: design to meet the life you need, then stop.

Wake-up design in firmware

  • Sleep as soon as the work is done and wake only on a timer (an RTC or the watchdog timer) or an event (a pin change). Never poll in a busy loop.
  • Do the work in the wake handler or the main loop, then go back to sleep: a state machine whose idle state sleeps.
  • Turn off what you do not use before sleeping: the ADC, the radio and unused serial ports; switch off sensors with a MOSFET or their own enable pin.
  • Wake the slow clock domain: a low-power 32.768 kHz crystal and RTC keep time for microamps; the fast oscillator takes time to restart (up to milliseconds for a crystal), which is energy too.
  • Keep state across sleep: deep sleep modes lose RAM (except a small retained area); store what you need in retained memory or non-volatile memory (see Memory, Number Formats and Reliability).
  • Handle the wake race: an event that arrives just before you sleep must still wake you; check the flag with interrupts disabled before the sleep instruction.
// ATmega328P: sleep until a pin or the watchdog wakes us (avr/sleep.h)
#include <avr/sleep.h>
#include <avr/power.h>

void sleep_until_event(void) {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  cli();
  if (!event_pending) {              // the race check: only sleep if nothing arrived meanwhile
    power_adc_disable();             // switch off unused peripherals
    sleep_enable();
    sei();                           // the instruction after sei() still runs before the interrupt
    sleep_cpu();                     // ~0.1 uA here; wakes on the interrupt
    sleep_disable();
    power_adc_enable();
  } else {
    sei();
  }
}

Regulators and quiescent current

A linear regulator (LDO) drops the extra voltage as heat; a buck converter switches and wastes much less. But in sleep the regulator’s own quiescent current (Iq) can exceed the MCU’s.

Worked example: the regulator that eats the battery

  • Heat in a linear regulator: from 9 V to 5 V at 50 mA wastes (9 − 5) × 0.05 = 0.2 W. From a 3.7 V battery to 3.3 V at 20 mA the efficiency is Vout ÷ Vin = 89 % and the loss is 8 mW, which is acceptable: a linear regulator is fine for a small drop at low current.
  • Quiescent current. Take the same node (10 µA asleep). An ordinary LDO with Iq = 50 µA raises the sleep current to 60 µA and the average to 0.0932 mA: 715 days instead of 1 539. A micropower LDO with Iq = 1 µA gives a sleep current of 11 µA and an average of 0.0443 mA: 1 504 days.
  • For buck converters look at the light-load efficiency and the quiescent current (a few µA for the best), not the full-load figure, and note that cheap modules often draw milliamps.
  • Remove the parts you do not need: the power LED and the USB-serial chip on a development board, or power the bare chip from the battery directly if its voltage range allows (many 3.3 V chips run from a 3 V coin cell or two AA cells).

Clock speed, voltage and “race to sleep”

A CMOS chip’s dynamic power is about P = C V2 f, so it scales with the clock frequency and the square of the voltage. But power is only half the story: the energy for a fixed task is power times time, and a faster clock finishes sooner. If the chip can then sleep deeply, running fast and sleeping longer (race to sleep) is usually the better choice.

Worked example: fast or slow for the same job?

  • A task needs 8 million cycles once a second. At 8 MHz it takes 1.00 s at 8 mW; at 16 MHz it takes 0.50 s at 11 mW (much of the power is static, so doubling the clock raises it by far less than double).
  • Energy of the work: 8 mW × 1.00 s = 8 mJ at the slow clock, 11 mW × 0.50 s = 6 mJ at the fast clock. Adding the sleep power of 0.03 mW for the rest of the second gives 8.00 mJ against 5.52 mJ.
  • The lesson: the result depends on the ratio of active to sleep power. Race to sleep wins when sleep is very deep and the static power is large; lowering the clock helps when the CPU must be awake anyway (waiting for a slow peripheral). Measure both.
  • Lower the voltage where the chip allows (many parts have a lower-voltage range at lower speed): the V2 term is the biggest saving.

Hidden drains: pins, pull-ups and peripherals

Worked example: a pull-up that costs the whole sleep budget

A switch with a 10 kΩ pull-up to 3.3 V draws 3.3 ÷ 10 000 = 330 µA whenever it is closed. If it is held closed (a door sensor with the door shut) for the whole sleep, that is thirty times the 10 µA sleep current. Use a 1 MΩ pull-up (3.3 µA), or switch the pull-up on only when reading, or use a normally-open contact so that it draws current only when it is pressed (a button pressed 0.1 % of the time averages 0.33 µA with the 10 kΩ resistor).

  • Floating inputs draw extra current as they hover between thresholds: configure unused pins as outputs low or as inputs with a pull-up (consult your chip’s low-power guidance).
  • Pins connected to something powered: an output driving an LED, a sensor, or another chip that is off can leak current through its protection diodes; set pins to inputs or low before turning a peripheral’s power off.
  • Peripherals left on: the ADC, brown-out detector, watchdog, internal reference, analog comparator and timers each draw microamps; disable them for deep sleep (the brown-out detector is the one you may need to keep, see below).
  • External parts: voltage dividers (see the battery divider in Analog Input and Signal Processing), sensors, level shifters, the USB-serial chip and LEDs: each may draw more than the MCU.
  • Leakage in capacitors and boards: electrolytic capacitors leak microamps, and a dirty board adds more. Use low-leakage ceramic or film capacitors in a microamp design.

Radios: Wi-Fi, BLE and LoRa

Radios dominate the energy budget of a wireless node: transmitting costs tens to hundreds of milliamps. Minimize how long the radio is on, how often, and how many bytes it sends.

RadioTypical active currentNotes
Wi-Fi (ESP32)Transmit 120 to 240 mA; receive 80 to 100 mA; connection takes 0.5 to 3 sConnecting is the expensive part: use a fixed channel and static IP, keep the BSSID, or send one UDP packet
Bluetooth LEPeak 5 to 15 mA, ≈ 0.01 to 0.05 mA averaged at slow advertisingBuilt for coin cells; use long connection intervals and slave latency
LoRa / LoRaWANTransmit 40 to 120 mA for 0.05 to 2 s per message; receive 10 mAMiles of range at a few messages an hour; watch the duty-cycle limits
Cellular (LTE-M, NB-IoT)Hundreds of mA peaks; seconds per connectionPSM and eDRX modes sleep for hours at microamps
Zigbee, Thread, Z-Wave10 to 40 mA transmitMesh networks with sleepy end devices

Worked example: a Wi-Fi sensor sending every 15 minutes

  • The node wakes, connects and sends for 3.0 s at about 100 mA average, then deep-sleeps at 10 µA for the rest of 15 minutes. Iavg = (100 × 3.0 + 0.01 × 897) ÷ 900 = 0.343 mA. A 2 000 mAh cell (1 600 mAh usable) lasts 1 600 ÷ 0.343 ÷ 24 = 194 days.
  • Cutting the connect-and-send time to 0.8 s (static IP, fixed channel, a single small packet) gives 0.099 mA and 674 days: the connection time is the lever. Sending every hour instead of every 15 minutes divides the average by nearly four.
  • Batch the data: read often, send rarely; one connection carrying ten readings costs far less than ten connections.

Batteries, brown-out and low-battery handling

CellVoltage rangeNotes
Alkaline AA/AAA1.6 V fresh to 0.9 VTwo cells give 3.2 to 1.8 V: check the MCU’s minimum voltage; cheap; capacity falls at high current
Lithium primary (CR2032, AA lithium)3.0 V flat; 1.5 V per AA lithiumLow self-discharge (about 1 % a year), long shelf life; coin cells cannot supply high pulses: add a capacitor
Li-ion / LiPo4.2 V full, about 3.7 V nominal, 3.0 V emptyRechargeable; needs a protection circuit and a charger; never discharge below the cut-off
LiFePO43.65 V full, 3.2 V nominal, 2.5 V emptySafer chemistry; flat curve; direct 3.3 V supply possible
NiMH1.4 V full, 1.2 V nominal, 1.0 V emptySelf-discharge of 1 to 2 % per day for standard cells (low-self-discharge cells are better)
  • Brown-out detection: the MCU resets (or interrupts) when the supply falls below a threshold (here 2.7 V), instead of running erratically; it draws a microamp or so, which is a small price. Set the threshold above the voltage at which the chip’s flash and clock stop being reliable at your speed.
  • Low-battery warning: measure the battery voltage (the internal reference trick in Analog Input and Signal Processing), average it (a sag during a radio transmission is normal), and warn well above the cut-off. A Li-ion cell is nearly empty at 3.0 V, but its voltage curve is flat between about 3.7 and 3.9 V, so the voltage is only a rough gauge of charge.
  • Pulse loads: a coin cell’s internal resistance (10 to 30 Ω) makes the voltage sag under a radio burst: a 100 µF capacitor or a hybrid capacitor supplies the pulse.
  • Safe shutdown: on a low battery, save the data, switch off the loads, and sleep until the supply recovers or is replaced.

Measuring low currents

Worked example: measuring a sleep current

  • A multimeter on its microamp range has a burden voltage (it drops a few hundred millivolts) and cannot follow a wake burst. A shunt resistor of 100 Ω in series with the supply turns 10 µA into 1.0 mV: readable on an oscilloscope, but the shunt also drops 1.0 mV from the supply, an acceptable burden here.
  • For a wide range (10 µA asleep, 100 mA awake) a single fixed shunt does not work: use a dedicated tool (a current-profiling instrument such as the Nordic PPK2 or the Joulescope, an SMU, or a low-burden amplifier like the µCurrent) that auto-ranges, and integrates the charge over a whole cycle.
  • Integrate over a complete cycle (wake, work, sleep) to get the average; a short snapshot can mislead.
  • Measure the whole board, not only the MCU, with the real battery, at the real temperature; sleep currents double every 10 to 15 °C for some chips.
  • Look for unexpected wake-ups: periodic bursts on the profile are interrupts, timers or a peripheral you forgot to stop.

Related

FAQ

How long will my project last on a battery?

Divide the usable capacity (derated to about 80 %) by the average current. Measure the average over a complete wake-and-sleep cycle; the sleep current and the awake time are usually the two numbers that matter.

Why does my “10 µA” device draw 5 mA?

The development board’s other parts: the USB-serial chip, power LED, regulator quiescent current, and any pull-ups, sensors or peripherals still powered. Measure the bare design, or remove those parts.

Is it better to run slowly or to sleep?

Usually race to sleep: finish the work quickly and spend the rest in a deep sleep. But if the CPU must wait for a slow peripheral, a slower clock saves energy. Measure both on your own hardware.

Can a coin cell power a Wi-Fi or Bluetooth device?

BLE yes, if you advertise slowly and use a capacitor for the pulses. Wi-Fi draws too much current for a coin cell: use a larger lithium or alkaline pack, or an energy-harvesting design.

References

  • Microcontroller datasheets and low-power application notes (Microchip AVR, STMicroelectronics STM32L, Nordic nRF52, Espressif ESP32 sleep-mode current tables).
  • Battery makers’ datasheets (Energizer, Panasonic, Saft) for capacity, pulse performance and self-discharge.
  • Nordic Semiconductor, Online Power Profiler; Joulescope documentation (measuring dynamic currents).

Last reviewed: October 2026. Currents are typical datasheet values for the parts named: they vary with voltage, temperature and configuration, so measure your own board.