🛠 Deep sleep sur batterie avec réveil par GPIO16
Objectifs
Transformer l'ESP8266-ESP-12E en capteur sur batterie : en deep sleep, la puce consomme de l'ordre de la dizaine de microampères contre plusieurs dizaines de milliampères en fonctionnement Wi-Fi, ce qui permet des autonomies de plusieurs mois. Le réveil est assuré par le timer RTC interne, et le câblage obligatoire GPIO16 → RST permet aussi un réveil externe (GPIO16 génère une impulsion qui relance le module via la broche reset). Point crucial : le deep sleep efface toute la RAM — aucun compteur, aucune variable ne survit ; on utilise la mémoire RTC (RTC_SLOW_MEM) pour conserver un état entre les réveils, et il faut tout réinitialiser à chaque démarrage.
Matériel
- 1 module ESP8266-ESP-12E nu (les cartes NodeMCU complètes consomment 30 à 50 mA de trop à cause du régulateur et du pont USB)
- 1 batterie LiPo 3,7 V + régulateur LDO 3,3 V à faible consommation (type XC6206, Iq ≈ 1 µA)
- 1 fil reliant GPIO16 à RST (obligatoire pour le réveil)
- Condensateur 100 µF en sortie du régulateur
- LED de test à DÉCONNECTER pour les mesures d'autonomie (elle consommerait 5 mA en permanence)
Code complet
#include <ESP8266WiFi.h>
// Memoire RTC : survit au deep sleep (RAM classique : effacee !)
RTC_DATA_ATTR uint32_t compteur = 0;
extern "C" {
#include "user_interface.h"
}
void setup {
Serial.begin(115200);
compteur++;
Serial.printf("\nReveil n°%u raison: %s\n", compteur,
user_rtc_get_reset_reason == POWERON_RESET ? "mise sous tension" : "deep sleep");
// --- Travail court : lecture capteur, mesure batterie ---
uint32_t vbat = ESP.getVcc; // mV (si calibration AD0 faite)
Serial.printf("Vcc=%u mV\n", vbat);
// Optionnel : publier en Wi-Fi puis attendre 1 s que le paquet parte
// WiFi.mode(WIFI_STA); WiFi.begin(SSID, PASS);
// unsigned long t0 = millis;
// while (WiFi.status != WL_CONNECTED && millis - t0 < 8000) delay(50);
// ... publish MQTT ...
// WiFi.forceSleepBegin; // radio off avant de dormir
Serial.println("Endormissement 30 s (GPIO16 doit être cablee a RST)");
Serial.flush;
delay(50);
ESP.deepSleep(30 * 1000000ULL); // 30 s ; 0 = attendre un réveil externe
}
void loop {
// Jamre atteint : deepSleep ne revient jamais
}
Vérification attendue
Débranche/rebranche : le compteur repart à 1 (la mémoire RTC est aussi perdue sans alimentation), puis le module affiche « Reveil n°1 » et dort. Toutes les 30 secondes environ, un nouveau réveil s'affiche avec le compteur incrémenté (2, 3, 4...) alors que le module n'a pas été touché — preuve que le timer RTC et le fil GPIO16→RST fonctionnent. Au multimètre en série avec la batterie, le courant doit retomber à quelques centaines de µA en moyenne (hors régulateur de la carte de dev). Avec deepSleep(0), le module ne se réveille plus que si tu relies brièvement RST à la masse.
Erreurs fréquentes
- Oublier le fil GPIO16 → RST : le timer RTC expire mais personne ne relance le module, il reste endormi éternellement.
- Compter sur une variable classique pour compter les réveils : la RAM est effacée, seul RTC_DATA_ATTR (RTC_SLOW_MEM, 512 octets) survit.
- Tester avec une LED sur GPIO2 : elle tire 5 mA en permanence et ruine l'autonomie ; GPIO2 est de plus sensible au boot.
- Utiliser une carte NodeMCU complète « pour mesurer l'autonomie » : le régulateur embarqué et le pont USB consomment bien plus que le module lui-même.
- deepSleep avec un delay de transmission Wi-Fi trop court : les derniers paquets sont perdus, laisse ~1 s ou coupe la radio avec forceSleepBegin avant de dormir.
- GPIO16 n'a ni interruption, ni PWM, ni I2C : ne pas essayer de l'utiliser pour autre chose que le réveil.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht11.inoArduinoluxmetre.inoArduinoserveur-web.inoArduino