🛠 Sommeil profond, dormclock et PIO autonome sur batterie
Objectifs
Alimentée par une cellule Li-Ion sur VSYS (le régulateur buck-boost embarqué tient 3,3 V de ~1,8 à 5,5 V), la Pico peut fonctionner sur batterie. Mais son plancher d'économie n'est pas celui d'une puce « ultra-low-power » : la datasheet annonce DORMANT ≈ 0,8 mA et SLEEP ≈ 1,3 mA à 25 °C sous 5 V, dominés par le SMPS et le support embarqué — pas des microampères. L'enjeu : combiner attente WFI, réveil par GPIO/alarme du timer, dormclock (horloge 1 kHz en dormant) et PIO qui continue de travailler pendant que les deux cœurs dorment.
Matériel
- 1 × Raspberry Pi Pico + cellule Li-Ion 3,7 V sur VSYS et GND (broches 39/38) — jamais de Li-Ion non protégée
- Bouton sur GP2 (réveil, pull-up), LED GP25
- Idéalement un µA-mètre en série avec la batterie pour mesurer le vrai courant
Code complet
// 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
}
}
Pour le vrai mode dormant (XOSC coupé, réveil par broche uniquement), le SDK fournit dormant_sleep_until_32k / le pattern dormclock du livre C SDK : le chip reste alimenté en 1 kHz, la PIO peut continuer si son horloge le permet — à valider sur ta carte.
Vérification attendue
Avec le µA-mètre : en boucle active ~30-90 mA selon USB et périphériques ; en attente WFI, on descend vers les ~1,3 mA (SLEEP datasheet) ; en dormant, ~0,8 mA. La LED PIO continue de clignoter pendant que le CPU attend — la consigne « la PIO ne consomme pas de CPU » vaut aussi pour le sommeil. Le bouton réveille la boucle (LED d'activité, mesure ADC, etc.).
Erreurs fréquentes
- Attendre du µA : le plancher est le régulateur embarqué (~0,8-1,9 mA sous VBUS) ; pour du vrai µA, il faut redessiner l'alimentation ou utiliser la puce nue — l'attribution exacte au SMPS n'est d'ailleurs pas décomposée par la datasheet.
- Réveil dormant : en mode dormant profond, seules certaines broches (VREG/USB/PIO-IRQ selon config) réveillent ; un simple
gpio_set_irqne suffit pas, il faut le chemin dormant du SDK. - Oublier que
sleep_msn'est PAS du sommeil profond : c'est une temporisation active du timer. - Forcer le régulateur en mode PFM (GPIO23 flottant par défaut) et s'étonner du bruit ADC en sortie de sommeil : force le mode PWM avant les mesures.
- PIO sans horloge en dormant : si ton programme PIO dépend du clock principal coupé, il s'arrête — conçois-le pour l'horloge qui survit, ou accepte la pause.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython