(Nízka) spotreba energie

problém spotreby energie v IoT riešeniach, o kapacite batérií a ich životnosti, riadenie spotreby energie pomocou softvéru, low power, polling, prerušenia, typy prerušení, ISR, výhody a nevýhody používania prerušení

Problém spotreby energie v IoT

(slide) Internet vecí so svojím príchodom priniesol niekoľko zaujímavých tém, ktoré je potrebné riešiť. Patria medzi ne napríklad bezpečnosť, ergonómia, technológie pre komunikáciu, ale hlavne nízka spotreba zariadení. Zariadenia IoT sú totiž často napájané batériou, pretože sú umiestnené na miestach, kde prístup k elektrickej sieti nie je možný.

(slide) Hľadanie spôsobov, ako zabezpečiť nízku spotrebu, však neprinieslo až IoT. Už dávno predtým sme tu mali kalkulačky, diaľkové ovládače, digitálne hry, ale aj notebooky alebo mobilné telefóny. Všetky tieto zariadenia boli napájané z batérií. IoT zariadenia však predstavujú špeciálnu skupinu zariadení, od ktorých sa očakáva, že budú pracovať bez zásahu používateľa mesiace až roky a pred vyčerpaním batérie s dostatočným predstihom upozornia, že je potrebné ju vymeniť. Energeticky autonómne zariadenia sú totiž základom IoT.

Spotreba zariadenia

Skôr ako začneme spotrebu znižovať, pozrime sa, ako zariadenie energiu vlastne spotrebúva.

(slide) Náš chytrý senzor je z pohľadu fyziky elektrický obvod. Aby mohol fungovať, musí byť obvod uzavretý, a preto ho pripájame k zdroju napájania, napríklad k batérii. Zdroj poskytuje obvodu určité napätie a obvod si z neho odoberá prúd. Koľko prúdu obvod odoberá, neurčuje zdroj, ale samotný obvod, teda to, ktoré jeho časti práve pracujú. Preto keď hovoríme o odbere zariadenia, máme na mysli prúd, ktorý zariadenie zo zdroja odoberá.

Čím viac častí zariadenia pracuje, tým väčší je jeho odber (pozri obrázok 1). Napätie zdroja sa pritom (približne) nemení.

Obr. 1: Chytré zariadenie ako elektrický obvod

Pracovný cyklus

(slide) Každé zariadenie pracuje inak. Senzor napájaný z batérie obyčajne odmeria údaje a zaspí, aby vydržal pracovať čo najdlhšie. Niektoré senzory majú trvalé napájanie, vďaka čomu nepotrebujú spať. Podobne je to aj s mnohými akčnými členmi – musia byť neustále pripravené vykonať svoju činnosť, a preto bývajú obyčajne napájané trvalo. Trvalé napájanie umožňuje zariadeniam poskytovať aj služby, ktoré by si pri napájaní z batérie kvôli spotrebe nemohli dovoliť. Príkladom môže byť webové rozhranie, v ktorom môže používateľ zariadenie nastaviť alebo si pozrieť jeho aktuálne namerané hodnoty.

Na obrázku 2 sa nachádza ukážka odberu fiktívneho senzora počas jedného pracovného cyklu. Tento senzor väčšinu času pracovného cyklu spí. V pravidelných intervaloch sa zobudí (v našej ukážke je to každých 15 minút), inicializuje svoje periférie, odmeria potrebné veličiny, pripojí sa do siete, odošle namerané údaje, odpojí sa a znova zaspí.

Obr. 2: Odber zariadenia počas jedného pracovného cyklu (ilustračné hodnoty)

Túto postupnosť činností, ktorú zariadenie stále dokola opakuje, nazývame pracovný cyklus. Pracovný cyklus má aj zariadenie, ktoré nespí. Chýba v ňom len spánok, a preto jeho odber medzi jednotlivými činnosťami nikdy neklesne tak nízko ako odber spiaceho zariadenia.

Odber zariadenia teda nie je stály. Mení sa vždy, keď zariadenie prejde do iného stavu alebo keď zapne či vypne niektorú zo svojich periférií. Najvyšší odber je počas komunikácie cez WiFi, a najnižší počas spánku.

Špičky odberu

Krátkodobé prudké zvýšenie odberu nazývame špička (z angl. peak). Najvyššie špičky vznikajú vtedy, keď rádio vysiela, teda pri pripájaní do siete aj pri odosielaní údajov. Trvajú len veľmi krátko, ale zdroj napájania ich musí zvládnuť. Ak by ich nezvládol, napätie by na okamih kleslo a zariadenie by sa mohlo reštartovať (pozri podkapitolu Podpätie).

Pre ich krátke trvanie ich navyše bežný merací prístroj nemusí zachytiť. Na ich meranie je potrebný prístroj, ktorý dokáže odber merať minimálne tisíckrát za sekundu.

Okamžitý odber

(slide) Ak odmeriame prúd, ktorý preteká zariadením v istom momente počas jeho činnosti, zistíme jeho okamžitý odber (pozri obrázok 3). V závislosti od toho, kedy meriame, môžeme namerať 1,5 mA, ale aj 90 mA.

Obr. 3: Okamžitý odber zariadenia v jednom okamihu pracovného cyklu (ilustračné hodnoty)

Spotreba pracovného cyklu

Z jednej nameranej hodnoty sa však nedozvieme, koľko zariadenie spotrebuje počas celého pracovného cyklu. Odber sa počas cyklu neustále mení, a preto musíme zohľadniť nielen to, aký veľký prúd zariadenie odoberá, ale aj to, ako dlho ho odoberá. Krátka vysoká špička tak môže zariadenie stáť menej ako dlhší mierny odber.

(slide) Prúd vyjadruje, aký elektrický náboj (označujeme ho \(Q\)) pretečie obvodom za jednotku času. Za predpokladu, že je prúd stály (v čase sa nemení), vieme náboj \(Q\), ktorý pretečie za čas \(t\), vyjadriť ako súčin prúdu a času:

\[Q = I \cdot t\]

Zariadenie, ktoré odoberá stály prúd 50 mA počas 2 sekúnd, teda odoberie zo zdroja náboj 100 mAs. V grafe závislosti prúdu od času predstavuje tento náboj plochu obdĺžnika, ktorého výška je prúd a šírka je čas.

Odber zariadenia však počas pracovného cyklu stály nie je. Pracovný cyklus preto môžeme rozdeliť na veľmi krátke časové úseky, počas ktorých sa odber takmer nemení. Náboj odobraný v každom z nich je plochou úzkeho obdĺžnika a ich súčtom dostaneme náboj odobraný počas celého cyklu. Náboj, ktorý zariadenie odobralo zo zdroja počas jedného pracovného cyklu, je teda plocha pod krivkou odberu (pozri obrázok 4).

Obr. 4: Elektrický náboj odobraný počas jedného pracovného cyklu (ilustračné hodnoty)

(slide) Čím kratšie úseky zvolíme, tým presnejší výsledok dostaneme. Matematicky túto plochu vypočítame ako určitý integrál prúdu podľa času:

\[Q = \int_0^T i(t)\,dt\]

kde \(i(t)\) je okamžitý odber v čase \(t\) a \(T\) je dĺžka pracovného cyklu. Rovnakým spôsobom určujú náboj aj meracie prístroje: v pravidelných krátkych intervaloch odmerajú prúd a súčiny nameraného prúdu a dĺžky intervalu sčítavajú.

Jednotkou náboja je súčin jednotky prúdu a času. Základnou jednotkou je ampérsekunda (As), ktorá sa nazýva aj coulomb (C). Pri batériách sa náboj udáva v miliampérhodinách (mAh), pretože ich výdrž sa počíta v hodinách. Napríklad batéria s kapacitou 1000 mAh dokáže teoreticky dodávať prúd 1000 mA počas jednej hodiny alebo 10 mA počas 100 hodín.

Výdrž batérie

(slide) Pri návrhu každého zariadenia pre internet vecí, ktoré je napájané z batérie, je dôležité vedieť, ako dlho vydrží na jednu batériu. Odpoveď závisí od dvoch vecí:

  • od kapacity batérie, a
  • od spotreby zariadenia.

Kapacita batérie

