Lekce 3 - Mód hlubokého spánku na modulu ESP-32
V předchozí lekci, Přerušení a časovač na modulu ESP-32, jsme se seznámili s možností přerušení a časování na modulu ESP-32.
V dnešním tutoriálu Internetu věcí s ESP32 nás bude zajímat mód hlubokého spánku na mikrokontroleru ESP-32, který tento modul poskytuje zejména kvůli úspoře energie.
ESP-32 a úspora energie
Modul ESP-32 nabízí různé možnosti módů pro úsporu energie, které uživateli umožňují snížit spotřebu tím, že deaktivuje některé operace. Je to v podstatě podobné, jako bychom dávali počítač do režimu spánku za účelem úspory elektrické energie. Z těchto režimů je velmi často využívaný mód Deep Sleep, kterému se dnes budeme věnovat. I když se o tomto módu mluví jako o módu hlubokého spánku, není to mód, který ušetří nejvíce energie. Tím je režim hibernace. Následující tabulka zobrazuje spotřebu energie při různých režimech:
Režim | Popis | Spotřeba energie |
---|---|---|
Modem-sleep | CPU je napájen, rychlosti jsou: 240 MHz, 160 MHz nebo 80 MHz | 20mA - 68 mA |
Light-sleep | - | 0,8mA |
Deep-sleep | ULP koprocesor je napájen, je kontrolována jeho činnost a zároveň běží RTC časovač a paměť | 10μ - 150μA |
Hibernace | Běží pouze RTC časovač | 5μA |
Vypnuto | CHIP_PU je na nízké úrovni, čip samotný je vypnutý | 1μA |
Podrobnější informace lze nalézt v oficiálním datasheetu od výrobce.
K čemu vlastně je režim hlubokého spánku?
Tento režim je velmi vhodné použít hlavně při napájení modulu z baterie a to zejm. v případech, kdy celý modul funguje periodicky. Například jako meteostanice, která posílá data přes Wi-Fi nebo Bluetooth každých 15 minut.
Po aktivaci Deep Sleep módu se ESP-32 přepne do co nejzákladnějšího stavu. To znamená, že se oba CPU vypnou a veškeré operace si přebírá tzv. ULP (Ultra Low Processor). Tento procesor je ale velmi jednoduchý a zvládne řešit jen základní operace. Při zapnutém Deep Sleep módu jsou vypnuty tyto důležité části:
- Flash a RAM paměti,
- WiFi modul,
- Bluetooth modul.
Napájena však zůstává RTC (Real Time Clock) paměť a lze s ní nadále pracovat.
Způsoby probuzení z Deep Sleep módu
Ještě než se dostaneme k praktické ukázce, pojďme si říct něco málo o tom, jak se mikrokontroler přepíná zpět do běžného režimu. Na výběr máme z několika možností:
- použití integrovaného časovače, kdy se ESP-32 probudí po určité době,
- použití kapacitních dotykových senzorů,
- použití RTC pinů.
Zdroje probuzení lze různě kombinovat.
Další z možnosti je samozřejmě také to, že vůbec nemusíme nastavit jakýkoli zdroj probuzení. V tom případě zůstane ESP-32 v Deep Sleep módu nepřetržitě. Jedinou možností, jak jej probudit je buď ruční reset pomocí EN/RST na desce nebo znovupřipojení desky. Nikdy tedy nelze zablokovat celý mikrokontroler tím, že jej necháme neustále v Deep Sleep módu.
Aktivace a probuzení z Deep Sleep módu
Když už máme teoretický základ, pojďme si nyní přiblížit, jak lze
aktivovat Deep Sleep mód a jak nakonfigurovat zdroje probuzení. Pro aktivaci
Deep Sleep módu se používá funkce esp_deep_sleep_start()
. Jako
zdroje probuzení v této lekci použijeme časovač a
GPIO pin. Pro reálné projekty si pak vždy musíme nejprve
uvědomit a rozvrhnout:
- jaký způsob probuzení bude pro daný projekt nejlepší (každý zdroj probuzení má odlišnou spotřebu energie, odchylka je však velmi zanedbatelná – v µA),
- které piny můžeme vypnout a které ne. Ve výchozím nastavení mikrokontroleru ESP-32 je, že vypne všechny periferie, které nejsou potřeba k rozpoznání signálu k probuzení.
Použití časovače jako zdroj probuzení
Tento způsob je ten nejméně náročný, co se týče spotřeby energie. Jak již víme, v Deep Sleep módu funguje mj. RTC časovač. Ten nám zajistí, že se mikrokontroler probudí automaticky po námi určeném časovém úseku. Pojďme si tedy sestavit jednoduchý program, ve kterém využijeme časovač jako zdroj probuzení:
#define uS_NA_S 1000000 #define DELKA_SPANKU 5
První makro je převodník mezi mikrosekundami a sekundami, který později využijeme při konfiguraci délky spánku. Druhé makro určuje časový úsek, který udává dobu, jak dlouho bude mikrokontroler ve spánku.
Abychom si udrželi přehled o tom, kolikrát se náš mikrokontroler probudil ze spánku, vytvoříme si k tomu proměnnou, která bude počet probuzení počítat:
RTC_DATA_ATTR int pocetBootovani = 0;
Makro RTC_DATA_ATTR
je definované v ESP-IDF, což je
oficiální vývojový rámec pro ESP32 a jiné čipy od Espressif. Toto makro
se používá při deklaraci proměnných, které chceme, aby přetrvaly mezi
různými probuzeními z hlubokého spánku. RTC_DATA_ATTR
umístí
proměnnou do RTC paměti, o níž jsme si řekli, že zůstává
napájená.
Nyní si pojďme sestavit funkci, která do sériového monitoru vypíše informaci o tom, čím bylo způsobeno probuzení čipu:
void vypisZdrojProbuzeni(){ esp_sleep_wakeup_cause_t zdrojProbuzeni; zdrojProbuzeni = esp_sleep_get_wakeup_cause(); switch(zdrojProbuzeni) { case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Cip probuzen externim signalem - RTC_IO"); break; case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Cip probuzen externim signalem - RTC_CNTL"); break; case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Cip probuzen casovacem"); break; case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Cip probuzen dotykovym senzorem"); break; default : Serial.printf("Jiny zdroj probuzeni: %d\n",zdrojProbuzeni); break; } }
V této funkci si jednoduše přiřadíme do proměnné
zdrojProbuzeni
hodnotu a poté ji ve vícenásobném větvení
porovnáme a vypíšeme na monitor odpovídající informaci.
Přesuňme se nyní do funkce setup()
. Nejdříve nastavíme
intenzitu sériového monitoru:
Serial.begin(115200); delay(1000);
Pak inkrementujeme počet nabootování a vypíšeme informaci o tom, kolikrát se již ESP-32 probudil:
++pocetBootovani;
Serial.println("Boot c. " + String(pocetBootovani));
Nyní je prostor pro operace, které chceme aby mikrokontroler provedl po
probuzení ze spánku, např. čtení dat z nějakého senzoru atp. Náš kód
pouze zavolá námi vytvořenou funkci vypisZdrojProbuzeni()
, díky
které zjistíme, co bylo impulsem pro probuzení:
vypisZdrojProbuzeni();
V dalším kroku nastavíme časovač s pomocí vytvořených maker. Jelikož chceme, aby mikrokontroler sám provedl výpočet délky spánku, vynásobíme časový úsek v sekundách naším převodníkem a vypíšeme informaci na monitor:
esp_sleep_enable_timer_wakeup(DELKA_SPANKU * uS_NA_S); Serial.println("Casova prodleva spanku: " + String(DELKA_SPANKU) + "s");
A jako poslední krok opět uspíme mikrokontroler a můžeme otestovat správnou funkčnost kódu:
Serial.println("Aktivuji mod hlubokeho spanku..."); delay(1000); Serial.flush(); esp_deep_sleep_start(); Serial.println("Testovaci zprava, nikdy se nevypisu");
Funkce loop()
nás opět nezajímá, protože nebude nikdy
zavolána, tudíž je zbytečné ji jakkoli definovat.
Použití GPIO pinu jako zdroj probuzení
Jako způsob probuzení lze také použít vnější impuls. V našem případě využijeme tlačítko. Typicky tento princip využívají zařízení, které se probudí hned po stisku tlačítka, např. mobily, tablety atd. Co se týče spotřeby baterie, je zde trošičku vyšší než při využití časovače. Rozdíl je ale v cca 2 µA, tudíž téměř zanedbatelný.
Pozor, pro tento způsob probuzení lze použít pouze RTC_GPIO piny.
Pojďme si nyní sestavit jednoduchý obvod. Budeme potřebovat:
- ESP-32,
- rezistor,
- tlačítko,
- propojovací vodiče.
Do nepájivého pole součástky osadíme následovně:

Máme zdárně zapojeno a můžeme se přesunout ke kódu. Hlavička je opět velmi jednoduchá, pouze si zadeklarujeme proměnnou, která bude, stejně jako u minulého příkladu, počítat počet nabootování:
RTC_DATA_ATTR int pocetBootovani = 0;
Testovací funkci vypisZdrojProbuzeni()
už máme hotovou, a tak
se rovnou přesuňme do funkce setup()
:
void setup(){ Serial.begin(115200); ++pocetBootovani; Serial.println(String(pocetBootovani)+ ". nabootovani"); vypisZdrojProbuzeni(); esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,HIGH); Serial.println("Aktivuji mod hlubokeho spanku..."); esp_deep_sleep_start(); }
Místo funkce esp_sleep_enable_timer_wakeup()
využijeme funkci
esp_sleep_enable_ext0_wakeup()
, která přijímá dva parametry.
První parametr určuje, na který pin je přivedeno tlačítko. V našem
případě to je pin GPIO_NUM_33
. Druhý parametr pak určuje, při
jaké hodnotě na tlačítku má být vyslán signál pro probuzení. Funkce
loop()
opět zůstane prázdná, stejně jako v předešlém
případě. Tím jsme zdárně dokončili náš program, který vždy po
stisknutí tlačítka probudí mikrokontroler ESP-32 z módu hlubokého
spánku.
Oba kompletní programy jsou připojeny v archivu pod lekcí.
V příští lekci, Webový server na modulu ESP-32, začneme pracovat na webovém serveru na modulu ESP-32.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 56x (1.95 kB)
Aplikace je včetně zdrojových kódů v jazyce C++