Deep sleep pe ESP32-C3 — cum faci tag-ul să țină toată ziua de demo
Fără deep sleep, tag-ul de la Lecția 08 ține ~6h. Cu deep sleep — câteva zile. Trucul: ESP32 doarme la 50μA în loc să stea aprins la 80mA.
Ce înveți
- De ce ESP32 pornit continuu mănâncă bateria și ce înseamnă 80mA vs 50μA
- Diferența între delay() (CPU activ) și esp_deep_sleep_start() (CPU oprit)
- Cum înlocuiești delay(2000) cu deep sleep adevărat în firmware-ul tag-ului
- Ce supraviețuiește între sleep-uri (RTC memory) și ce se pierde
- Cum măsori curentul cu multimetru ca să confirmi că funcționează
Ce ai nevoie
De ce ai nevoie de deep sleep
Tag-ul de la Lecția 08 merge — emite probe requests, VIA îl numără, totul bun. Dar dacă-l lași aprins lângă macheta orașului, după ~6 ore bateria-i moartă.
Calcul rapid: LiPo 500mAh, ESP32-C3 cu WiFi activ trage cam 80mA continuu. 500 / 80 = 6.25 ore.
Concursul tău e marți 26 mai. Demo-ul ține toată ziua — judecători dimineața, profesori la prânz, vizitatori după-amiaza. Ai nevoie de minim 8 ore, idealul ar fi să nu te gândești deloc la baterie.
Soluția: ESP32 nu trebuie să fie treaz tot timpul. Are nevoie de o burst scurt (200ms) ca să facă un scan WiFi și să emită probe-ul, după aia poate dormi 2 secunde. În somn adânc trage doar 50μA — adică 1600× mai puțin decât treaz.
delay() nu te ajută cu nimic
În codul de la Lecția 08 ai pus delay(2000) la sfârșitul loop-ului. Asta nu pune ESP-ul să doarmă — îi zice doar “nu fă nimic 2 secunde”. CPU rulează, WiFi-ul rămâne pornit, radio-ul ascultă, totul consumă.
delay(2000) la 80mA = la fel de scump ca să faci 2 secunde de scan. Pierdere totală.
Ce vrei:
esp_deep_sleep_start()— oprește CPU-ul, oprește RAM-ul, oprește aproape tot. Rămân alimentate doar RTC controller-ul și un timer mic.- La trezire ESP-ul repornește de la zero — rulează
setup()din nou, ca după reset.loop()nu mai e folosit deloc.
E o schimbare de mentalitate: în loc de “rulează în buclă”, devine “trezește-te, fă o treabă, dormi imediat”.
Codul nou
Înlocuiește complet firmware-ul de la Lecția 08 cu ăsta:
#include <WiFi.h>
#include <esp_sleep.h>
#define SLEEP_SECONDS 2
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(50);
// Burst: scan WiFi (emite probe requests)
WiFi.scanNetworks(true, true, false, 100, 1);
delay(200);
// Sleep adânc
esp_sleep_enable_timer_wakeup(SLEEP_SECONDS * 1000000ULL);
esp_deep_sleep_start();
}
void loop() {
// niciodată — setup() rulează la fiecare wake
}
Ce se întâmplă pas cu pas:
- ESP se trezește (sau pornește prima dată) →
setup()rulează. - Pornește WiFi-ul, face un scan rapid pe canalul 1 (200ms — cât să emită probe-ul).
- Programează timer-ul RTC să-l trezească peste 2 secunde (valoarea-i în microsecunde, de-aia
* 1000000). esp_deep_sleep_start()— gata, somn adânc.- Peste 2 secunde, RTC îl trezește. Go to 1.
loop() nu se mai execută niciodată pentru că esp_deep_sleep_start() nu se întoarce — practic resetează placa cu un flag care zice “tocmai m-am trezit”.
Ce se pierde, ce rămâne
Când ESP-ul intră în deep sleep:
- Se pierde: toate variabilele normale (
int x = 5;), starea WiFi, conexiunile, ce era în Serial buffer. - Rămâne: RTC memory — o zonă mică (~8KB) care e ținută alimentată. Variabilele declarate cu
RTC_DATA_ATTRsupraviețuiesc.
Exemplu dacă vrei să numeri câte trezirile:
RTC_DATA_ATTR int boot_count = 0;
void setup() {
boot_count++;
Serial.printf("Trezire #%d\n", boot_count);
// ... restul codului
}
Pentru tag-ul tău n-ai nevoie să păstrezi nimic — fiecare trezire e independentă. Dar e bun de știut dacă vrei să adaugi un identificator unic per scan, sau să clipești LED-ul doar la fiecare a 10-a trezire.
Cum confirmi că merge — măsoară curentul
Codul poate părea că rulează corect (vezi mesajele pe Serial) dar tu vrei dovada că chiar doarme la 50μA, nu că ai uitat ceva pornit.
Ai nevoie de un multimetru cu scala pe μA (majoritatea celor ieftine au — caută scala μA sau 200μA).
Montajul:
LiPo + ────[multimetru pe μA]──── TP4056 B+
LiPo − ──────────────────────── TP4056 B−
Întrerupi firul roșu între LiPo și TP4056. Pui sonda roșie a multimetrului la LiPo+, sonda neagră la TP4056 B+. Multimetrul devine parte din circuit — tot curentul trece prin el și-l măsoară.
Atenție: pornește multimetrul pe scala mA întâi (nu μA). Burst-ul de 200ms trage 80mA, dacă ai siguranța prinsă pe μA o arzi instant. După ce vezi că-i 0.05mA între burst-uri (= 50μA), poți comuta pe scala μA pentru valoarea fină.
Ce ar trebui să vezi:
- Burst (200ms, o dată la 2s): ~80mA — fulger scurt pe display.
- Între burst-uri (1.8s): ~50μA — valoarea de bază.
Dacă vezi 10mA constant între burst-uri, înseamnă că WiFi-ul n-a fost oprit cum trebuie. Verifică linia WiFi.disconnect(); și că ai pus esp_deep_sleep_start(), nu altceva.
Calcul de baterie
Curentul mediu cu deep sleep:
(0.2s × 80mA + 1.8s × 0.05mA) / 2s ≈ 8mA
Cu LiPo 500mAh:
500mAh / 8mA = 62.5 ore ≈ 2.5 zile
Față de 6h fără deep sleep = de 10× mai mult. Demo-ul de marți o să meargă fără probleme, chiar dacă-l lași pornit cu o seară înainte.
Dacă vrei și mai mult, crește SLEEP_SECONDS la 5 sau 10. VIA scanează la fiecare câteva secunde oricum — nu pierzi nimic dacă tag-ul emite mai rar. La 5s între burst-uri ajungi pe la ~5mA mediu = 100 ore.
Provocări
- LED de status — adaugă un blink scurt (50ms) din LED-ul intern la fiecare trezire. Vezi vizual că merge fără să te uiți pe multimetru. Costă ~1mA × 50ms — nimic în media totală.
- Wake pe buton — pe lângă timer, ESP-C3 poate fi trezit de un pin GPIO. Lipești un buton mic pe placă, configurezi
esp_sleep_enable_ext1_wakeupși ai un tag care doarme până-l apeși tu. Util dacă vrei să-l activezi doar când mașinuța intră în macheta. - Light sleep — un sleep mai puțin adânc, păstrează RAM-ul și WiFi-ul în standby. Trezire mai rapidă (microsecunde, nu milisecunde) dar consum mai mare (~1mA în loc de 50μA). Pentru tag-ul tău, deep sleep e alegerea bună.
Pas următor
Flashează firmware-ul nou pe toate 3 tag-urile. Lasă unul pornit cu multimetru lipit toată după-amiaza — la sfârșit ai dovada că merge. Apoi întoarce-te la proiectul VIA și actualizează rezultatele Fazei 4.5 cu autonomia confirmată.
După lecția asta, poți
- Faci orice tag pe baterie LiPo să țină 3-4 zile în loc de 6 ore
- Înțelegi diferența 80mA (treaz) vs 50μA (deep sleep) — și unde-i diferența de zile
- Salvezi variabile între cicluri de sleep folosind RTC_DATA_ATTR
- Măsori curentul real cu multimetru ca să confirmi că deep sleep merge