(slide) Pri batériách sa stretneme s dvoma veličinami, ktoré sa často zamieňajú: kapacitou a energiou. Rozdiel si najľahšie predstavíme na nádrži s vodou, ktorá poháňa vodné koleso. Množstvo vody v nádrži zodpovedá kapacite batérie a výška, z ktorej voda padá, zodpovedá napätiu. Koleso dokáže vykonať tým viac práce, čím viac vody v nádrži je a čím z väčšej výšky padá. Táto práca zodpovedá energii batérie. Dve nádrže s rovnakým množstvom vody teda môžu vykonať rôzne veľkú prácu, ak sú v rôznej výške (pozri obrázok 5).

Obr. 5: Kapacita a energia batérie ako nádrž s vodou: rovnaké množstvo vody z väčšej výšky vykoná viac práce

(slide) Kapacita batérie teda udáva, aký elektrický náboj dokáže batéria dodať. Udáva sa v ampérhodinách (Ah), resp. v miliampérhodinách (mAh). Batéria s kapacitou 1 Ah dokáže teoreticky dodávať prúd 1 A počas 1 hodiny alebo prúd 100 mA počas 10 hodín.

Kapacita však neudáva, koľko energie batéria obsahuje. Energia závisí aj od napätia batérie a udáva sa vo watthodinách (Wh):

\[ E = Q \cdot U \]

kde \(E\) je energia batérie vo watthodinách (Wh), \(Q\) jej kapacita v ampérhodinách (Ah) a \(U\) jej nominálne napätie vo voltoch (V).

Napríklad alkalická batéria AA s kapacitou 2500 mAh a napätím 1,5 V obsahuje približne 3,75 Wh energie, zatiaľ čo lítiový článok s rovnakou kapacitou a napätím 3,7 V obsahuje približne 9,25 Wh. Pri porovnávaní batérií s rôznym napätím preto treba porovnávať energiu, nie kapacitu.

(slide) Kapacita uvedená na batérii navyše platí len za presne určených podmienok. Skutočná kapacita závisí najmä od:

  • odoberaného prúdu – čím väčší prúd, tým menej náboja batéria dodá; napríklad alkalická batéria Energizer EN91 veľkosti AA dodá pri odbere 25 mA približne 2850 mAh, ale pri odbere 500 mA len približne 1400 mAh (katalógový list),
  • konečného napätia – výrobca udáva kapacitu do určitého napätia, pri alkalických batériách zvyčajne do 0,8 V; ak zariadenie prestane pracovať skôr, využije len časť kapacity,
  • teploty – pri nízkych teplotách kapacita výrazne klesá, čo je dôležité pri zariadeniach umiestnených vonku.

Kapacita a napätie batérie závisia najmä od jej chemického zloženia. Prehľad typických batérií, s ktorými sa pri IoT zariadeniach stretneme, sa nachádza v tabuľke 1. Hodnoty sú uvedené pre konkrétne batérie podľa katalógových listov výrobcov, batérie od iných výrobcov sa môžu líšiť.

Tab. 1: Typické batérie pre IoT zariadenia
Batéria Chemické zloženie Napätie Kapacita Energia Nabíjateľná Poznámka
AA alkalická (Energizer EN91) Zn/MnO₂ 1,5 V 2850 mAh 4,3 Wh nie kapacita výrazne klesá pri väčšom odbere
AA lítiová (Energizer L91) Li/FeS₂ 1,5 V 3000 mAh 4,5 Wh nie kapacitu si drží aj pri odbere 1 A
AA NiMH (Panasonic eneloop) NiMH 1,2 V 1900 mAh 2,3 Wh áno nízke samovoľné vybíjanie (70 % po 10 rokoch)
18650 (Samsung INR18650-25R) Li-Ion 3,6 V 2500 mAh 9 Wh áno dokáže dodávať prúd až 20 A
mincová CR2032 (Energizer) Li/MnO₂ 3 V 254 mAh 0,8 Wh nie určená len pre malý odber

Údaje pochádzajú z katalógových listov batérií Energizer EN91, Energizer L91, Panasonic eneloop, Samsung INR18650-25R a Energizer CR2032. Výrobcovia merajú kapacitu za rôznych podmienok, preto hodnoty slúžia len na hrubé porovnanie.

Zaujímavé je porovnanie alkalickej a lítiovej batérie veľkosti AA. Pri malom odbere majú podobnú kapacitu, ale pri odbere 1 A dodá lítiová batéria stále približne 3000 mAh, zatiaľ čo alkalická len približne 1000 mAh (katalógový list Energizer L91). Pre zariadenia s veľkými špičkami odberu, ako je napr. pripájanie do WiFi siete, je preto lítiová batéria vhodnejšia.

Nabíjateľné alebo nenabíjateľné batérie

(slide) Nabíjateľné batérie sú výhodné v zariadeniach, ktoré sa používajú denne a dajú sa ľahko nabiť, ako napr. mobilné telefóny, fotoaparáty alebo bezdrôtové myši. Pri IoT zariadeniach je však situácia iná. Zariadenie väčšinu času spí, zobudí sa len na krátky čas a batéria v ňom má vydržať mesiace až roky. Pri takomto použití sa stáva dôležitým samovoľné vybíjanie, teda strata energie aj vtedy, keď sa batéria nepoužíva.

Nenabíjateľné (primárne) batérie majú samovoľné vybíjanie veľmi nízke. Napríklad lítiová batéria Energizer L91 si podľa výrobcu zachová 90 % kapacity po 15 rokoch skladovania (katalógový list). Bežné nabíjateľné batérie sa naopak môžu samovoľne vybiť za niekoľko mesiacov. Preto sa v batériových IoT zariadeniach zvyčajne používajú alkalické batérie, alebo pri požiadavke na dlhú výdrž, veľké špičky odberu či nízke teploty lítiové batérie.

Nabíjateľné batérie majú v IoT zariadeniach zmysel najmä vtedy, ak:

  • ich je možné nabíjať priamo v zariadení, napr. zo solárneho článku alebo z USB portu,
  • sa použijú batérie s nízkym samovoľným vybíjaním, ako napr. NiMH batérie Panasonic eneloop z tabuľky 1.

Pri výbere nabíjateľných batérií však treba myslieť aj na ich odlišné vlastnosti:

  • napätie – článok NiMH má napätie 1,2 V namiesto 1,5 V, takže zariadenie navrhnuté pre alkalické batérie s nimi nemusí pracovať správne; článok Li-Ion má napätie 3,6 V až 4,2 V a zariadenie preto potrebuje vhodný stabilizátor alebo menič,
  • nabíjanie a ochrana – lítiové články potrebujú riadené nabíjanie a ochranný obvod proti prebitiu, úplnému vybitiu a skratu,
  • teplota – lítiové články sa nesmú nabíjať pri teplotách pod bodom mrazu, čo je dôležité pri zariadeniach umiestnených vonku.

Podpätie

Pri výbere batérie si je tiež dobré uvedomiť, že celkovú spotrebu ovplyvňuje spotreba jednotlivých komponentov. Niektoré náročnejšie senzory dokonca krátkodobo vyžadujú veľmi veľký prúd aj napriek tomu, že počas bežnej prevádzky, resp. pri uspaní je ich spotreba minimálna. Po zobudení alebo pri pripájaní (napr. niektoré komunikačné moduly) sú však schopné krátkodobo vyžadovať odber aj 2 A. Batéria teda musí byť pripravená v závislosti od komponentov IoT zariadenia aj na takúto krátkodobú záťaž.

(slide) Pri veľkom odbere súvisí s batériou problém podpätia (z angl. undervoltage, resp. brown-out). Každá batéria má vnútorný odpor, preto jej napätie pri väčšom odbere klesne. Napríklad alkalická batéria Energizer EN91 má podľa výrobcu vnútorný odpor 150 až 300 mΩ (katalógový list) a s postupným vybíjaním sa zvyšuje.

Vnútorný odpor \(R_i\) je so zariadením zapojený do série. Keď zariadenie odoberá prúd \(I\), vznikne na vnútornom odpore úbytok napätia a na svorky batérie sa dostane menšie napätie:

\[U = U_0 - I \cdot R_i\]

kde \(U_0\) je napätie batérie naprázdno, teda bez záťaže. Úbytok napätia je úmerný odberu. Pri odbere 20 mA klesne napätie spomínanej batérie s vnútorným odporom 150 mΩ len o 3 mV, ale pri špičke 2 A už o 0,3 V. Čiastočne vybitá batéria má navyše nižšie napätie naprázdno aj väčší vnútorný odpor, a preto jej napätie počas špičky klesne výraznejšie (pozri obrázok 6).

Obr. 6: Pokles napätia batérie počas špičky odberu (ilustračné hodnoty)

Ak napätie klesne pod minimálne napätie mikrokontroléra, zariadenie sa reštartuje alebo sa začne správať nepredvídateľne. Typickým príznakom sú náhodné reštarty pri pripájaní do WiFi siete, keď komunikačný modul odoberá najväčší prúd (pozri špičky pri vysielaní na obrázku 2), a to často už vtedy, keď sa batéria javí ako dostatočne nabitá.

(slide) Mikrokontroléry sa pred podpätím chránia obvodom na detekciu poklesu napätia (z angl. brown-out detector), ktorý pri nízkom napätí udrží mikrokontrolér v reštarte, aby nevykonával chybné inštrukcie. Pri návrhu zariadenia je však dobré podpätiu predchádzať:

  • pridať k napájaniu komunikačného modulu kondenzátor, ktorý pokryje krátkodobé špičky odberu,
  • zvoliť batériu s nízkym vnútorným odporom,
  • merať napätie batérie a pri jeho poklese obmedziť činnosť zariadenia, napr. neodosielať údaje a nezapisovať do pamäte flash, ale upozorniť na potrebu výmeny batérie.

Priemerný odber a výdrž batérie

(slide) Ak by zariadenie odoberalo stály prúd \(I\), výdrž batérie s kapacitou \(C\) by sme vypočítali ako podiel kapacity batérie a odoberaného prúdu:

\[t = \frac{C}{I}\]

Ak by sme teda k batérii s kapacitou 1000 mAh pripojili napr. Arduino Uno, ktoré odoberá prúd približne 50 mA, vydržalo by byť napájané 20 h.

Odber nášho zariadenia sa však počas pracovného cyklu mení. Namiesto neho preto použijeme priemerný odber \(\bar{I}\), teda stály prúd, pri ktorom by zariadenie za celý pracovný cyklus odobralo rovnaký náboj ako pri skutočnom premenlivom odbere:

\[\bar{I} = \frac{Q}{T}\]

kde \(Q\) je náboj odobraný počas jedného pracovného cyklu a \(T\) je dĺžka pracovného cyklu. Výdrž batérie potom vypočítame rovnako ako pri stálom odbere:

\[t = \frac{C}{\bar{I}}\]

Vypočítajme takto výdrž senzora z obrázka 2, ktorý je napájaný batériou s kapacitou 2000 mAh. Jeho pracovný cyklus trvá 15 minút, teda 900 s. Aktívna časť cyklu trvá približne 5,5 s a zariadenie počas nej odoberie náboj približne 230 mAs. Zvyšných 894,5 s zariadenie spí s odberom 1,5 mA, a teda odoberie ďalších 1340 mAs. Priemerný odber a výdrž batérie budú:

\[\bar{I} = \frac{230\,\mathrm{mAs} + 1340\,\mathrm{mAs}}{900\,\mathrm{s}} \approx 1{,}74\,\mathrm{mA}\]

\[t = \frac{2000\,\mathrm{mAh}}{1{,}74\,\mathrm{mA}} \approx 1150\,\mathrm{h} \approx 48\text{ dní}\]

Hoci je odber počas spánku najnižší, pripadá naň až 85 % náboja odobraného počas pracovného cyklu, pretože spánok trvá takmer celý cyklus. Ak by sme odber počas spánku znížili na 10 µA, zariadenie by počas spánku odobralo len približne 9 mAs. Priemerný odber by klesol na 0,26 mA a výdrž batérie by stúpla na približne 7600 h, teda viac ako 10 mesiacov.

Pri zariadení, ktoré väčšinu času spí, teda o výdrži batérie rozhoduje najmä jeho odber počas spánku. Vypočítaná výdrž je však len teoretická, pretože skutočná kapacita batérie býva nižšia ako kapacita uvedená výrobcom (pozri podkapitolu Kapacita batérie).

Stav batérie

(slide) Vypočítaná výdrž batérie je len odhad. Skutočná kapacita batérie závisí od jej veku, od teploty aj od toho, ako z nej zariadenie odoberá prúd (pozri podkapitolu Kapacita batérie). Zariadenie sa preto nemôže spoliehať len na výpočet, ale malo by stav svojej batérie priebežne zisťovať samo.

Stav batérie potrebuje zariadenie poznať z dvoch dôvodov:

  • aby mohlo včas upozorniť, že je potrebné batériu vymeniť alebo nabiť, napr. správou pre správcu alebo upozornením na prehľadovom paneli (z angl. dashboard), ktorý zobrazuje stav všetkých zariadení,
  • aby mohlo pri nízkom stave batérie obmedziť svoju činnosť, a tak predĺžiť čas, kým bude batéria vymenená, a predísť podpätiu (pozri podkapitolu Podpätie).

Stav batérie je možné zisťovať viacerými spôsobmi. Najjednoduchší a najčastejší z nich je meranie napätia batérie.

Meranie napätia batérie

(slide) Napätie batérie s postupným vybíjaním klesá. Ak ho zariadenie odmeria, vie z neho odhadnúť, koľko náboja v batérii ešte zostáva. Na meranie napätia používa mikrokontrolér analógovo-digitálny prevodník (z angl. analog-to-digital converter, ADC). Ten však dokáže merať len napätie od 0 V po svoje referenčné napätie, ktoré je obyčajne rovnaké ako napájacie napätie mikrokontroléra (napr. 3,3 V). Napätie batérie býva vyššie, a preto sa k prevodníku pripája cez delič napätia. Ten tvoria dva rezistory, ktoré napätie batérie znížia v známom pomere, napr. na tretinu. Zariadenie potom nameranú hodnotu týmto pomerom vynásobí.

Aj delič napätia je obvod pripojený k batérii, a preto z nej odoberá prúd, a to aj vtedy, keď zariadenie spí. Rezistory deliča preto mávajú veľký odpor, obyčajne stovky kΩ, aby bol tento odber čo najmenší.

Z nameraného napätia sa stav batérie odhaduje podľa jej vybíjacej krivky, ktorá opisuje, ako sa napätie batérie mení s odobraným nábojom. Ako ukazuje obrázok 7, táto závislosť nie je lineárna a pre rôzne typy batérií vyzerá rôzne. Napätie alkalickej batérie klesá počas vybíjania postupne, takže sa z neho dá stav batérie odhadnúť pomerne dobre. Napätie lítium-iónového článku sa však počas väčšiny vybíjania mení len málo a výrazne klesne až tesne pred vybitím. Malá chyba merania napätia tak môže znamenať veľkú chybu v odhade zostávajúceho náboja.

Obr. 7: Vybíjacie krivky alkalickej batérie a lítium-iónového článku (ilustračné hodnoty)

Napätie batérie navyše závisí od aktuálneho odberu. Počas špičky klesne o úbytok napätia na vnútornom odpore batérie (pozri podkapitolu Podpätie) a stav batérie by sa javil horší, ako v skutočnosti je. Napätie batérie je preto vhodné merať vtedy, keď zariadenie odoberá malý prúd, napr. hneď po zobudení, a nikdy nie počas komunikácie cez WiFi. Napätie batérie ovplyvňuje aj teplota, pretože v chlade je nižšie.

Meranie napätia je teda len hrubým odhadom stavu batérie. Na včasné upozornenie, že sa batéria blíži k vybitiu, však obyčajne stačí.

Hlásenie stavu batérie

(slide) Odmeraný stav batérie zariadenie posiela spolu s ostatnými nameranými hodnotami, napr. ako jednu z metrík svojej telemetrie. Môže ho posielať priamo ako napätie vo voltoch alebo ako odhad zostávajúceho náboja v percentách. Systém, ktorý údaje zo zariadení spracúva, potom môže na prehľadovom paneli zobraziť, na ktorých zariadeniach treba batériu vymeniť.

Okrem samotnej hodnoty je vhodné stanoviť aj hranice, pri ktorých zariadenie zmení svoje správanie:

  • nízky stav batérie (napr. 20 %) – zariadenie upozorní, že je potrebné batériu vymeniť, a naďalej normálne pracuje,
  • kritický stav batérie (napr. 5 %) – zariadenie obmedzí svoju činnosť, aby vydržalo čo najdlhšie a aby sa vyhlo podpätiu. Môže napr. predĺžiť interval merania, prestať zapisovať do pamäte flash, kde by podpätie mohlo poškodiť uložené údaje, alebo pred vypnutím odoslať poslednú správu o tom, že sa vypína.

