3.29. Modes basse consommation et veille¶
Les caméras alimentées par batterie et les capteurs actifs par intermittence n’ont pas besoin que le CPU tourne à pleine vitesse en permanence. Le module machine expose quatre états d’économie d’énergie de plus en plus profonds – active, idle(), lightsleep() et deepsleep(). Chaque cran plus profond éteint une plus grande partie de la puce et économise plus d’énergie, au prix d’un réveil plus long. Choisir le bon état est un compromis entre l’énergie économisée par la caméra et sa rapidité de réaction lorsqu’un événement survient.
3.29.1. Active¶
L’état par défaut. Le CPU exécute Python, chaque périphérique est cadencé, et le courant consommé est à son maximum – des dizaines de milliampères sur le rail logique de la caméra, plus tout ce que les accessoires connectés y prélèvent.
3.29.2. idle()¶
machine.idle() bloque l’horloge du CPU jusqu’à ce que n’importe quelle interruption se déclenche (un périphérique, un minuteur, une IRQ de broche). La RAM est active, les périphériques restent allumés, les horloges continuent de tourner – seul le CPU lui-même est en pause, et il se réveille en microsecondes dès qu’il y a du travail à faire.
Utilisez-la dans toute boucle de scrutation serrée qui attend qu’un événement externe se produise :
import machine
while not button_pressed():
machine.idle()
Le CPU cesse de brûler des cycles sur la vérification while elle-même et se réveille naturellement à l’arrivée de l’événement suivant – une petite économie qui s’accumule sur une boucle exécutée des millions de fois.
3.29.3. lightsleep()¶
machine.lightsleep() est le cran suivant. Le CPU est complètement arrêté et la plupart des horloges internes de la puce sont coupées, mais la RAM et l’état des périphériques sont préservés. Lorsque la source de réveil se déclenche, le script reprend exactement là où il a appelé lightsleep – variables, descripteurs ouverts et données en attente tous intacts – quelques millisecondes plus tard.
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
La source de réveil – ici une IRQ de broche – doit être configurée avant l’appel de veille. La consommation chute considérablement par rapport au mode actif ; le chiffre exact dépend de la carte et des périphériques encore configurés.
3.29.4. deepsleep()¶
machine.deepsleep() est l’état le plus profond. Le CPU s’arrête, les périphériques sont mis hors tension, et le contenu de la RAM peut être perdu. Les seuls éléments encore alimentés sont le circuit de réveil et une petite portion de logique toujours active.
Lorsque la source de réveil se déclenche, la puce redémarre depuis le début du script principal – deepsleep ne retourne pas. Le script distingue un réveil de deepsleep d’une mise sous tension à froid ou d’une réinitialisation matérielle à l’aide de 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
L’argument en millisecondes de deepsleep() arme en interne l’alarme RTC intégrée à la puce – c’est le RTC qui porte la temporisation de réveil à travers la veille, puisque la plupart des autres minuteurs sont hors tension. Appeler deepsleep() sans argument laisse le réveil à la charge de la source que vous avez configurée séparément (une IRQ de broche, une alarme RTC armée de l’extérieur).
Comme le script redémarre, tout ce dont l’itération suivante a besoin doit être soit reconstruit en tête de main.py, soit persisté en mémoire flash (ou dans les registres de sauvegarde du RTC, sur les puces qui en disposent). Le deepsleep offre la plus grande économie d’énergie mais impose le plus de restructuration du programme – l’application doit se comporter comme une série de courtes « rafales de mesure » séparées par des veilles, plutôt que comme une boucle longue durée avec un état en RAM.
3.29.5. Choisir un état¶
Le bon état dépend de ce que la caméra attend :
Boucle de scrutation serrée, attente de quelques millisecondes. Utilisez
idle(). Les économies sont faibles par cycle mais importantes au total, et le réveil est invisible.Inactivité de quelques secondes ou minutes entre les événements. Utilisez
lightsleep(). L’état est préservé, le réveil est rapide, et la consommation n’est qu’une fraction du mode actif.Inactivité de plusieurs minutes ou plus entre de brèves rafales de travail. Utilisez
deepsleep(). La puce est en pratique éteinte entre les événements, et la structure du script passe à une boucle réveil, mesure, veille.
Quel que soit l’état, la source de réveil compte autant que l’état lui-même – un deepsleep qui ne se réveille que sur un minuteur est une boucle de mesure à cycle de service ; un lightsleep qui se réveille sur une IRQ de broche est un capteur piloté par événement. Les fonctions de veille du module machine, les alarmes RTC et irq() fournissent ensemble les briques de base.