Lekce 21 - Arduino a využití přerušení (interrupt) a ošetření záchvěvů při stisku tlačítka
22.06.2013 21:25Translate to English
V dnešní lekci si řekneme něco o přerušení neboli anglicky"interrupt". Určitě jste si říkali někdy při psaní programu do Arduina, že program nebo cyklus programu musíte napsat tak, aby v cyklech např zjišťoval, zda nebylo stisknuto nějaké tlačítko. V malém programu na pár řádků to není problém, ale pokud máme nějaký program, kde smyčka v "loop" trvá např. 2 sekundy, tak přidávat funkci zda uživatel stiskl nějaké tlačítko by byl nesmysl a také co když se uživatel zrovna "trefí" do času, kdy program dělá něco jiného. Řešení je právě tzv. "přerušení", které zastaví aktuální běh programu, a vykoná funkci, která je zapsaná, aby se při tomto právě vykonala. Jinak řečeno, když Arduino dostane na pin, kde je možné nastavit přerušení, nějaký určený impuls, zastaví běh programu a vykoná něco jiného.
Tabulka pinů, kde je možno nastavit přerušení:
Arduino | 0 | 1 | 2 | 3 | 4 | 5 |
UNO, Ethernet | 2 | 3 | -- | -- | -- | -- |
Mega 2560 | 2 | 3 | 21 | 20 | 19 | 18 |
Leonardo | 3 | 2 | 0 | 1 | 7 | -- |
Zápis funkce, která aktivuje přerušení:
attachInterrupt(přerušení, funkce, mód);
Příklad:
attachInterrupt(1, Reakce, RISING); - což v překladu znamená, že se spustí funkce Reakce(), když se na pinu 3 (Arduino UNO), změní hodnota z LOW na HIGH
V tabulce nahoře vidíme, kde naše Arduino má piny kde lze aktivovat přerušení. V případě Arduina UNO máme přerušení dvě na pinech 2 a 3 a v případě Arduino MEGA (typ 2560) je možnost nastavit přerušeních dokonce 6 na pinech, uvedených v tabulce. V případech jiných typů Arduina, byste měli přerušení nalézt v jejich dokumentaci.
My si nyní zkusíme jednoduchý praktický příklad. Nějak zaměstnáme Arduino a budeme chtít, aby něco udělal když detekuje přerušení. Do Arduina si nahrajeme tedy tento program:
Sami můžete vidět, že je to kód jenom pro demonstraci. Nic užitečného nedělá jen v cyklech něco počítá a čísla cyklu vypisuje na sériový port. Ale tím jsme Arduino zaměstnali a můžeme vyzkoušet přerušení, které jsme si v setup() nastavili na pin 2 (přerušení 1 u UNO), vykoná funkci test (ta jenom rozsvítí nebo zhasne LED integrovanou na Arduinu k pinu 13), a bude aktivována když se na pinu 2 (přerušení) změní hodnota z LOW na HIGH.
Samozřejmně by jsem k Arduinu připojil tlačítko, aby jsme simulovali změnu honoty na přerušení tlačítkem, ale neučiním tak a to z důvodu, který zjistíme dále. Jako zdroj této změny jsem si naprogramoval jednoduchým kódem druhé Arduino (MEGA), které pouze bliká ledkou integrovanou k pinu 13 na svoji desce.
Kód pro druhé Arduino:
Takže jedno Arduinko nám dává hezký signál, který je připojený na ke druhému Arduino. To spustí funkci, kterou má nastavenou, když v našem případě jde signál z 0 do 1. My jsme nastavili mód detekce na RISING, ale možností je více jak ukazuje následující tabulka:
spustí funkci při přechodu z 0 na 1 | |
spustí funkci při přechodu z 1 na 0 | |
spustí funkci při kterékoliv změně jak z 1 na 0, tak z 0 na 1 | |
spustí funkci pro 0 (LOW) |
Tak tento příklad funguje bezvadně a i když si Arduino ve funkci loop() hezky něco dělá, nemusíme ošetřovat v kódu a zjišťovat zda bylo přerušení aktivováno. V běžné praxi budeme, ale chtít, aby jsme třeba zjistili, zda bylo stisknuto nějaké tlačítko. No není problém, připojíme si tedy místo Arduina s naším uměle vyrobeným signálem tlačítko, které když stiskneme, tak budeme chtít, aby se rozsvítila nebo zhasla LED (digital 13) na Arduinu. Připojíme si ho tedy (samozřejmě dle zvyklostí musí být vstupní pin připojen přes odpor k 0 nebo 1 a tlačítkem měníme hodnotu).
Tak a co se nám děje? funguje to zcela nespolehlivě, někdy nám dioda zhasne nebo se rozsvítí, ale né podle pravidel. Funguje to náhodně. A teď otázka, čím je to způsobeno? Vysvětlení je jednoduché. Tlačítko je vlastně elektromechanický prvek, který když stiskneme tak v našem reálném čase byť je to zcela okem nezjistitelné dojde při zapnutí, nebo rozpojení tlačítka k záchvěvům (bouncing). Viz obrázek z osciloskopu:
Takže Arduino to vyhodnotí jako několik stisknutí i když jsme tlačítko stisky pouze jednou. Takže pokud náš program vyhodnotí a spustí 4x funkci k přerušení (protože zjistil 4x změnu z 0 na 1) tak spustí také 4x funkci test, která ze stavu vypnuté LED - zapne, vypne, zapne, vypne. Takže my si vlastně můžeme myslet, že to nefunguje, ale funguje to zcela správně. Co tedy udělat. Existují 2 způsoby, buď to ošetřit v programu tím, že po zjištění prvního přerušení toto přerušení vypneme nebo deaktivujeme, vykonáme co potřebujeme, poté počkáme třeba 300 ms a následně zase přerušení aktivujeme, tak je upraveno zde:
Má to ovšem i své nevýhody. Zastavíme tím program na 300ms a také nemáme jistotu co se stane, když stisk bude trvat déle jak 300ms. Takže moje rada používat toto jen v nejnutnějších případech a z rozvahou.
Pozn.: V mém případě nepomohlo ani nastavení prodlevy na 500ms a ledka si po stisknutí tlačítka dělala co chtěla.
Druhá možnost je ošetřit tyto záchvěvy elektronicky pomocí několika málo součástek. Bude se jednat o obvod RC složený z kondenzátoru a odporu a jednoho integrovaného obvodu 40106, který obsahuje 6x Schmittův klopný obvod. Zakladní schéma je zde:
Princip je následovný. Když stiskneme tlačítko vybijeme kondenzátor C1, tím se vstupu Schmittova klopného obvodu objeví 0. Po uvolnení tlačítka se kondenzátor opět nabije. Pro zvádavé nabití kondenzátoru C1 si můžeme vypočíst podle vzorce t = R*C (10 000 Ohm * 0,00001 F) což je 0,1sec. Pro nás nepodstatné. Využijeme vlasnosti Schmittova klopného obvodu, který upraví signál do podoby podle obrázku (vidíme tam i průběh před na vstupu klopného obvodu i na výstupu)
Schmittův KO slouží k úpravě tvaru impulzů. Jeho základní vlastností je hystereze. To znamená, že jeho výstup je závislý nejen na hodnotě vstupu, ale i na jeho původním stavu. Hystereze, která je jindy nežádoucí, má zde své opodstatnění v tom, že zabraňuje vzniku zákmitů výstupního signálu v okolí střední úrovně spínání. Citlivost obvodu se nastavuje šíří-velikostí hystereze. Obvod je možno využít i jako jednobitový analogově digitální převodník - komparátor.
Schema zapojení pinů obvodu 40106, existuje několik integrovaných obvodů, které Schmittovy klopné obvody obsahují - máte mnoho možností při nákupu.
Jinak mnou uvedený integrovaný obvod obsahuje celkem 6 uvedených klopných obvodů, takže k 6ti tlačítkům nám stačí 1 integráček. Až ho budete kupovat, zjistíte, že jeho cena je opravdu nízká :-).
Poté co máme zapojeno, vyzkoušíme a zjistíme, že to funguje touto metodou opravdu skvěle. Odstranění záchvěvů při práci s tlačítky a využití přerušení v Arduinu myslím, že využijete a doufám, že Vám tento návod pomohl a posunul Vaše vědomosti a malý kousek dále.
———
ZpětDiskusní téma: Lekce 21 - Arduino a využití přerušení (interrupt) a ošetření záchvěvů při stisku tlačítka
Datum | 19.07.2013 |
---|---|
Vložil | Dan |
Titulek | Moje praktické využití :-) |
Tak jsem včera zkoušel přenastavit u mojí jednopanelové FVE (https://90.182.76.49:8090) logování výkonu.
Původní stav byl, že jsem ve smyčce odečítal napětí na analogovém vstupu a když došlo ke změně (podružný elektroměr sepnul na výstupu S0), tak se spustila funkce pro zápis odečtu jedné Wh (1 imp/Wh) do MySQL.
Nově jsem využil přerušení (s ošetřeným chvěním),ale nic se nedělo. Ve funkci definované v přerušení jsem spouštěl druhou funkci pro zápis do MySQL. Pokusem jsem zjistil, že to nefunguje, ale fungovala mi změna hodnoty na digitálním pinu. A tak jsem to ošetřil tak, že se pomocí přerušení změní hodnota na dig.pinu na HIGH a v loop když je na pinu HIGH, tak se následně spustí funkce pro MySQL a následně se pin vrátí na LOW. A takhle to jede dál do dalšího přerušení.
Mezitím běží v loop měření AC proudu pomocí metody z OpenEnergyMonitor.org a zobrazuje se na displeji.
Funguje to a je to hezké :-))
———
Datum | 10.07.2013 |
---|---|
Vložil | Dan |
Titulek | Co potom ... ? |
Možná jsem to přehlédl, nebo to nebylo uvedeno. Když tedy dojde k přerušení a následnému vykonání funkce definované v přerušení, jak bude Arduino pokračovat? Bude pokračovat v "rozdělané" práci, nebo začne smyčku loop vykonávat nově od začátku? Díky za odpověď.
———
Datum | 11.07.2013 |
---|---|
Vložil | Admin |
Titulek | Re: Co potom ... ? |
Bude pokračovat v rozdělené práci. :-)