Keďže namerané napätie kolíše v závislosti od odberu a teploty, mohlo by zariadenie okolo hranice prechádzať z jedného stavu do druhého a späť. Preto je vhodné rozhodovať sa na základe niekoľkých po sebe idúcich meraní, prípadne pre návrat do normálneho stavu použiť vyššiu hranicu ako pre prechod do stavu nízkej batérie (tzv. hysterézia).

Postupy na znižovanie odberu

(slide) So zvyšujúcim sa množstvom prenosných zariadení vznikajú stále nové technológie na zvyšovanie kapacity batérií. Rovnako tak vznikajú aj postupy na to, ako zabezpečiť nízky odber energie. Takýchto postupov je niekoľko, ale v princípe je možné ich rozdeliť do dvoch základných skupín:

  1. postupy na znižovanie odberu pri navrhovaní softvéru, a
  2. postupy na znižovanie odberu pri navrhovaní hardvéru.

Znižovanie spotreby pri návrhu hardvéru

(slide) Martin Malý vo svojej knihe Hradla, volty, jednočipy uvádza tieto postupy na zníženie odberu elektrickej energie [10]:

  • zníženie napájacieho napätia (aspoň na úroveň 3,3 V),
  • spomalenie práce mikrokontroléra (napr. jeho uspaním alebo znížením pracovnej frekvencie),
  • použitie technológie CMOS, ktorá má v pokoji veľmi nízky odber.

(slide) Prečo pomáha nižšie napätie, vysvetľuje spotreba obvodov CMOS, ktorá je približne úmerná

\[ P \approx C \cdot U^2 \cdot f \]

kde \(C\) je kapacita prepínaných obvodov, \(U\) napájacie napätie a \(f\) pracovná frekvencia. Napätie je v druhej mocnine, preto jeho zníženie z 5 V na 3,3 V zníži túto zložku spotreby takmer na polovicu. Zo vzťahu je zrejmé aj to, prečo pomáha znížiť pracovnú frekvenciu. Nižšie napätie však zvyčajne znamená aj nižšiu maximálnu frekvenciu mikrokontroléra.

Znížiť odber je samozrejme možné aj výberom vhodných komponentov. Často môže ísť o zbytočné LED diódy, ktoré síce v porovnaní s inými zdrojmi svetla majú nízky odber, ale pri neustálom svietení dokážu spoľahlivo a rýchlo vybiť zdroj napájania.

Najväčším spotrebičom v IoT zariadení býva zvyčajne komunikačný modul. Napríklad WiFi modul odoberá pri vysielaní násobne väčší prúd ako mikrokontrolér, a to ešte predtým, ako zariadenie odošle prvý bajt: pripojenie do siete, získanie adresy a nadviazanie šifrovaného spojenia trvajú niekoľko sekúnd. Niektoré komunikačné technológie sú preto pre batériové zariadenia nevhodné, zatiaľ čo iné, ako napr. Bluetooth Low Energy alebo LoRaWAN, boli navrhnuté práve pre ne. Porovnanie komunikačných technológií z pohľadu spotreby nájdete v prednáške o komunikačných technológiách.

(slide) Pre výdrž batérie však nie je rozhodujúci samotný prúd pri vysielaní, ale energia potrebná na odoslanie jednej správy, teda prúd vynásobený časom vysielania, a to, či modul medzi správami spí. Porovnanie komunikačných technológií z tohto pohľadu sa nachádza v tabuľke 2.

Tab. 2: Energia potrebná na odoslanie správy
Technológia Prúd pri vysielaní Čas na odoslanie správy Spánok medzi správami
WiFi vysoký dlhý (pripojenie, adresa, TLS) nie, zariadenie sa musí znova pripojiť
BLE nízky veľmi krátky áno
Zigbee nízky krátky áno, len koncové zariadenia
LoRaWAN vysoký krátky, správy sú zriedkavé áno
NB-IoT / LTE-M vysoký stredný áno (režim PSM)

Preto napr. LoRaWAN s vysokým prúdom pri vysielaní vydrží na batériu roky, zatiaľ čo zariadenie s WiFi spotrebuje väčšinu energie už pri pripájaní do siete. Pri Zigbee môžu spať len koncové zariadenia, smerovače v sieti musia byť stále zapnuté, a preto bývajú napájané zo siete.

Dôležitý je aj spôsob napájania. Pri zariadeniach napájaných z elektrickej siete si môžeme dovoliť premieňať prebytočnú energiu na teplo. Ak napríklad napájame z 5 V senzor s napájacím napätím 3,3 V cez lineárny stabilizátor, rozdiel 1,7 V sa pri pretekajúcom prúde premení na teplo a z batérie by sa tak stratila zhruba tretina energie. Pri batériových IoT zariadeniach sa preto používajú spínané meniče, ktoré napätie menia s oveľa vyššou účinnosťou.

Znižovanie spotreby pomocou softvéru

(slide) IoT zariadenia často nevyžadujú pre svoju činnosť, aby boli neustále aktívne. Napríklad pri meraní teploty v miestnosti nie je potrebné, aby jej odčítanie zo senzora teploty prebehlo každú sekundu. V tomto prípade stačí dokonca niekoľkominútový interval merania. Kým tento interval neuplynie, zariadenie nerobí nič. „Nič“ však môže znamenať aj čakanie pomocou blokujúcej funkcie time.sleep() jazyka MicroPython. Môže sa síce zdať, že mikrokontrolér nič nerobí, ale zariadenie bude elektrickú energiu odoberať aj naďalej. Ak sa však na potrebný čas uvedie do režimu spánku, jeho odber elektrickej energie bude minimálny.

Motivácia

(slide) Predstavte si, že pracujete na niečom veľmi dôležitom. Ste úplne sústredení, keď sa vtom ozve váš žalúdok a hlasno vám dá najavo, že máte hlad. Neváhate, veď to nie je prvýkrát, keď ste vyhladli, zavoláte do svojej obľúbenej pizzerie, objednáte si svoju obľúbenú pizzu a obsluha vám oznámi, že vám vašu pizzu doručia až o 60 minút. Takže ešte 60 minút budete zápasiť s hladom.

Čo teraz? Do úvahy prichádza niekoľko možností:

  1. nebudem robiť ďalej, kým sa nenajem, takže nasledujúcich 60 minút strávim sledovaním hodiniek
  2. budem ďalej robiť hladný a popritom budem pravidelne sledovať hodinky, či už neuplynulo tých 60 minút
  3. nastavím si budík, aby ma po uplynutí 60 minút upozornil, a nemusím teda neustále sledovať hodinky, ale môžem sa plne sústrediť na prácu

Aj napriek tomu, že tento príklad z reálneho života vyznieva vzhľadom na uvedené možnosti pomerne komicky, môžeme isté paralely nájsť v mnohých našich, ale aj v existujúcich IoT riešeniach. Takže, čo robíme zle?

Polling

(slide) Pamätáte sa na druhú časť animáku Shrek? Shrek šiel spolu s Fionou a oslíkom na návštevu k Fioniným rodičom do kráľovstva za siedmymi horami a siedmymi dolinami. A pamätáte sa na to, čo robil celý čas oslík? Celý čas kládol rovnakú otázku: „Kedy tam už budeme?“ (pozri obrázok 8)

Obr. 8: Oslík sa neustále pýta: „Kedy tam už budeme?“ (Shrek 2, DreamWorks, 2004)

Presne rovnaký prístup často volíme pri čítaní hodnôt zo senzorov: každý prechod hlavným cyklom programu sa začne prečítaním výstupu senzora, napr. pohybového senzora PIR, a to celé sa zopakuje niekoľkokrát za sekundu. Aby sa dopytovanie nedialo príliš často, je možné medzi dvoma čítaniami chvíľu počkať, napr. 500 ms. Senzor sa tak prečíta dvakrát za sekundu.

(slide) Pri takomto prístupe sa správame presne tak ako oslík v Shrekovi – neustále sa pýtame na tú istú vec. Znova a znova. Vo svete informatiky sa tento prístup nazýva polling (z angl. poll, teda pýtať sa). Jeho princíp spočíva v neustálom dopytovaní sa externého zariadenia, či na ňom nedošlo k požadovanej udalosti, resp. k zmene stavu. Polling predstavuje synchrónnu operáciu.

Pojem polling definuje napríklad Wikipédia takto:

Polling je aktívne zisťovanie stavu externého zariadenia klientskym programom, ktoré prebieha ako synchrónna činnosť.

