IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

2. diel - Prerušenie a časovač na module ESP-32

V predchádzajúcej lekcii, Zoznámenie s ESP-32 , sme sa zoznámili s čipom ESP-32 a vývojovou doskou ESP-32 DEVKIT DOIT.

V tomto tutoriále Internetu vecí s ESP32 sa zameriame na možnosti využitia prerušenia a časovania, ktoré nám modul ESP-32 ponúka. Vysvetlíme si princíp prerušenia a jeho dva typy.

Prerušenie

Prerušenia sú kľúčovým konceptom v oblasti mikrokontrolérov a systémov vstavaných zariadení, ako je ESP32. Ako prerušenie označujeme signály generované buď externými alebo internými udalosťami. Tieto signály dočasne prerušia bežiaci program a spustia špecifickú obslužnú rutinu. Uveďme si príklad s jednoduchou LED diódou. Povedzme, že máme program, ktorý rozbliká LED. Mikrokontrolér vykonáva všetky príkazy v programe tak, ako idú za sebou. Ak však chceme monitorovať stav diódy v reálnom čase, narážame na oneskorenie, ktoré je dané dĺžkou bežiaceho programu – pokiaľ neskončí, nemáme možnosť do neho vstúpiť. A keď program beží v slučke loop(), sme od neho oddelení úplne. Tu do hry prichádza prerušenie.

Pri prerušení mikrokontrolér zastaví beh programu a zavolá funkciu typu ISR (Interrupt Service Routine). Následne sa vykonajú všetky príkazy v tele funkcie a potom sa mikrokontrolér opäť vráti do hlavného programu. Tento mechanizmus umožňuje mikrokontroléru rýchlo reagovať na dôležité udalosti (ako je zmena stavu LED diódy) bez toho, aby bol nutný priebežný prieskum (polling) stavu diódy. To zefektívňuje použitie procesorového času a umožňuje mikrokontroléru zvládať viac úloh súbežne.

ESP-32 má celkom 32 prerušení na každé jadro a každé z nich má určitú prioritu.

Typy prerušenia

Základné rozdelenie je odvodené od zdroja prerušenia, delí sa preto na externé/hardvérové a softvérové .

Externé/hardvérové prerušenie

Toto prerušenie je vyvolané udalosťou na externú perifériu. Ako príklad si uveďme senzor dotyku. Pokiaľ senzor zaregistruje dotyk, zmení sa aj stav na GPIO a vyvolá sa prerušenie. Následne sa vykonajú príkazy v tele ISR funkcie a potom sa riadenie vráti do hlavného programu. Najväčšou výhodou prerušenia je, že nemusíme neustále monitorovať stav periférie. Periféria si naopak sama povie, že u nej nastala zmena, pre ktorú máme pripravenú obslužnú rutinu.

Softvérové prerušenie

Tento typ prerušenia nastane vo chvíli, keď program sám explicitne vyvolá prerušenie a určí rutinu, ktorá sa vykoná. Softvérové prerušenie sa často používa na manipuláciu s hardvérovými zariadeniami, signalizáciu chýb alebo na realizáciu komplexných funkcií v rámci operačného systému. Je možné ním tiež emulovať hardvérové udalosti pre testovanie alebo ladenie kódu, alebo vynútiť kontrolu niektorých funkcií.

Pri softvérových prerušeniach je dôležité zaistiť správnu synchronizáciu a riadenie prerušenia, aby nedochádzalo k nekonzistencii dát alebo iným problémom.

GPIO prerušenie

Výhodou modulu ESP-32 je, že všetky jeho GPIO piny je možné nakonfigurovať ako zdroje hardvérového prerušenia. Docielime to veľmi jednoducho, stačí iba príslušný pin pripojiť k zodpovedajúcej ISR. Toto nám umožní nasledujúce makro:

Makro obsahuje tri argumenty:

  • GPIOpin: číslo pinu, ku ktorému má byť priradené prerušenie,
  • ISR: názov funkcie, ktorá má byť pri prerušení zavolaná,
  • Event: tretí argument určí, pri akej udalosti má byť prerušenie vyvolané. Možné hodnoty sú nasledovné:
    • LOW - prerušenie sa spustí, ak je na pine hodnota LOW (0),
    • HIGH - prerušenie sa spustí, ak je na pine hodnota HIGH (1),
    • CHANGE - prerušenie sa spustí vždy, keď sa na pine zmení hodnota (LOW na HIGH alebo HIGH na LOW),
    • FALLING - prerušenie sa spustí, ak sa hodnota na pine zmení z HIGH na LOW (dobežná hrana),
    • RISING - prerušenie sa spustí, ak sa hodnota na pine zmení z LOW na HIGH (nábežná hrana).
Keď už teraz vieme, čo znamená aký argument, poďme dosadiť konkrétne hodnoty:

Po vykonaní tohto príkazu sa nám na piaty pin nastaví hardvérové prerušenie, ktoré spustíme napr. tlačidlom. Poďme si ešte popísať ISR funkciu, ktorá je odovzdávaná do makra ako argument:

Táto funkcia obsahuje všetky príkazy, ktoré sa majú spustiť, keď je hlavný program prerušený. Návratový typ funkcie IRAM_ATTR zaistí, že bude funkcia uložená do časti pamäte IRAM a nie do pamäte flash, čím zaistíme jej rýchlejšie načítanie.

Keďže táto funkcia blokuje chod hlavného programu, je vhodné používať ju pre čo najkratšie úlohy.

Ako odstrániť prerušenie?

