Mettre un Arduino en veille (deep sleep) consiste à endormir le microcontrôleur pour réduire sa consommation de plusieurs milliampères à quelques microampères, en attendant un événement qui le réveille — une interruption sur une broche ou l’échéance d’un chien de garde. C’est la clé de l’autonomie sur batterie : un objet qui dort 99 % du temps et ne se réveille que pour agir tient des mois là où, éveillé en permanence, il tiendrait des jours.
À quoi ça sert ?
Un microcontrôleur éveillé consomme en continu, même quand il ne fait rien d’utile. Il exécute sa boucle à pleine vitesse. Pour un montage alimenté en USB, peu importe. Pour un capteur sur pile (station météo, balise, traceur), c’est l’autonomie qui s’effondre. La veille renverse la logique : le système passe l’essentiel de son temps endormi, ne consommant presque rien, et ne se réveille que brièvement pour mesurer, transmettre, puis se rendort.
Le principe se résume à un cycle : dormir → se réveiller sur événement → agir vite → se rendormir. Plus la part de sommeil est grande, plus l’autonomie s’allonge. On met cela en place tard dans le projet, en phase d’intégration, comme optimisation énergétique d’un montage déjà fonctionnel, pas avant que la fonction marche.
Procédure pas à pas
Quatre étapes : choisir un mode de veille, couper les périphériques, endormir, et préparer le réveil.
1. Choisir un mode de veille
Un AVR offre plusieurs niveaux de sommeil, du plus léger au plus profond. Plus on descend, moins on consomme, mais moins il reste de moyens de se réveiller :
- Idle — le processeur s’arrête, mais les périphériques (timers, série) tournent ; réveil facile, gain modeste.
- Power-down — presque tout s’éteint, consommation minimale (quelques µA), mais seuls une interruption externe ou le chien de garde peuvent réveiller.
Pour l’autonomie, c’est power-down que l’on vise. La bibliothèque LowPower (à installer via le gestionnaire de bibliothèques) masque les détails de registres et expose ces modes simplement.
2. Couper les périphériques inutiles
En sommeil profond, les périphériques encore alimentés gâchent l’économie. On éteint notamment le convertisseur analogique (ADC) et le détecteur de baisse de tension (brown-out detector, BOD). La bibliothèque LowPower le fait par des arguments :
#include <LowPower.h>
// dort 8 s, ADC éteint, brown-out detector éteint
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);3. Endormir le microcontrôleur
L’appel à powerDown() bloque volontairement : c’est la seule attente qu’on s’autorise, puisque l’objectif est de ne rien faire. Le programme reprend juste après cette ligne au réveil.
void loop() {
faireLaMesure(); // bref réveil utile
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // puis dodo 8 s
}Le chien de garde réveille ici la carte toutes les 8 secondes (durée maximale d’un cycle WDT). Pour dormir plus longtemps, on enchaîne plusieurs cycles dans une boucle.
4. Préparer le réveil
Deux sources de réveil depuis le sommeil profond :
- le chien de garde — réveil périodique (toutes les N secondes), comme ci-dessus : idéal pour un capteur qui relève une valeur à intervalle régulier ;
- une interruption externe — réveil sur événement (un bouton, un détecteur de mouvement) : on attache l’interruption avant d’endormir, et c’est elle qui ranime la carte.
// réveil sur événement : dort indéfiniment jusqu'à une interruption sur D2
attachInterrupt(digitalPinToInterrupt(2), reveil, FALLING);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);Le gain se mesure au multimètre, en série avec l’alimentation du montage. Trois relevés suffisent à le cadrer :
| État du montage | Courant relevé |
|---|---|
| Éveillé, mesure en cours | … |
AVR nu en powerDown, ADC et BOD coupés | … (quelques µA attendus) |
| Carte Uno complète, microcontrôleur endormi | … (plusieurs mA quoi qu’il arrive) |
L’écart entre les deux dernières lignes est tout le sujet : la veille ne rend ce qu’elle promet que sur un AVR nu ou une carte conçue basse consommation. Le calcul d’autonomie complet, du courant moyen à la durée de vie d’une pile, est déroulé sur la notion.
Exemple — Capteur sur batterie réveillé périodiquement
Un capteur de température sur pile relève une mesure toutes les 32 secondes, l’envoie, puis se rendort. Comme un cycle de veille AVR dure au plus 8 secondes, on en enchaîne quatre.
#include <LowPower.h>
const int CAPTEUR = A0;
void setup() {
Serial.begin(9600);
}
void dormir(int secondes) { // enchaîne des cycles de 8 s
for (int i = 0; i < secondes / 8; i++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
void loop() {
int mesure = analogRead(CAPTEUR); // réveil utile : on mesure
Serial.println(mesure);
Serial.flush(); // s'assurer que tout est envoyé avant de dormir
dormir(32); // 4 × 8 s de sommeil profond
}Entre deux mesures, la carte ne consomme presque rien. Serial.flush() est important : sans lui, on peut s’endormir avant que l’envoi soit terminé. Sur la durée, le rapport « 32 s de sommeil pour une fraction de seconde d’éveil » transforme l’autonomie. C’est tout l’enjeu d’un objet sur pile.
Pièges
La carte Uno consomme trop pour que la veille serve à grand-chose. Le régulateur de tension et la puce USB d’une Uno tirent plusieurs milliampères en permanence, microcontrôleur endormi ou non. Le vrai gain s’obtient sur un AVR nu ou une carte conçue basse consommation (sans USB ni régulateur gourmand). Sur Uno, la mesure est surtout pédagogique.
Oublier de couper l’ADC et le brown-out. Laissés actifs, ils maintiennent une consommation qui ruine l’économie. Toujours passer ADC_OFF et BOD_OFF (ou les couper soi-même) en sommeil profond.
S’endormir avant d’avoir fini d’émettre. Le port série et les communications sont asynchrones : Serial.flush() (ou l’équivalent) garantit que l’envoi est terminé avant la mise en veille, sinon le message est tronqué.
Croire que le réveil reprend de zéro. Au réveil depuis power-down, le programme continue après la ligne de mise en veille. Il ne redémarre pas comme après un reset. Les variables sont conservées. (À ne pas confondre avec un reset par chien de garde, qui, lui, repart de setup().) Sur ESP32, c’est l’inverse : le deep sleep redémarre la puce au réveil et ré-exécute setup() (seule la RTC memory survit), à connaître si l’on porte le code (API et sources de réveil propres à l’ESP32, voir ESP32).
Câbler une source de réveil sur une broche qui ne réveille pas. En power-down, seules certaines broches d’interruption peuvent réveiller (D2/D3 sur Uno). Vérifier avant de compter dessus.
Durée de sommeil non multiple de 8 s. Le helper dormir(secondes) boucle secondes / 8 fois : la division entière tronque. dormir(32) donne bien 4 cycles (32 s), mais dormir(30) donne 30 / 8 = 3 cycles, soit 24 s. La carte dort moins que demandé, sans le moindre avertissement. Passer un multiple de 8 s, ou composer la durée avec les constantes plus fines (SLEEP_4S, SLEEP_2S, SLEEP_1S…).
Cas particulier — Réveil par chien de garde en mode interruption
Le chien de garde a deux usages opposés. En mode reset, il redémarre une carte bloquée. En mode interruption, il déclenche une routine sans redémarrer, et c’est ce second mode qui sert de réveil périodique pour la veille. La bibliothèque LowPower s’en sert en interne pour ses durées SLEEP_xS. Comprendre que le même périphérique sert à la fois de filet de sécurité et de réveil aide à ne pas s’emmêler entre les deux rôles.
Raccrochage projet
- Phase d’intégration et tests — l’optimisation énergétique vient une fois la fonction validée : on mesure la consommation, puis on introduit la veille pour atteindre l’autonomie visée par le cahier des charges.
- Spécification — l’autonomie cible (« tenir une saison sur deux piles AA ») est une exigence à poser tôt. La veille est le moyen de la tenir, à dimensionner avec le budget énergétique du montage (voir alimenter la carte).
Sur un objet connecté autonome, la veille n’est pas un détail d’optimisation mais l’architecture même du programme, d’où l’intérêt de la prévoir dès qu’une contrainte de batterie existe.
Voir aussi
- Deep sleep — la notion : les modes de veille et leur intérêt énergétique
- Arduino — hub des tutoriels Arduino
- Interruptions — la source de réveil sur événement
- Watchdog — la source de réveil périodique, et le filet de sécurité
- Alimenter la carte — budget énergétique et choix de l’alimentation
- ESP32 — une famille où la veille profonde est particulièrement soignée (objets connectés)