(slide) Polling je veľmi jednoduchý a často postačuje na riešenie väčšiny problémov. Má však aj niektoré nevýhody. Jednou z nich je vysoká pravdepodobnosť straty údajov. K tomu môže dôjsť napr. vtedy, ak externé zariadenie pošle údaje mikrokontroléru tesne potom, ako sa ich ten pokúsil prečítať. Alebo aj vtedy, ak dôjde k pohybu uprostred 500 ms prestávky a počas tých istých 500 ms sa pohyb aj skončí (pozri obrázok 9).

Obr. 9: Polling: mikrokontrolér kontroluje stav senzora v pravidelných intervaloch, takže udalosť zachytí s oneskorením alebo ju úplne prehliadne

V príklade s doručením pizze zo začiatku kapitoly môže dôjsť k problému napr. vtedy, ak bude pizza doručená pred uplynutím 60 min intervalu. Vo všeobecnosti takýto prístup nepredstavuje veľmi dobrý dizajn, ak je potrebné zákazníkovi povedať, že pizza dorazí presne po 60 minútach a ak vtedy neotvorí, svoj tovar nedostane (aj napriek tomu, že zaň zaplatil).

Samozrejme existujú požiadavky, pri ktorých je takéto správanie postačujúce. Napr. merať vonkajšiu teplotu stačí v niekoľkominútových pravidelných intervaloch a prípadný výkyv teplôt medzi dvoma Zzazvoní alebo zaklope na dvere. Prípadne zákazníka pred príchodom upozorní telefonátom. Zákazník sa tak nemusí starať o to, či už uplynul čas doručenia, alebo či doručovateľ neprišiel skôr. Môže sa venovať svojej práci a o doručení bude upozornený automaticky a hlavne včas.

(slide) Tento mechanizmus sa vo svete informačných technológií nazýva prerušenie (z angl. interrupt). Koncept prerušení je vo svete mikrokontrolérov veľmi dôležitý.

Pojem prerušenie definuje napríklad Wikipédia takto:

Prerušenie je signál pre procesor, ktorý vyšle hardvér alebo softvér a ktorý oznamuje udalosť vyžadujúcu okamžitú pozornosť.

(slide) Hlavný rozdiel medzi pollingom a prerušením je v tom, kto dá o udalosti vedieť. Pri pollingu sa softvér sám opakovane pýta, či udalosť nastala. Pri prerušení naopak zariadenie samo oznámi mikrokontroléru, že udalosť nastala, podobne ako doručovateľ, ktorý zazvoní pri dverách. Požiadavka na prerušenie preto môže prísť kedykoľvek a prerušenie predstavuje asynchrónny spôsob komunikácie.

Prečo používať prerušenia

(slide) Prerušenia majú oproti pollingu niekoľko výhod:

  • Mikrokontrolér na udalosť reaguje okamžite, pretože sa o nej dozvie hneď, ako nastane. Nestratí tak ani krátku udalosť, ktorú by polling medzi dvoma čítaniami prehliadol.
  • Procesor nie je zbytočne zaťažený, pretože sa nemusí neustále dopytovať na stav zariadenia a môže sa venovať inej práci.
  • Zariadenie šetrí energiu, pretože mikrokontrolér môže byť v režime spánku a prerušenie ho zobudí až vtedy, keď je potrebné niečo urobiť. Zobudiť ho môže napr. alarm hodinového modulu DS3231 alebo stlačenie servisného tlačidla.

Obsluha prerušenia (ISR)

(slide) Inštrukcie programu, ktorý beží v mikrokontroléri, sa vykonávajú sekvenčne. To znamená, že po vykonaní jednej inštrukcie sa vykoná ďalšia inštrukcia v poradí. Keď však mikrokontrolér dostane požiadavku na prerušenie, pozastaví vykonávanie programu a spustí špeciálnu funkciu na obsluhu prerušenia, ktorá sa označuje ISR (z angl. Interrupt Service Routine). Po skončení tejto funkcie program pokračuje na mieste prerušenia ďalšou inštrukciou v poradí.

Pojem ISR definuje napríklad Wikipédia takto:

Obsluha prerušenia (ISR) je špeciálny blok kódu, ktorý sa spustí pri vzniku konkrétneho prerušenia.

(slide) Celý mechanizmus zobrazuje obrázok 10. Požiadavka na prerušenie prišla počas vykonávania inštrukcie 3. Obsluha prerušenia sa preto vykoná až po dokončení tejto inštrukcie a program potom pokračuje inštrukciou 4.

Obr. 10: Volanie obsluhy prerušenia (ISR) zjednodušene

(slide) Pozrime sa však na to, ako celý tento mechanizmus funguje pod kapotou. Riadi ho procesor mikrokontroléra v týchto krokoch (pozri obrázok 11):

  1. Keď vznikne požiadavka na prerušenie, procesor najprv dokončí práve vykonávanú inštrukciu a uloží si kontext, teda stav prerušeného programu (napr. obsah registrov a adresu nasledujúcej inštrukcie).
  2. V tabuľke vektorov prerušení nájde adresu ISR. V tejto tabuľke má každý zdroj prerušenia, napr. pin alebo časovač, priradenú svoju obsluhu.
  3. Po skončení ISR procesor obnoví uložený kontext a pokračuje vo vykonávaní programu ďalšou inštrukciou, akoby sa nič nestalo.
Obr. 11: Volanie obsluhy prerušenia (ISR) procesorom mikrokontroléra

Pravidlá pre písanie ISR

Hlavný program o prerušení nevie a nemôže ho ani predvídať, pretože prerušenie môže nastať medzi ľubovoľnými dvoma inštrukciami. Preto pre ISR platia prísnejšie pravidlá ako pre bežné funkcie.

(slide) ISR nevracajú žiadnu hodnotu, pretože ich nevolá program, ale procesor. Ak je potrebné v ISR zmeniť stav aplikácie, používajú sa na to globálne premenné. Je to jediný spôsob, ako si môžu ISR a hlavný program vymieňať údaje.

(slide) Pri tvorbe ISR je dobré dodržiavať niekoľko odporúčaní [7], [1]:

  • Písať ISR čo najkratšie a čo najrýchlejšie, aby zbytočne nebrzdili hlavný program alebo prípadne ďalšie prerušenia, ktoré môžu nastať.
  • V ISR iba zaznamenať udalosť, napr. nastaviť príznak, a jej spracovanie nechať na hlavný program, pretože ten nemá obmedzenia, ktoré platia pre ISR.
  • V ISR nečakať, pretože počas čakania procesor nevykonáva hlavný program ani neobslúži ďalšie prerušenia. Na niektorých platformách, napr. Arduino Uno, navyše čas počas ISR stojí, pretože ho počíta obsluha iného prerušenia, a čakanie by tak nikdy neskončilo.
  • V ISR nepoužívať dlhotrvajúce operácie, akou je napr. komunikácia cez sériovú linku, pretože často samy potrebujú prerušenia, a preto v ISR nemusia fungovať správne.
  • V ISR nealokovať pamäť, pretože prerušenie mohlo nastať práve počas jej správy a správca pamäte by sa tak dostal do nekonzistentného stavu.
  • V ISR nevypínať ani nezapínať podporu prerušení, pretože o ich povolenie počas obsluhy a po nej sa stará procesor sám. Ich zapnutím v ISR by mohlo dôjsť k vnoreniu prerušení, prípadne aj k opätovnému spusteniu tej istej ISR skôr, ako skončí.
  • V hlavnom programe chrániť prístup k údajom zdieľaným s ISR, pretože prerušenie môže nastať aj uprostred ich čítania alebo zápisu (napr. pri viacbajtovom čísle, ktoré 8-bitový procesor číta po bajtoch). Na krátky čas sa preto zakážu prerušenia a vytvorí sa tzv. kritická sekcia (z angl. critical section).
  • V jazyku C označiť globálne premenné, ktoré sa používajú na zdieľanie údajov medzi ISR a programom, kvalifikátorom volatile, aby prekladač pri každom použití načítal ich aktuálnu hodnotu z pamäte.

Typy prerušení

(slide) Podľa toho, kto prerušenie vyvolá, rozlišujeme hardvérové a softvérové prerušenia. Hardvérové prerušenia vyvoláva hardvér a pri mikrokontroléroch sa delia na dve skupiny:

  1. externé prerušenia, ktoré vyvolá zmena signálu na pine mikrokontroléra, a
  2. interné prerušenia, ktoré vyvolávajú periférie vo vnútri mikrokontroléra, ako napr. časovače.

