How it works
The average current of an nRF52 device is the duty-cycle-weighted sum of its operating states. The key states are:
I_avg = I_sleep × t_sleep/T + I_cpu × t_cpu/T + I_radio × t_radio/T + I_peripherals
Getting this right requires knowing the current for each state from the datasheet and the time spent in each state.
System ON sleep
With CPU halted (__WFE() / sd_app_evt_wait()), radio off, and peripherals gated, the nRF52840 draws 1.5 µA retaining 3 RAM banks at 3.0 V. This drops to ~0.7 µA if you can reduce RAM retention to 1 bank.
In Zephyr, configure RAM retention in devicetree or use pm_state_force() to ensure the correct power state. The SoftDevice on bare-metal firmware handles this automatically when sd_app_evt_wait() is called.
DC/DC converter
The onboard DC/DC converter (requires a 4.7 µH inductor on the DCC pin — nRF52840-DK has it populated) reduces CPU and radio current by approximately 35–40% at 3.0 V. This is the single highest-leverage power optimization available.
For a beacon drawing 1 mA average with LDO, DC/DC brings it to ~0.62 mA — extending a 225 mAh CR2032 from 225 to 363 hours.
In Zephyr: the nrf52840dk_nrf52840 board target enables DC/DC by default. On a custom board, set CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y and ensure the DCC inductor is present.
BLE advertising
Each advertising event consists of 3 channel transmissions (CH 37, 38, 39). For a typical ADV_IND PDU with 20-byte payload:
- Each channel TX: ~0.35–0.40 ms
- Full 3-channel event: ~1.2 ms
- Connectable advertising (ADV_IND) adds a SCAN_REQ receive window per channel: ~1.5–1.6 ms total
At a 1000 ms advertising interval:
duty = 1.2 ms / 1000 ms = 0.12%
avg_radio_current = 0.0012 × 4.8 mA (TX 0 dBm) = 5.8 µA
This is why BLE beacons at 1-second intervals can run for months on a CR2032. At 100 ms intervals the duty rises to 1.2%, consuming ~58 µA from radio alone.
BLE connection
In a connection, the radio wakes at every connection interval for a brief event. For empty connection events (no application data, just keep-alive):
- Event duration: ~0.5 ms (1 TX + 1 RX empty PDU)
- At 100 ms CI: duty = 0.5%, avg = 0.005 × (4.8 + 4.6) / 2 mA = 23.5 µA
When data is exchanged (DLE packets, notifications), event duration grows to 1–3 ms depending on MTU. At 7.5 ms CI with data exchange, radio duty can reach 10%+.
Peripherals
Peripherals left powered in sleep cost more than most engineers expect:
- UART RX active: ~400 µA. If you’re polling or waiting on UART, the receiver is live. Use
UARTEwithENDRXevent and put the peripheral into low-power state between messages. - USB (enumerated): 2.7 mA. USB on nRF52840 requires the 48 MHz USB oscillator running. Disconnect USB in production firmware unless the use case requires it.
- RTC: 1 µA. Always leave this running — it’s what drives your sleep scheduler.
Common mistakes
Leaving the high-frequency crystal running in sleep. The HFXO (32 MHz / 64 MHz) draws ~500 µA. The SoftDevice manages this automatically, but bare-metal firmware must explicitly request clock stop: nrfx_clock_hfclk_stop().
Not enabling DC/DC. On custom boards, the DC/DC is off by default. Forgetting to populate the 4.7 µH inductor on DCC is a hardware mistake; forgetting to enable it in software on a board that has the inductor is a firmware mistake. Add NRFX_POWER_ENABLED=1 and call nrfx_power_clock_irq_handler() or configure via Zephyr Kconfig.
Tight advertising intervals with SoftDevice. The SoftDevice inserts a SD_EVT_BLE_GAP_ADV_STOPPED event after each advertising window. If your main loop doesn’t return to sd_app_evt_wait() quickly, you add CPU active time proportional to application latency. Profile with Power Profiler Kit II before finalizing.
Using CPU at 64 MHz when 16 MHz is sufficient. The nRF52840 runs at 64 MHz by default. If your workload is light (sensor reads, packet builds), running at 16 MHz saves ~4 mA in the active state. In Zephyr, set CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=16000000.
Counting sleep current wrong. The 1.5 µA System ON figure assumes RAM retention and no peripheral activity. Every peripheral you leave clocked adds to this. Measure with a PPK2 rather than calculating — the numbers rarely add up cleanly due to undocumented leakage paths.