6.29. Low-power and sleep modes¶
Battery-powered cameras and intermittently-active sensors do
not need the CPU running at full speed all the time. The
machine module exposes four progressively-deeper
power-saving states – active, idle(),
lightsleep(), and deepsleep().
Each step deeper turns more of the chip off and saves more
power, at the cost of a longer wake-up. Picking the right one
is a trade between how much power the camera saves and how
fast it can react when something happens.
6.29.1. Active¶
The default state. The CPU is running Python, every peripheral is clocked, and current draw is at its highest – tens of milliamps on the camera’s logic rail, plus whatever any attached accessories pull through it.
6.29.2. idle()¶
machine.idle() gates the CPU clock until any interrupt
fires (a peripheral, a timer, a pin IRQ). RAM is live,
peripherals stay on, the clocks keep running – only the CPU
itself is paused, and it wakes in microseconds when there is
work to do.
Use it inside any tight polling loop that is waiting for something external to happen:
import machine
while not button_pressed():
machine.idle()
The CPU stops burning cycles on the while check itself and
wakes naturally when the next event arrives – a small saving
that adds up over a loop that runs millions of times.
6.29.3. lightsleep()¶
machine.lightsleep() is the next step down. The CPU is
stopped completely and most of the chip’s internal clocks are
switched off, but RAM and peripheral state are preserved. When the wake source
fires, the script resumes from exactly where it called
lightsleep – variables, open handles, and pending data
all intact – on the order of milliseconds later.
import machine
from machine import Pin
wake_pin = Pin("P0", Pin.IN, Pin.PULL_UP)
wake_pin.irq(lambda _: None, trigger=Pin.IRQ_FALLING, wake=machine.SLEEP)
while True:
do_work()
machine.lightsleep() # wakes on a falling edge on P0
The wake source – a pin IRQ here – must be configured before the sleep call. Power draw drops significantly relative to active mode; the exact number depends on the board and what peripherals are still configured.
6.29.4. deepsleep()¶
machine.deepsleep() is the deepest state. The CPU stops,
peripherals are powered down, and RAM contents may be lost.
The only things still drawing power are the wake circuit and a
small bit of always-on logic.
When the wake source fires, the chip boots from the start of
the main script – deepsleep does not return. The script
distinguishes a deepsleep wake from a fresh power-on or hard
reset using machine.reset_cause():
import machine
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
# Woke from deepsleep -- restore state from non-volatile storage,
# take a measurement, etc.
pass
else:
# Fresh boot
pass
do_work()
machine.deepsleep(60_000) # arm RTC wake for 60 s, sleep, then restart
The millisecond argument to deepsleep() arms
the on-chip RTC alarm internally – the RTC is what carries
the wake-up timing through the sleep, since most other timers
are powered down. Calling deepsleep() with no
argument leaves the wake-up to whatever source you configured
separately (a pin IRQ, an externally-armed RTC alarm).
Because the script restarts, anything the next iteration needs
has to either be reconstructed at the top of main.py or
persisted to flash (or to the RTC’s backup registers, on parts
that have them). Deepsleep gives the largest power saving but
imposes the most program restructuring – the application has
to behave as a series of short “measurement bursts” separated
by sleeps, rather than a long-running loop with state in RAM.
6.29.5. Choosing a state¶
The right state depends on what the camera is waiting for:
Tight polling loop, waiting milliseconds. Use
idle(). The savings are small per cycle but large in aggregate, and the wake is invisible.Idle for seconds or minutes between events. Use
lightsleep(). State is preserved, wake is fast, and power draw is a fraction of active mode.Idle for minutes or longer between brief bursts of work. Use
deepsleep(). The chip is effectively off between events, and the script structure shifts to a wake, measure, sleep loop.
Whatever the state, the wake source matters as much as the
state itself – a deepsleep that wakes only on a timer is a
duty-cycled measurement loop; a lightsleep that wakes on a pin
IRQ is an event-driven sensor. The machine module’s
sleep functions, RTC alarms, and
irq() together give the building blocks.