Softvérové prerušenie vyvolá program pomocou špeciálnej inštrukcie procesora (napr. SVC na procesoroch ARM). Využívajú ho najmä operačné systémy na volanie svojich služieb. V bežnom programe pre IoT zariadenie sa s ním priamo nestretneme.

Externé prerušenia

Signál externého prerušenia prichádza z externého zariadenia, ktoré je pripojené k pinu mikrokontroléra. Môže ísť napr. o tlačidlo, rotačný enkodér, senzor pohybu alebo alarm hodinového modulu.

Pri externom prerušení je potrebné určiť, čo na pine prerušenie vyvolá. Podľa toho rozlišujeme prerušenia vyvolané hranou signálu (z angl. edge-triggered) a prerušenia vyvolané úrovňou signálu (z angl. level-triggered).

Prerušenie vyvolané hranou nastane pri zmene úrovne signálu na pine. Zvyčajne sú k dispozícii tieto možnosti (pozri obrázok 12):

  • nábežná hrana (z angl. rising edge) – prerušenie sa vyvolá pri zmene úrovne z LOW na HIGH,
  • dobežná hrana (z angl. falling edge) – prerušenie sa vyvolá pri zmene úrovne z HIGH na LOW,
  • zmena (z angl. change) – prerušenie sa vyvolá pri oboch zmenách.
Obr. 12: Spustenie prerušenia na nábežnej, dobežnej alebo oboch hranách signálu na pine mikrokontroléra s napájaním 3,3 V

Prerušenie vyvolané úrovňou nastáva, kým je na pine úroveň LOW alebo HIGH. Pri tomto type prerušenia treba dať pozor na to, že kým sa úroveň signálu nezmení, prerušenie sa vyvolá znova hneď po skončení obsluhy predchádzajúceho prerušenia.

Nie každý mikrokontrolér podporuje každý typ externého prerušenia. To, ktoré možnosti a ktoré piny mikrokontrolér podporuje, je potrebné vždy overiť v jeho dokumentácii. Napríklad mikrokontroléry ESP32 a RP2350 dokážu zachytiť prerušenie na každom GPIO pine, kým mikrokontrolér ATmega328P na doskách Arduino má plnohodnotné externé prerušenia len na 2 pinoch.

Či stlačenie tlačidla vyvolá nábežnú alebo dobežnú hranu, závisí od jeho zapojenia. Ak je tlačidlo pripojené k zemi a pin používa pull-up rezistor, je na pine v kľude úroveň HIGH. Stlačenie tlačidla potom vyvolá dobežnú hranu a jeho uvoľnenie nábežnú hranu. Pri zapojení s pull-down rezistorom je to naopak.

Ako sa externé prerušenie nastavuje v jazyku MicroPython, ukazuje kapitola Prerušenia.

Interné prerušenia

Signál interného prerušenia prichádza z periférie, ktorá je súčasťou mikrokontroléra. Najčastejšie ide o časovač, ale prerušenie môžu vyvolať napr. aj:

  • watchdog, ak mu program v stanovenom čase nedá znamenie, že stále správne beží (na mnohých mikrokontroléroch však watchdog prerušenie nevyvolá, ale zariadenie rovno reštartuje),
  • komunikačné rozhrania UART, SPI alebo I²C po prijatí údajov alebo po dokončení prenosu,
  • A/D prevodník po dokončení prevodu analógovej hodnoty na digitálnu.

Časovače

(slide) Časovač (z angl. timer) je periféria mikrokontroléra, ktorá po uplynutí nastaveného času vyvolá interné prerušenie. Časovač môže prerušenie vyvolať jednorazovo alebo opakovane s danou periódou, resp. frekvenciou, napr. každú 1 sekundu. Program tak nemusí sám sledovať čas a medzi prerušeniami sa môže venovať inej činnosti.

Pojem časovač definuje napríklad Wikipédia takto:

V informatike a vo vstavaných systémoch je programovateľný časovač počítadlo, ktoré vygeneruje výstupný signál, keď dosiahne naprogramovanú hodnotu. Tento výstupný signál môže vyvolať prerušenie.

(slide) Časovač dokáže mikrokontrolér po uplynutí nastaveného času aj zobudiť zo spánku. Zvyčajne na to slúži špeciálny časovač, ktorý beží aj počas spánku, keď sú ostatné periférie vypnuté. Na tom je postavené periodické meranie s nízkou spotrebou: zariadenie väčšinu času spí a časovač ho zobudí len na krátky čas, keď je potrebné vykonať meranie (pozri obrázok 13).

Obr. 13: Časovač s periodickým prerušením, ktoré prebúdza mikrokontrolér zo spánku na meranie

Zaujímať by nás mohlo, akú najdlhšiu periódu vieme na danom mikrokontroléri dosiahnuť. Tá závisí od dvoch vecí:

  1. od šírky počítadla v bitoch a
  2. od frekvencie, s akou počítadlo počíta.

Počítadlo so šírkou \(n\) bitov dokáže napočítať do hodnoty \(2^n\). Najdlhšiu periódu je potom možné vyjadriť vzťahom

\[ T_{max} = \frac{2^n}{f} \]

kde \(n\) je šírka počítadla v bitoch a \(f\) je frekvencia počítadla v hertzoch (Hz). Najdlhšia perióda \(T_{max}\) je potom v sekundách.

Napríklad 16-bitový časovač mikrokontroléra ATmega328P, ktorého počítadlo počíta s frekvenciou hodín 16 MHz, dosiahne najdlhšiu periódu

\[ T_{max} = \frac{2^{16}}{16\,000\,000} \approx 0{,}0041\ s = 4{,}1\ ms \]

Frekvenciu počítadla je možné znížiť tzv. preddeličkou (z angl. prescaler), ktorá vydelí frekvenciu hodín mikrokontroléra, napr. číslom 1024. Tým sa najdlhšia perióda úmerne predĺži. Ak napríklad pri spomínanom časovači mikrokontroléra ATmega328P s frekvenciou 16 MHz použijeme preddeličku 1024, najdlhšia perióda sa predĺži na približne 4,2 s. Naproti tomu mikrokontrolér RP2350 má 64-bitové počítadlo s frekvenciou 1 MHz, ktorého alarmy porovnávajú 32 bitov, takže dosiahnu približne 71 minút.

Čo však v prípade, ak potrebujeme dlhšiu periódu, ako nám dovoľuje mikrokontrolér? Do úvahy prichádza niekoľko možností:

  • Počítať prerušenia v programe. Časovač vyvolá prerušenie napr. každú sekundu a program vykoná meranie až po zodpovedajúcom počte prerušení. Nevýhodou je, že sa mikrokontrolér zobúdza zbytočne často, čo zvyšuje spotrebu.
  • Použiť časovač, ktorý beží aj počas spánku, napr. pri prechode do hlbokého spánku na nastavený čas. Mikrokontrolér sa tak zobudí až po uplynutí celej periódy. Aj tento časovač má však obmedzený rozsah [12].
  • Použiť alarm externého hodinového modulu, napr. DS3231. Modul v nastavenom čase zmení úroveň na svojom výstupe a vyvolá tak externé prerušenie, ktoré mikrokontrolér zobudí. Alarm sa však spustí pri zhode s konkrétnym časom, nie po uplynutí intervalu, preto ho treba po každom zobudení nastaviť na ďalší čas [2].

Ako sa časovače používajú v jazyku MicroPython, ukazuje kapitola Časovače.

Nevýhody použitia prerušení

Prerušenia majú okrem svojich výhod aj nevýhody:

  • Ťažšie ladenie. Prerušenie môže nastať kedykoľvek, aj počas krokovania programu. Pri krokovaní tak nie je zrejmé, koľko prerušení medzitým nastalo. Chyby, ktoré závisia od presného okamihu prerušenia, sa navyše často nedajú spoľahlivo zopakovať.
  • Zložitejší program. Program sa už nevykonáva len sekvenčne, pretože okamih spustenia ISR určujú udalosti. Je preto potrebné dodržiavať pravidlá pre písanie ISR a starostlivo navrhnúť, ako si ISR a hlavný program vymieňajú údaje.
  • Súbeh (z angl. race condition). Ak ISR a hlavný program pracujú s rovnakými údajmi bez ochrany pomocou kritickej sekcie, výsledok závisí od toho, v ktorom okamihu prerušenie nastalo. Takéto chyby sa prejavujú len občas, a preto sa ťažko hľadajú [1].
  • Nežiaduce prerušenia. Mechanické tlačidlo pri stlačení zakmitá, takže jedno stlačenie môže vyvolať viacero prerušení. Podobne môže prerušenie vyvolať aj rušenie na pine, ku ktorému nie je nič pripojené. Takéto prerušenia je potrebné odfiltrovať (z angl. debouncing) alebo im zabrániť správnym zapojením, napr. pomocou pull-up alebo pull-down rezistora.
  • Príliš časté prerušenia. Ak prerušenia prichádzajú rýchlejšie, ako ich mikrokontrolér stihne obslúžiť, hlavný program sa nedostane k slovu a niektoré prerušenia sa môžu stratiť. Táto situácia sa nazýva zahltenie prerušeniami (z angl. interrupt storm). Pri veľmi rýchlych signáloch je preto vhodnejšie použiť špecializovanú perifériu mikrokontroléra, napr. počítadlo impulzov.