V niektorých prípadoch je potrebné odstrániť prerušenie na dobu neurčitú. Na to nám poslúži funkcia detachInterrupt(). Keďže sme si v predchádzajúcom kroku nastavili prerušenie na pin 5, poďme ho teraz odstrániť:

Po vykonaní tohto príkazu sa pin prestane chovať ako zdroj prerušenia do doby, kedy bude zavolaná funkcia attachInterrupt() alebo bude rebootovaný systém.

Praktický príklad - zhasnutie a rozsvietenie LED diódy

Teraz už vieme všetko, čo potrebujeme na vytvorenie jednoduchého programu, ktorý bude vďaka prerušeniu zhasínať a rozsvecovať LED. K tomuto príkladu budeme potrebovať okrem modulu aj tlačidlo a LED diódu, ktoré spoločne zapojíme podľa nasledujúcej schémy:

Internet vecí s ESP32

Všetko máme zapojené a môžeme sa vrhnúť na kód. Najskôr si nastavíme makrá pre jednotlivé piny a tiež definujeme ISR funkciu:

Pri využívaní prerušenia v programe nie je potrebné definovať funkciu loop(), tá teda zostane prázdna. Zostáva už len doplniť telo funkcie setup(), a to nasledovne:

Pre úplnosť si zrekapitulujme celý program:

Teraz nám bude tlačidlo fungovať ako prepínač, tzn. že po jeho stlačení zmení hodnotu LED diódy na opačnú.

Časovanie

Keď už rozumieme tomu, čo je to prerušenie a ako funguje, môžeme sa pustiť do časovania. Časovanie je v podstate druh prerušenia, pretože generuje prerušenie po určitej časovej dobe. Často sa využíva napríklad ako počítadlo.

Časovanie na module ESP32

Náš mikrokontrolér ESP32 obsahuje dve skupiny časovačov, z ktorých každá skupina obsahuje dva hardvérové časovače. Každý časovač má 64 bitov. Tie sú založené na 16 bitovom prescaleri (delička vstupného signálu). Využívanie časovania je veľmi efektívne, pretože je pri ňom isté, že sa načasované udalosti stanú s presnosťou na milisekundu.

Všetky prerušenia vyvolané časovačom sa radia do softvérových prerušení.

Podľa frekvencie mikrokontroléra sa práve vďaka prescaleru táto frekvencia rozdelí na menšie celky, tzv. ticky. Nám už známa ISR funkcia sa teda vždy spustí po uplynutí určitého počtu tickov.

Poďme si teda zrekapitulovať, ako funguje časovač. Časovač používa počítadlo, ktoré sa zvýši o jedna vždy, keď uplynie určitý časový úsek (tick). Akonáhle bude počítadlo na hodnote, ktorú sme mu v kóde nastavili, časovač spustí prerušenie a počítadlo sa vynuluje.

Praktický príklad - pravidelné blikanie LED diódou

Predstavte si, že chceme každú sekundu bliknúť LED diódou. Ponúka sa použiť funkciu delay(), ale to by zabralo všetok procesorový čas a nemohli by sme vykonávať žiadne iné úlohy. Lepšou cestou je teda použitie časovača. Zapojenie pre tento príklad ponecháme v podstate rovnaké, len z neho vymažeme tlačidlo. V kóde si najskôr zase nastavíme hodnotu makra, vytvoríme premennú pre časovač a nadefinujeme si ISR funkciu:

Do hodnoty makra je dôležité vložiť číslo pinu, do ktorého sme pripojili LED diódu. V prípade, že sa čísla nezhodujú, program nebude fungovať!

Keď máme všetko nastavené, doplníme už len telo funkcie setup() a máme hotovo. Funkcia loop() zostane opäť prázdna, pretože pre ukážku nepotrebujeme vykonávať iné operácie (prerušenie nastane aj tak). Nastavíme pin LED diódy na výstup:

Následne zapneme časovač v našom mikrokontroléri. Prvým parametrom funkcie je číslo časovača, ktorý chceme použiť (hodnoty 0 až 3). Druhým parametrom je hodnota prescalera, z ktorého sa počíta dĺžka jedného ticku. My teraz použijeme hodnotu 80. Tým dosiahneme frekvenciu 1 MHz, čo znamená, že každý tick trvá jednu mikrosekundu. Posledný parameter určuje, či má počítadlo počítať hore (true) alebo dole (false):

Musíme tiež určiť, ktorá funkcia sa má vykonať keď nastane prerušenie. V našom prípade využijeme ISR funkciu naCas(), ktorú sme si vytvorili:

Ďalej nastavíme interval zmeny hodnoty na LED dióde. Na to použijeme funkciu timerAlarmWrite(). Prvý parameter určuje, o ktorý časovač sa jedná, druhý určuje oneskorenie v mikrosekundách a tretí parameter (true) zaisťuje periodické resetovanie časovača:

A konečne len povolíme časovač a náš kód je pripravený na spustenie. Teraz bude LED dióda blikať vždy po jednej sekunde:

Na záver si ešte pre istotu zrekapitulujeme celý program:

V budúcej lekcii, Mód hlbokého spánku na module ESP-32 , si popíšeme mód hlbokého spánku na module ESP-32 a predvedieme si ho na praktickej ukážke.


 

Predchádzajúci článok
Zoznámenie s ESP-32
Všetky články v sekcii
Internet vecí s ESP32
Preskočiť článok
(neodporúčame)
Mód hlbokého spánku na module ESP-32
Článok pre vás napísal Adam Hudeczek
Avatar
Užívateľské hodnotenie:
1 hlasov
Autor se věnuje zejména programování mikrokontrolerů a tvorbou a provozem webových stránek a webových aplikací.
Aktivity