The sleep strategy is determined bybusiness cadence(how often to wake, what to do while awake, which events must wake it immediately), not by "some µA number". This Skill provides baseline (high-confidence) facts about the dual modes and wake-up sources;the specific deep sleep current values are UNVERIFIED in the baseline—always refuse to recite numbers, and provide the measurement method。
Determine Task Type
- Battery device runtime design(periodic reporting/month-level runtime) → Workflow A (decision table main path).
- Wake-up source selection and configuration(button/timer/touch/ULP) → Workflow B, read wakeup-sources。
- Sleep current questions / runtime estimation → Workflow C (measurement-based acceptance, including the refusal stance on "reciting datasheet numbers").
- Preserving data across sleep → trade-off between RTC memory retention vs NVS snapshot (see the dedicated section after Contracts).
Prerequisites / Preflight
idf.py --version # 本机 IDF 实际版本
grep -E "CONFIG_ESP_SLEEP|CONFIG_PM_" sdkconfig 2>/dev/null | head -10 # 现有睡眠/电源管理配置
grep -m1 "CONFIG_IDF_TARGET" sdkconfig 2>/dev/null # 目标芯片——决定唤醒源集合与 ULP 类型
- Read target first: the chip model determines the wake-up source set and ULP form (see Contracts item 3); before there is a physical chip/engineering target, do not answer "which wake-up sources are available".
- Confirm the power supply form: battery chemistry and regulator quiescent current areboard-level facts, ask the user/schematic, do not guess.
- Real device and power meter (USB power meter or source meter)—essential for current acceptance; if absent, mark Pending HIL in the conclusion.
Offline Baseline
- : ESP-IDF baseline = v6.1(read through 2026-09-02, no automatic updates). Low-power facts are cited from the dated baseline §8 (official sleep_modes documentation, high confidence).
- Specific µA values are medium confidence(datasheet search paraphrase, not directly scraped from PDF)—before citing any specific current number, it must be verified at runtime or measured; this Skill never gives numbers.
- For behavior changes in later versions, defer to the official sleep_modes documentation; do not assert from memory.
Contracts (device contracts)
- Dual-mode definitions (high confidence):Light-sleep = clock gating, state retention, wireless power-off;Deep-sleep = CPU/most RAM/digital peripherals powered off, only the RTC controller, ULP, and RTC FAST/SLOW memory remain powered.
- Deep sleep wake-up sources (high confidence, listed verbatim in the baseline): RTC Timer (µs precision), Touch, EXT0 (single RTC GPIO), EXT1 (multiple RTC GPIOs, S2/S3/C6/H2 additionally support ANY_LOW),ULP coprocessor、deepsleep GPIO wake;combinable: Wake-up methods not included in the baseline (such as UART/Bluetooth wake) are always marked UNVERIFIED and must not be written into the answer.
- ULP distribution (high confidence):ESP32 = ULP-FSM;S2/S3 = RISC-V ULP or FSM core; C6/P4 = LP core (20/40 MHz). Before writing a ULP program, first confirm the target's ULP form.
- Deep sleep current values = UNVERIFIED: the baseline only confirms "µA order of magnitude" (the official page only gives SPI Flash standby <30µA / Deep Power-Down <1µA); "typical 10µA / ULP running ~150µA" comes from a datasheet paraphrase.This Skill does not output any specific value as fact—acceptance only recognizes board-level measurements (Workflow C).
- Sleep is a state-destructive operation: deep sleep kills normal RAM (task stacks and connection state are not retained), light sleep disconnects wireless. Before entering, state must first be settled (see the next section).
RTC memory retention vs NVS snapshot (trade-off decision)
| Criterion | RTC memory retention | Snapshot to NVS after wake/before sleep |
|---|---|---|
| Survives "battery swap/power loss" | No(deep sleep still relies on battery power for the RTC domain) | Yes(flash persistent) |
| Access speed | Available immediately upon wake, fastest | Needs to be read back (NVS API) |
| Capacity | Small (RTC slow memory, size per chip spec—verify at runtime) | Large (per flash budget) |
| Write cost | No flash wear | Has write endurance considerations, don't flush in high-frequency loops |
| Applicable to | Sleep counters, last report timestamp, and other small state | Configuration, cumulative values, data that must not be lost on power loss |
Common combination: put small state in RTC memory forbetween sleepspersistence; at the same time, write the "cannot be lost even if the battery is removed" conclusionsbefore entering deep sleeponce to NVS. The way RTC memory variables are declared (commonly the RTC_DATA_ATTR family) is per the official deep sleep documentation (verify at runtime).
Capability Boundaries + Hand-off
Not covered: power design at the FreeRTOS task/tick-less level, chip selection, project skeleton, andany commitment to specific current values。
| User Intent | Skill |
|---|---|
| Project/partition/sdkconfig basics | esp32-idf |
| Coordinating task suspension/queues with sleep (tick level) | esp32-freertos |
| Chip not yet decided / evaluating a switch to a low-power chip | esp32-variants |
| Power measurement/real-device in-the-loop acceptance (power meter, long run) | fw-hil-testing |
| "Validating business logic without a board" beyond ULP | fw-emulation |
| Trade-offs of Bluetooth/Wi-Fi provisioning in sleep scenarios | esp32-wifi-provision |
Workflow A — Sleep strategy for month-level battery life on battery devices (main path)
Set the strategy according to the decision table; every step must be able to answer "why not the other cell":
- Ask about the business cadence: How often is data reported? Are there external events that must be responded to immediately? If you can't answer, ask first, don't assume.
- Against the decision table:
| Requirement | Strategy |
|---|---|
| Periodic reporting (minute~hour-level duty cycle) | deep sleep + RTC timer wakeup(µs-precision timing, wake→sample→report→sleep again) |
| Button/external event must wake within seconds | deep sleep + EXT0 (single RTC GPIO)/ EXT1 (multiple RTC GPIO), note the RTC GPIO pin set limitations |
| Millisecond-level recovery, acceptable cost of maintaining connections | light sleep—but wireless power-off is an explicit baseline, "low power and still connected" does not hold |
| Sampling is more power-efficient than waking the whole system | Delegate to ULP/LP core(for the form, check Contracts clause 3 per target) |
- Settle state: Small state for falling asleep → RTC memory; must not be lost on power loss → write NVS before sleep.
- Configure wakeup source: see Workflow B.
- Current acceptance: see Workflow C; before there is a measured value, no battery-life conclusion may be stated.
Workflow B — Configure wake-up sources
- Read target and wakeup-sources, confirm that the selected wake-up source exists on that chip (the baseline only guarantees the existence of the 6 categories and the chip scope of EXT1 ANY_LOW; for the complete per-chip support matrix, refer to the official documentation — verify at runtime).
- Use the esp_sleep enable API family to declare wake-up sources (e.g., the
esp_sleep_enable_timer_wakeup()/esp_sleep_enable_ext0_wakeup()/esp_sleep_enable_ext1_wakeup()family — for specific signatures and enums, refer to the official API documentation, verify at runtime); multiple wake-up sources can be combined, and finally enter deep sleep. - After wake-up, usereset reason/wake-up reason queryto record "why it woke up this time" and write it into the boot log — sleep code without a wake-up reason log is not considered complete.
- GPIO-type wake-up sources only recognize the RTC GPIO set: which specific pins are available is subject to the chip datasheet/official pin documentation,if uncertain, stop(anti-hallucination red line: pins/multiplexing not from memory).
Workflow C — Sleep current measured acceptance (including refusal stance)
Refusal stance: the user asks "deep sleep is 10µA, right" — the answer is not "right", it is torefuse to treat this number as fact: it comes from a datasheet paraphrase (the baseline marks it as verify at runtime), and the datasheet value is the chip's bare current,not the current of your board(peripheral leakage, pull-up resistors, LEDs, and regulator quiescent current will all multiply it several times over). Correct actions:
- Set up measurement: connect a power meter/source meter in series into the power supply circuit, record the supply voltage and supply method.
- Measure the quiescent baseline: connect all on-board peripherals according to the product's real configuration (do not "strip everything off before measuring").
- Have the device enter the target sleep mode, and after stabilizing for ≥5 minutes, record theaverage current(flashing instantaneous values do not count).
- Use the measured values for battery life integral estimation:
续航 ≈ 电池可用容量 ÷ (占空比加权平均电流); mark the estimation result with the input assumptions. - Long-run and temperature-dimension acceptance →
fw-hil-testing; when there is no real hardware, mark the conclusionPending HIL。
Validation Gates
- Build level:
idf.py buildpasses, the sleep-related options in sdkconfig match the target (Preflight output kept on file). - Functional level (real hardware): timer wake-up wakes at the set period, the boot log has the wake-up reason; GPIO wake-up wakes immediately upon trigger; each configured wake-up source is actually triggered and tested one by one. No real hardware = Pending HIL。
- Current level (mandatory): obtain board-level measured values per Workflow C and keep them on file (supply method, board-level configuration, average current); datasheet numbers are not used as acceptance evidence.
- Battery life conclusions must give measured inputs and the estimation formula; battery life promises lacking measured inputs must not leave the door.
Pitfalls
- Do notwrite paraphrased numbers like "typical 10µA / ULP ~150µA" into the answer or calculate battery life based on them — UNVERIFIED, only board-level measurements count.
- Do notassume all wake-up sources exist on all chips — EXT1's ANY_LOW is only S2/S3/C6/H2 (baseline); verify the per-chip matrix at runtime.
- Do notleave cross-sleep state in normal RAM — deep sleep only preserves the RTC domain; data that must not be lost on power loss must go into NVS.
- Do notdescribe light sleep as "low power and stays connected" — wireless power-off is baseline-documented behavior.
- Do notUsing the GPIO class to wake up but picking a pin arbitrarily — only the RTC GPIO set is recognized; if the pin fact is uncertain, stop.
- Do notpromise users "it can last X months" without measured data — battery-life promises must have measured current input.
Official Sources
- ESP-IDF Sleep Modes
- ESP-IDF Programming Guide
- Espressif ESP32 product page (ULP/LP core distribution)
Privacy
This Skill does not collect or send user data externally; power consumption measurement records (power supply method, board-level configuration, current values) are kept locally only, and identifying information such as device serial numbers should be removed before sending them out with reports; access to official links complies with the user's environment network policy.