Režimy spánku

Doteraz sme niekoľkokrát spomenuli, že prerušenie alebo časovač dokáže mikrokontrolér zobudiť zo spánku. Čo však znamená, že mikrokontrolér spí?

(slide) Pomôcť si môžeme porovnaním s ľudským spánkom. Keď človek zaspí, jeho telo prejde do úsporného režimu: spomalí sa mu srdcový tep aj dýchanie a mierne mu klesne telesná teplota. Najdôležitejšie orgány však pracujú ďalej, a preto sa človek dokáže zobudiť, keď zazvoní budík alebo keď ho niekto zatrasie. Podobne sa správa aj mikrokontrolér: počas spánku vypne časti, ktoré práve nepotrebuje, a nechá bežať len tie, ktoré ho dokážu zobudiť (pozri obrázok 14).

Obr. 14: Porovnanie spánku človeka a mikrokontroléra

(slide) Stav, do ktorého takto prejde telo človeka aj mikrokontrolér, sa v prípade mikrokontrolérov nazýva režim spánku (z angl. sleep mode). Patrí medzi tzv. úsporné režimy (z angl. low-power modes), ktoré podľa stránky Last Minute Engineers opisujeme takto [8]:

Úsporné režimy slúžia na zníženie spotreby, keď mikrokontrolér nemusí pracovať naplno. Dosahujú to tak, že niektoré časti mikrokontroléra vypnú a iné nechajú bežať.

Čo sa deje počas spánku

(slide) Pri návrhu hardvéru sme videli, že spotreba mikrokontroléra závisí aj od frekvencie, s akou pracujú jeho hodiny (pozri vzťah \(P \approx C \cdot U^2 \cdot f\)). Pri čakaní pomocou blokujúcej funkcie time.sleep() zostáva mikrokontrolér so všetkými svojimi perifériami zapnutý a jeho hodiny bežia ďalej. V režime spánku sa naopak hodiny procesora zastavia a vypnú sa aj tie časti mikrokontroléra (pozri obrázok 15 a prednášku O veciach), ktoré práve nie sú potrebné. Kým mikrokontrolér spí, nevykonáva žiadne inštrukcie a jeho odber môže klesnúť aj o niekoľko rádov. Zobudí ho až prerušenie, ktoré sme vopred nastavili, napr. od časovača alebo z pinu.

Obr. 15: Všeobecný blokový diagram mikrokontroléra

Ľahký a hlboký spánok v jazyku MicroPython

Rovnako ako sa mikrokontroléry líšia typom a počtom svojich častí, líšia sa aj počtom režimov spánku. Jednotlivé režimy sa od seba líšia tým, ktoré časti mikrokontroléra vypnú, a teda aj tým, koľko energie ušetria. Prehľad režimov vybraných mikrokontrolérov uvádza tabuľka 3.

Tab. 3: Úsporné režimy vybraných mikrokontrolérov
Mikrokontrolér Úsporné režimy
ESP32 Modem Sleep, Light Sleep, Deep Sleep, Hibernation [8]
RP2350 SLEEP, DORMANT a stavy s vypnutým napájaním jadra P1.0 až P1.7 [12]
ATmega328P Idle, ADC Noise Reduction, Power-down, Power-save, Standby, Extended Standby [3]

Podstata je však vo všetkých režimoch rovnaká: mikrokontrolér vypne niektoré svoje časti, aby znížil spotrebu. Čím viac častí vypne, tým menej energie spotrebuje. Tým dlhšie mu však trvá, kým sa zobudí, a tým menej si z predchádzajúceho stavu (napr. obsah pamäte RAM alebo nastavenie periférií) pamätá. Programátor si preto vyberá režim, ktorý najlepšie zodpovedá potrebám jeho aplikácie [3].

Jazyk MicroPython bez ohľadu na použitý mikrokontrolér a počet jeho režimov spánku rozlišuje len dva: ľahký spánok (z angl. light sleep) a hlboký spánok (z angl. deep sleep) [1]. Sú zastúpené volaním dvoch zodpovedajúcich funkcií, a to machine.lightsleep() a machine.deepsleep().

Každý z týchto dvoch režimov však MicroPython na konkrétnom mikrokontroléri implementuje pomocou niektorého z jeho vlastných režimov spánku. Príklad mapovania ľahkého a hlbokého spánku v jazyku MicroPython na mikrokontroléroch ESP32 a RP2350 (doska Raspberry Pi Pico 2 W) ukazuje tabuľka 4.

Tab. 4: Mapovanie ľahkého a hlbokého spánku v jazyku MicroPython na režimy spánku mikrokontrolérov (ESP32, RP2350)
Režim v jazyku MicroPython ESP32 RP2350
ľahký spánok (lightsleep()) Light Sleep SLEEP, ak je zadaný čas zobudenia, inak DORMANT
hlboký spánok (deepsleep()) Deep Sleep rovnaký ako ľahký spánok, po zobudení však nasleduje reštart

Ktoré časti mikrokontroléra zostanú v jednotlivých režimoch zapnuté, ukazuje na príklade mikrokontroléra ESP32 obrázok 16, [6], [5].

Obr. 16: Zapnuté, pozastavené a vypnuté časti mikrokontroléra ESP32 v aktívnom režime, v ľahkom a v hlbokom spánku

Na mikrokontroléri RP2350 (doska Raspberry Pi Pico 2 W) je však situácia iná. Hlboký spánok je v jazyku MicroPython implementovaný ako ľahký spánok s tým rozdielom, že sa mikrokontrolér po zobudení reštartuje (pozri tabuľku 4). Hlboký spánok teda neušetrí viac energie, mikrokontrolér len príde o stav programu.

Zaspanie a zobudenie

Mikrokontrolér prejde do režimu spánku volaním príslušnej funkcie v programe. Predtým však musí program nastaviť aspoň jeden zdroj zobudenia (z angl. wake-up source), teda prerušenie, ktoré mikrokontrolér zo spánku zobudí. Ak by žiadny nenastavil, mikrokontrolér by spal, kým by ho niekto nereštartoval alebo neodpojil od napájania.

Najčastejšími zdrojmi zobudenia sú časovače (pozri podkapitolu Časovače) a zmena úrovne na pine (pozri podkapitolu Externé prerušenia). Niektoré mikrokontroléry však ponúkajú aj ďalšie zdroje zobudenia, ako napríklad:

  • príchod správy na sériovej linke (UART) [6],
  • dotyk na dotykový senzor [6],
  • prekročenie nastavenej úrovne napätia na analógovom vstupe [3] alebo
  • prijatie vlastnej adresy na zbernici I²C [3].

Ktoré z nich je možné použiť, však závisí nielen od mikrokontroléra, ale aj od režimu spánku. Čím hlbší je spánok, tým menej zdrojov zobudenia je k dispozícii, pretože periférie, ktoré by prerušenie vyvolali, sú vypnuté [6], [3].

To, čo sa stane po zobudení, závisí od režimu spánku. Pri ľahkom spánku sa vykonávanie programu len pozastaví. Po zobudení program pokračuje ďalším príkazom a všetky premenné aj nastavenia periférií zostanú zachované (pozri obrázok 17). Treba však dať pozor hlavne na bezdrôtové komunikačné moduly (napr. WiFi), ktoré sa počas spánku vypnú, a po zobudení preto nebudú pripojené k sieti [6].

