🛠 Deep sleep sur batterie avec réveil par GPIO16
Objetivos
Transformar el ESP8266-ESP-12E en un sensor alimentado por batería: en modo deep sleep, el chip consume del orden de decenas de microamperios frente a varias decenas de miliamperios en funcionamiento Wi-Fi, lo que permite autonomías de varios meses. El despertar lo asegura el temporizador RTC interno, y el cableado obligatorio GPIO16 → RST permite también un despertar externo (GPIO16 genera un impulso que reinicia el módulo a través del pin reset). Punto crucial: el deep sleep borra toda la RAM —ningún contador, ninguna variable sobrevive—; se utiliza la memoria RTC (RTC_SLOW_MEM) para conservar un estado entre despertares, y hay que reinicializarlo todo en cada arranque.
Material
- 1 módulo ESP8266-ESP-12E desnudo (las placas NodeMCU completas consumen 30 a 50 mA de más debido al regulador y al puente USB)
- 1 batería LiPo de 3,7 V + regulador LDO de 3,3 V de bajo consumo (tipo XC6206, Iq ≈ 1 µA)
- 1 cable que une GPIO16 con RST (obligatorio para el despertar)
- Condensador de 100 µF a la salida del regulador
- LED de prueba que se debe DESCONECTAR para las mediciones de autonomía (consumiría 5 mA permanentemente)
Código completo
#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 etre cablee a RST)");
Serial.flush;
delay(50);
ESP.deepSleep(30 * 1000000ULL); // 30 s ; 0 = attendre un reveil externe
}
void loop {
// Jamre atteint : deepSleep ne revient jamais
}
Verificación esperada
Desconecta y vuelve a conectar: el contador vuelve a empezar en 1 (la memoria RTC también se pierde sin alimentación), luego el módulo muestra «Reveil n°1» y duerme. Aproximadamente cada 30 segundos, aparece un nuevo despertar con el contador incrementado (2, 3, 4...) aunque no se haya tocado el módulo —prueba de que el temporizador RTC y el cable GPIO16→RST funcionan. Con el multímetro en serie con la batería, la corriente debe bajar a unos cientos de µA de media (sin contar el regulador de la placa de desarrollo). Con deepSleep(0), el módulo solo vuelve a despertar si conectas brevemente RST a masa.
Errores frecuentes
- Olvidar el cable GPIO16 → RST: el temporizador RTC expira pero nadie reinicia el módulo, que permanece dormido eternamente.
- Confiar en una variable clásica para contar los despertares: la RAM se borra, solo RTC_DATA_ATTR (RTC_SLOW_MEM, 512 bytes) sobrevive.
- Probar con un LED en GPIO2: consume 5 mA permanentemente y arruina la autonomía; además, GPIO2 es sensible durante el arranque.
- Usar una placa NodeMCU completa «para medir la autonomía»: el regulador integrado y el puente USB consumen mucho más que el propio módulo.
- deepSleep con un delay de transmisión Wi-Fi demasiado corto: se pierden los últimos paquetes, deja ~1 s o apaga la radio con forceSleepBegin antes de dormir.
- GPIO16 no tiene interrupciones, ni PWM, ni I2C: no intentes usarlo para otra cosa que el despertar.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht11.inoArduinoluxmetre.inoArduinoserveur-web.inoArduino