19. diel - Arduino a práca s tlačidlami
V minulej lekcii, Tvorba vlastnej Arduino knižnice - Dokončenie , sme si ukázali, ako vytvoriť vlastné plnohodnotnú Arduino knižnicu.
Tlačidlo je asi najjednoduchšie a zároveň najproblematickejšie
súčiastka, s ktorou môže Arduino pracovať. Okrem tlačidla totiž
musíme zapojiť na daný pin cez rezistor aj nejakú predvolenú hodnotu, aby
nedochádzalo k rušeniu vo chvíli, kedy nie je stlačené a
na pinu by nebola privedená ani 0
ani 1
. Úplne
jednoduché nie je ani, aby jedným stlačením tlačidla došlo k zapnutiu a
opätovným stlačením toho istého tlačidla na vypnutie
obvodu. Tiež môžeme chcieť, aby držanie tlačidla zvyšovalo
hodnotu rýchlejšie, než opakované stláčanie tlačidla. To všetko
si v kurze ukážeme.
Čo je vlastne tlačidlo
Tlačidlo, alebo ak chcete mikrospínač, je elektromechanické súčiastka. Slúži na vytvorenie krátkodobých ovládacích impulzov tak, že zopne alebo preruší elektrický obvod:
Najčastejšie tlačidla vo slaboprúdové elektronike sa skladajú z plastového hmatníka, kovového pliešku a kontaktov. Impulz potom vzniká stláčaním hmatníka, čím sa prehýba pliešok, ktorý vodivo spája kontakty. Po uvoľnení tlačidla sa pliešok narovná do pôvodnej polohy, čím funguje aj ako vratná pružina:
Zapojenie tlačidla
V programovania sa pri práci s tlačidlami používa jednoduché čítanie stavov na digitálnom (alebo analógovom) pinu. Tam rozlišujeme iba dva stavy:
- logická jednička (
1
, HIGH,true
). - logická nula (
0
, LOW,false
).
Ako logickú 1
berie digitálny vstup hodnotu
napätia vyššie ako 3,0 V (pre dosky s napätím 3,3 V je to hodnota 2 V). Ako
logickú 0
napätie menšie ako 1,5 V (1 V pre dosky s napätím
3,3 V). Oblasť medzi 1,5 V - 3,0 V je tzv. "Zakázaná oblasť" a procesor na
ňu nijako nereaguje.
Nestačí však priviesť na pin hodnotu len pri stlačení tlačidla,
potrebujeme, aby tam neustále bola jasne definovaná hodnota 1
alebo 0
, inak by došlo k rušeniu. Východiskový
stav sa teda rieši zapojením rezistora a privedením
permanentne buď stavu 0
alebo 1
na pin, na ktorý je
tlačidlo pripojené. Týmto dvom režimom (podľa stavu, ktorý permanentne
privedieme) sa hovorí INPUT
(pull down) a
INPUT_PULLUP
(pull up) a každý má svoje výhody aj
nevýhody.
Režim INPUT
(pull down)
Tento spôsob vyžaduje externe pripojený "pull-down" rezistor medzi
vybraný pin a GND
, s hodnotou rádovo v kOhm (nepísaným
pravidlom je hodnota 10 kOhm). Takto je pin permanentne
pripojený k zemi cez veľký odpor a je na ňom tak logická 0
(hodnota LOW). Reagovať potom bude na logickú
1
.
Osobne môžem tento spôsob odporučiť, pretože čiastočne potláča vplyvy elektromagnetických rušenie, a zvyšuje tak stabilitu projektu.
Pozor! Ak by sme v tejto verzii nastavenie
vstupu zvolili hodnotu rezistora príliš nízku, alebo skratom pin s
GND
, môže dôjsť k zničeniu procesora
Arduino!
Režim INPUT_PULLUP
Toto je jednoduchší variant, kde sa tlačidlo pripojí medzi pin a
GND
. Vnútri procesora Arduino sa pripojí k pinu interný
"pull-up" rezistor, ktorý na pin privádza cez veľký
odpor logickú 1
. Tento spôsob vyhodnocuje logickú
0
(LOW).
Je vhodný pre ladenie na nepájivém kontaktným poli (breadboard), kedy u náročnejších projektov odpadá nutnosť externých rezistorov a teda šetrí miesto na doske. Avšak v hotovom projekte neodstraňuje vplyvmi možných rušenia.
Rozdiel medzi oboma spôsobmi je schematicky znázornený na obrázku:
Príklad programu
Ideme na praktickú ukážku programu. Ten využíva vstavanú LED diódu na
pinu 13
, preto postačí iba nepájivé poľa, pár tlačidiel a
prepojky:
void setup() { pinMode(3,INPUT_PULLUP); pinMode(4,INPUT); pinMode(13,OUTPUT); } void loop() { if(!digitalRead(3)) digitalWrite(13,1); // lze také použít výraz (digitalRead(3)==LOW) if(digitalRead(4)) digitalWrite(13,0); }
V slučke setup()
nastavíme piny 3
a
4
ako vstupy. Jeden je typu INPUT
a druhý typu
INPUT_PULLUP
. A samozrejme nastavíme aj výstup na pinu
13
. Stlačením tlačidla na pinu 3
sa LEDka
rozsvieti, stlačením tlačidla na pinu 4
zhasne. Vcelku
jednoduché a spoľahlivé.
Ovládanie výstupu jedným tlačidlom
Mať jedno tlačidlo na vypnutie a druhé na zapnutie môže byť niekedy na obtiaž, pretože tlačidlo na zapnutie a vypnutie často stačí len jedno spoločné. Stlačením zapneme, ďalším stlačením vypneme atď.
Spoľahlivé ovládanie jediným tlačidlom sa môže javiť ako ľahká úloha, ale nastáva tu rad problémov. Stlačenie tlačidla totiž nikdy nie je úplne bez závad.
Zlé riešenie - "zákmity"
Počas jediného stlačenia môže byť impulz nestály, pretože môže mať tzv. "Zákmity". To vedie k zlému vyhodnotenie signálu. Program si bude myslieť, že impulzov bolo počas doby jediného stlačenia niekoľko, a podľa toho tiež vykoná prípadné operácie (inkrementácia, dekrementace, zmena stavu, vypnutie atď ...) spojené s niektorou premennou.
Demonštratívny ukážkou je program nižšie. Tu je pre jednoduchosť
použité tlačidlo pinu 3
z predchádzajúcej ukážky:
bool svitit = false; void setup() { pinMode(3,INPUT_PULLUP); pinMode(13,OUTPUT); } void loop() { if(!digitalRead(3)) { svitit = !svitit; } digitalWrite(13,svitit); }
Program obsahuje premennú typu bool
. Každé stlačenie
tlačidla na pinu 3
zmení jej stav z true
na
false
a naopak. Schválne si ho skúste niekoľkokrát
stlačiť.
Ako iste vidíte, LED dióda sa rozsvecuje a zhasína nie celkom pravidelne. Každý cyklus programu totiž číta stav tlačidlá, a pri kmitočte 16 MHz je to naozaj veľa čítania za jedinú sekundu.
Zlé riešenie - Pauza
Problém možno síce ošetriť pauzou prostredníctvom funkcie
delay()
vo vnútri tela podmienky, avšak nejedná sa o šťastné
riešenie:
if(!digitalRead(3)) { svitit = !svitit; delay(200); // doplněná pauza }
Čo je na tomto riešení zlého? Skúste tlačidlo držať stlačené dlhšiu dobu. Ako iste vidíte, LED dióda vám bliká. To môže v niektorých prípadoch spôsobiť problém. Pokiaľ obsluha nechtiac pridrží tlačidlo, môže sa potom výsledné zariadenie správať inak, než je v daný moment žiaduce.
Správne riešenie - Cyklus
Možné riešenie je pomocou cyklu while
. Nie je zvlášť
zložité, a jeho výsledok určite uspokojí nespočet projektov. V programe je
použitá funkcia millis()
, ktorá nezávisle na behu programu
počíta čas od spustenia Arduino v milisekundách. Jedná sa o veľmi
užitočnú funkciu, ktorá na rozdiel od funkcie delay()
nezasekne
beh programu. Daní je ale o trošku zložitejšie práce s ňou:
unsigned long casomira; int dobaStisku, limit= 25; bool svitit = false; void setup() { pinMode(3,INPUT_PULLUP); pinMode(13,OUTPUT); } void loop() { casomira = millis(); digitalWrite(13,svitit); while(!digitalRead(3)) { dobaStisku = millis()-casomira; } if(dobaStisku >= limit) { svitit = !svitit; dobaStisku = 0; } }
Program obsahuje premennú typu unsigned long casomira
, ktorá
slúži na meranie času. Akonáhle dôjde ku stlačení tlačidla, spustí sa
cyklus, ktorý sa vykonáva tak dlho, kým je tlačidlo stlačené. Vnútri
cyklu sa meria doba stisku, kedy sa od premenné casomira
odpočítava hodnota millis()
. Tento rozdiel sa ukladá do
premennej dobaStisku
. Po uvoľnení tlačidla merania ustáva a
následne sa testuje, či je doba stlačenia väčšia ako požadovaný limit (v
ukážke 25
ms). Ak je táto podmienka splnená, zmení sa stav
premenné svitit
, čo vedie k rozsvieteniu / zhasnutie LED diódy,
a vynuluje sa premenná pre dobu stlačenia. Práve limit 25
ms v
drvivej väčšine prípadov spoľahlivo eliminuje prípadné zákmity tlačidla
i rušivé vplyvy.
Ak by nedošlo k vynulovanie doby stisku, bol by program rovnako nestabilné, ako v predchádzajúcich ukážkach!
Takto máme teda istotu, že každý stlačenie tlačidla bude zaznamenaný
ako jeden. Tento spôsob nás samozrejme neobmedzuje iba na zmenu stavov
true
/ false
, ale možno ho použiť aj inde,
napríklad pri výbere v menu možností, zvyšovanie / znižovanie požadovanej
teploty, času, úrovne intenzity svetla atď.
Predsa len dlhé stlačenie
Určite vás napadne, že keď budeme chcieť zmeniť postupnými
stlačeniami napríklad hodnotu od 0
do 255
pre PWM
reguláciu, budeme musieť desiatky sekúnd zbesilo stláčať tlačidlo, než
sa jas zvýši na maximum. Nešlo by to nejako pořešit? Samozrejme, že
išlo!
Po ľahkej úprave môžeme elegantne tlačidlom meniť jas externé LED diódy buď stláčaním, alebo dlhým stlačením. Zapojte obvod podľa priloženej schémy:
Kód bude teraz nasledujúce, hneď si ho vysvetlíme:
unsigned long casomira; int dobaStisku, limit=25; byte pwm = 0; void setup() { pinMode(3,INPUT_PULLUP); pinMode(5,OUTPUT); } void loop() { casomira = millis(); analogWrite(5,pwm); while(!digitalRead(3)) { dobaStisku = millis()-casomira; if(dobaStisku > 150) { break; } } if(dobaStisku >= limit && pwm < 255) { pwm += 5; dobaStisku = 0; } }
Podmienka vnútri cyklu hovorí programu, či preruší cyklus pokiaľ
dobaStisku
prekročí hodnotu 150
ms (táto hodnota
bola zvolená zámerne takto nízka). Tým je samozrejme splnená aj základné
limitný podmienka 25
ms, teda dôjde k navýšeniu hodnoty PWM o
5
a vynulovanie doby stisku. V základnej podmienke je ešte
zarážka pre jas pwm < 255
. Bez nej by po prekročení hodnoty
LED dióda nepríjemne blikla.
Určite by som pri programovaní viac ako jedného tlačidla použil pre tlačidlo triedu, alebo si rovno vytvoril vlastnú Knižnicu pre prehľadnejšie prácu.
Tým sme sa naučili ovládať tlačidlom Arduino. Určite si môžete vyskúšať pridať aj časť pre znižovanie jasu a alebo ľahko experimentovať. Všetky príklady sú k dispozícii na stiahnutie pod lekcií.
V budúcej lekcii, Arduino a práca s tlačidlami - Knižnica , si pre prácu s tlačidlom vytvoríme knižnicu, aby sa nám s tlačidlom pohodlnejšie pracovalo.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 295x (1.53 kB)