---
# spolocna konfiguracia stavovych diagramov THSensor; vklada sa ako prvy
# riadok bloku ```mermaid, za nim nasleduje "flowchart LR" a samotny diagram
config:
  flowchart:
    curve: basis
    nodeSpacing: 40
    rankSpacing: 60
  themeVariables:
    fontSize: 20px
  themeCSS: ".edgeLabel, .edgeLabel p, .labelBkg { background-color: var(--bs-body-bg) !important; }"
---

flowchart LR
    start@{ shape: f-circ } --> setup("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Nastavenie<br>zariadenia</div>")
    setup --> measurement("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Meranie</div>")
    measurement --> sleep("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Ľahký<br>spánok</div>")
    sleep -- "zobudenie" --> measurement

    %% spolocne styly stavovych diagramov THSensor (farby podla
    %% images/thsensor-state.diagram.complete.png); vklada sa na koniec diagramu
    %% a stavy sa k nim priradia cez "class <stavy> <styl>"
    classDef state fill:#cfe2ff,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef service fill:#cbc3a3,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef reset fill:#ffd6f5,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef config fill:#fddba7,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef error fill:#ffd7d9,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef ota fill:#c3f5c8,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef initial fill:#000,stroke:#fff,stroke-width:2px
    classDef final fill:#fff,stroke:#000,stroke-width:2px

    class setup,measurement state
    class sleep config
    class start initial

Obr. 17: Stavový diagram programu s ľahkým spánkom

Pri hlbokom spánku však môže byť situácia iná. Niektoré mikrokontroléry pri ňom vypnú aj procesor a pamäť RAM, a preto sa po zobudení reštartujú. Prerušenie, ktoré mikrokontrolér zobudilo, teda nespustí žiadnu obsluhu prerušenia. Program by preto mal hneď na začiatku zistiť, prečo bol spustený (pozri obrázok 18). Mikrokontrolér si príčinu svojho spustenia uchováva v špeciálnom registri a programovacie jazyky ju sprístupňujú pomocou svojho API.

---
# spolocna konfiguracia stavovych diagramov THSensor; vklada sa ako prvy
# riadok bloku ```mermaid, za nim nasleduje "flowchart LR" a samotny diagram
config:
  flowchart:
    curve: basis
    nodeSpacing: 40
    rankSpacing: 60
  themeVariables:
    fontSize: 20px
  themeCSS: ".edgeLabel, .edgeLabel p, .labelBkg { background-color: var(--bs-body-bg) !important; }"
---

flowchart LR
    start@{ shape: f-circ } --> init("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Init</div>")
    init -- "zapnutie<br>napájania" --> setup("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Nastavenie<br>zariadenia</div>")
    init -- "zobudenie" --> measurement("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Meranie</div>")
    setup --> measurement
    measurement --> sleep("<div style='width:164px;height:48px;display:flex;align-items:center;justify-content:center;line-height:1.2'>Hlboký<br>spánok</div>")
    sleep --> sleepEnd@{ shape: fr-circ }

    %% spolocne styly stavovych diagramov THSensor (farby podla
    %% images/thsensor-state.diagram.complete.png); vklada sa na koniec diagramu
    %% a stavy sa k nim priradia cez "class <stavy> <styl>"
    classDef state fill:#cfe2ff,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef service fill:#cbc3a3,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef reset fill:#ffd6f5,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef config fill:#fddba7,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef error fill:#ffd7d9,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef ota fill:#c3f5c8,stroke:#9aa3ad,stroke-width:3px,color:#343a40,font-weight:bold
    classDef initial fill:#000,stroke:#fff,stroke-width:2px
    classDef final fill:#fff,stroke:#000,stroke-width:2px

    class init,setup,measurement state
    class sleep config
    class start initial
    class sleepEnd final

Obr. 18: Stavový diagram programu s hlbokým spánkom

Znížiť frekvenciu, alebo rýchlo zaspať?

V časti o návrhu hardvéru sme videli, že spotreba mikrokontroléra závisí od jeho pracovnej frekvencie. Mohlo by sa preto zdať, že stačí frekvenciu znížiť a zariadenie ušetrí energiu vždy. Pri zariadeniach, ktoré väčšinu času spia, to však neplatí.

Batériu totiž nevybíja výkon, ale energia, teda výkon za určitý čas:

\[ E = P \cdot t \]

Nižšia frekvencia síce zníži výkon mikrokontroléra, ale ak procesor počíta, potrebuje na rovnakú prácu viac času.

Spotreba mikrokontroléra má navyše dve zložky. Dynamická zložka vzniká pri každom prepnutí obvodov a rastie s frekvenciou. Statická zložka od frekvencie nezávisí a mikrokontrolér ju odoberá po celý čas, kým je zapnutý [4]. Ak frekvenciu znížime, dynamická zložka klesne, ale statickú zložku bude mikrokontrolér odoberať dlhšie. Pri výpočtoch je preto výhodnejšie pracovať čo najrýchlejšie a hneď potom zaspať. Tento prístup sa nazýva „rýchlo urob prácu a čo najskôr zaspi“ (z angl. race to sleep alebo race to idle) [4].

Nižšia frekvencia sa naopak oplatí vtedy, keď procesor väčšinu času len čaká, napr. na odpoveď senzora alebo na prenos údajov cez zbernicu. Takáto práca trvá pri akejkoľvek frekvencii rovnako dlho, takže nižšia frekvencia ušetrí energiu [4]. Oplatí sa aj vtedy, keď zariadenie nemôže spať, alebo keď mikrokontrolér dokáže pri nižšej frekvencii znížiť aj napájacie napätie, ktoré je vo vzťahu pre výkon v druhej mocnine [4].

V odporúčaniach sa preto môžeme stretnúť s oboma prístupmi. Napríklad Steve Leibson odporúča prevádzkovať mikrokontrolér pri najnižšej možnej frekvencii a pri najnižšom možnom napätí jadra [9]. Ktorý z prístupov je pre konkrétne zariadenie výhodnejší, závisí od toho, čo zariadenie počas svojej aktívnej časti robí. Spoľahlivo to zistíme len meraním.

Literatúra

[1] MicroPython. In [online]. Dostupné na internete: <http://micropython.org>.
[2] ANALOG DEVICES DS3231: Extremely Accurate I²C-Integrated RTC/TCXO/Crystal. In [online]. Dostupné na internete: <https://www.analog.com/media/en/technical-documentation/data-sheets/DS3231.pdf>.
[3] ATMEL ATmega328P Automotive Microcontrollers Datasheet. In [online]. [cit. 2026-11-03]. Dostupné na internete: <https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf>.
[4] CHIANG, H. et al. Power Clocks: Dynamic Multi-Clock Management for Embedded Systems. In Proceedings of the International Conference on Embedded Wireless Systems and Networks (EWSN) [online]. 2021. Dostupné na internete: <https://par.nsf.gov/servlets/purl/10292320>.
[5] ESPRESSIF SYSTEMS ESP32 Technical Reference Manual. In [online]. [cit. 2026-11-03]. Dostupné na internete: <https://documentation.espressif.com/esp32_technical_reference_manual_en.pdf>.
[6] ESPRESSIF SYSTEMS ESP-IDF Programming Guide: Sleep Modes (ESP32). In [online]. [cit. 2026-11-03]. Dostupné na internete: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/sleep_modes.html>.
[7] GAMMON, N. Interrupts. In [online]. 2012. Dostupné na internete: <http://www.gammon.com.au/interrupts>.
[8] LAST MINUTE ENGINEERS Insight Into ESP32 Sleep Modes & Their Power Consumption. In [online]. [cit. 2026-11-03]. Dostupné na internete: <https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/>.
[9] LEIBSON, S. What is a Low-Power Microcontroller? In [online]. 2010. [cit. 2026-11-03]. Dostupné na internete: <https://www.digikey.com/en/articles/what-is-a-low-power-microcontroller>.
[10] MALÝ, M. Hradla, volty, jednočipy [online]. [s.l.]: CZ.NIC, z. s. p. o., 2017. ISBN 9788088168249.
[11] RASPBERRY PI LTD. Raspberry Pi Pico 2 W Datasheet: An RP2350-based microcontroller board with wireless. In [online]. 2024. [cit. 2026-11-06]. Dostupné na internete: <https://pip-assets.raspberrypi.com/categories/1088-raspberry-pi-pico-2-w/documents/RP-008304-DS-1-pico-2-w-datasheet.pdf>.
[12] RASPBERRY PI LTD. RP2350 Datasheet: A microcontroller by Raspberry Pi. In [online]. 2024. [cit. 2026-09-01]. Dostupné na internete: <https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf>.