🛠 Sommeil profond, dormclock et PIO autonome sur batterie
Objetivos
Alimentada por una célula de Li-Ion en VSYS (el regulador buck-boost integrado mantiene 3,3 V desde ~1,8 hasta 5,5 V), la Pico puede funcionar con batería. Pero su límite de ahorro no es el de un chip «ultra-bajo consumo»: la hoja de datos indica DORMANT ≈ 0,8 mA y SLEEP ≈ 1,3 mA a 25 °C bajo 5 V, dominados por el SMPS y el soporte integrado — no son microamperios. El reto: combinar la espera WFI, el despertar por GPIO/alarma del temporizador, dormclock (reloj de 1 kHz en modo dormido) y la PIO que sigue trabajando mientras los dos núcleos duermen.
Material
- 1 × Raspberry Pi Pico + célula de Li-Ion de 3,7 V en VSYS y GND (pines 39/38) — nunca usar una Li-Ion sin protección
- Botón en GP2 (despertar, pull-up), LED en GP25
- Idealmente, un µA-metro en serie con la batería para medir la corriente real
Código completo
// dormant_pio.c — WFI + réveil GPIO, la PIO clignote pendant le sommeil
#include "pico/stdlib.h"
#include "hardware/regs/intctrl.h"
#include "hardware/xosc.h"
#include "hardware/pio.h"
#include "dormant_pio.pio.h" // programme PIO « blink » généré (pioasm)
#define BTN 2
int main(void) {
gpio_init(BTN); gpio_set_dir(BTN, GPIO_IN); gpio_pull_up(BTN);
// programme PIO : clignotement GP25 autonome (SM0, bloc PIO0)
PIO pio = pio0;
uint off = pio_add(pio, blink_program);
uint sm = pio_claim_unused_sm(pio, true);
pio_sm_init(pio, sm, off, &blink_config);
pio_sm_set_consecutive_pindirs(pio, sm, 25, 1, true);
pio_sm_config c = blink_program_get_default_config(off);
sm_config_set_set_pins(&c, 25, 1);
pio_sm_init(pio, sm, off, &c);
pio_sm_set_enabled(pio, sm, true); // la PIO tourne sans CPU ni IRQ
irq_set_enabled(IO_IRQ_BANK0, true);
while (true) {
gpio_set_irq_enabled(BTN, GPIO_IRQ_EDGE_FALL, true);
__wfi; // les 2 cœurs s'endorment ici
gpio_set_irq_enabled(BTN, GPIO_IRQ_EDGE_FALL, false);
sleep_ms(500); // réveillé : tâche courte
}
}
Para el modo dormido real (XOSC apagado, despertar solo por pin), el SDK proporciona dormant_sleep_until_32k / el patrón dormclock del libro del SDK en C: el chip permanece alimentado a 1 kHz, la PIO puede seguir funcionando si su reloj lo permite — a validar en tu placa.
Verificación esperada
Con el µA-metro: en bucle activo ~30-90 mA según USB y periféricos; en espera WFI, se baja hacia los ~1,3 mA (SLEEP según hoja de datos); en modo dormido, ~0,8 mA. La LED controlada por PIO sigue parpadeando mientras la CPU espera — la premisa «la PIO no consume CPU» también aplica al sueño. El botón despierta el bucle (LED de actividad, medición ADC, etc.).
Errores frecuentes
- Esperar microamperios: el límite lo marca el regulador integrado (~0,8-1,9 mA bajo VBUS); para obtener verdaderos µA, hay que rediseñar la alimentación o usar el chip desnudo — además, la atribución exacta al SMPS no está desglosada en la hoja de datos.
- Despertar desde modo dormido: en modo dormido profundo, solo ciertos pines (VREG/USB/PIO-IRQ según configuración) despiertan; un simple
gpio_set_irqno es suficiente, se necesita la ruta de despertar del SDK. - Olvidar que
sleep_msNO es sueño profundo: es una temporización activa del temporizador. - Forzar el regulador en modo PFM (GPIO23 flotante por defecto) y sorprenderse del ruido ADC al salir del sueño: fuerza el modo PWM antes de las mediciones.
- PIO sin reloj en modo dormido: si tu programa PIO depende del reloj principal apagado, se detiene — diséñalo para el reloj que sobrevive, o acepta la pausa.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython