V minulém dílu seriálu článků o kitu TinyLab jsme si ukázali, jak se dá měřit teplota pomocí teploměru, který najdeme na desce. Dnes se budeme věnovat součástkám o poznání jednodušším – podíváme se, jak číst vstup z tlačítek.
Dobrá zpráva na začátek
Ve článku Tinylab: Nezbytný základ jsem psal, že knihovny, které jsou k desce Tinylab dostupné, nejsou kompatibilní s nejnovějším Arduino IDE a musíte proto využít starší verzi prostředí. Tento problém se nám podařilo s výrobcem vyřešit a nyní už je tedy možné využívat nejnovější Arduino IDE!
Tlačítka
Tlačítko je velice jednoduchá mechanická součástka. Funguje úplně stejně, jako kdybychom měli dva dráty a ty k sobě připojovali a odpojovali. V tlačítku skutečně dochází ke spojování a rozpojování dvou vodičů, jen je to o poznání pohodlnější. Tento princip je patrný i ze schématické značky pro tlačítko, kterou vidíte vpravo na obrázku níže.
To, že je tlačítko jednoduchá mechanická součástka s sebou nese i jedno nebezpečí – když ho zmáčkneme, může dojít k zákmitu. Tedy k tomu, že se obvod spojí, na chvilku rozpojí a zase spojí. Nejjednodušším způsobem, jak se takovému zákmitu bránit, je po zjištění stlačení/uvolnění tlačítka chvilku počkat, než provedeme další měření stavu tlačítka (asi 0,1s, tedy 100ms).
Na desce Tinylab máme tlačítka připojená následujícím způsobem:
S1 | 9 |
S2 | 8 |
S3 | A5 – LOW |
S4 | A5 – HIGH |
Jak vidíme, tlačítka S1 a S2 jsou připojená na digitálních pinech 9 a 8. Tlačítka S3 a S4 jsou obě připojená na analogovém pinu A5. Obsluhu obou typů pinů si dále popíšeme.
Tlačítka na digitálních pinech
Abychom mohli měřit stav na digitálním pinu, musíme ho nejdříve nastavit jako vstup. To provedeme pomocí funkce pinMode, kterou už známe z používání LED, kde jsme podobně pin nastavovali jako výstup.
pinMode(pin, INPUT);
Nyní už můžeme číst logickou úroveň na pinu, což provedeme pomocí funkce digitalRead.
digitalRead(pin);
Tato funkce nám vrátí buďto logickou 0 (LOW), nebo 1 (HIGH).
Zkusme si nyní rozsvěcovat a zhasínat LEDku podle zmáčknutí tlačítka. Využijeme tlačítko S1 (pin 9) a LED L1 (pin 13). Nezapomeňme na přepnutí přepínačů u těchto pinů do pozice ON. Tlačítka na desce Tinylab jsou zapojená tak, že při nestisknutém stavu na jejich pinu naměříme logickou 1, při stisku logickou 0, takže ještě budeme muset otočit logickou hodnotu, což zajistíme logickým operátorem vykřičník (!).
byte led = 13; byte tlacitko = 9; void setup() { pinMode(led, OUTPUT); pinMode(tlacitko, INPUT); } void loop() { byte stav = digitalRead(tlacitko); digitalWrite(led, !stav); }
Tento příklad je poměrně jednoduchý. Co takhle mít tlačítko, které jedním stiskem LED zapne a druhým vypne? K tomu si vytvoříme dvě pomocné proměnné. V jedné si budeme pamatovat, jestli bylo tlačítko stisknuté nebo uvolněné v předchozím průchodu. V druhé budeme mít stav LED (svítí / nesvítí). V tomto případě přidáme už i čekání na odeznění zákmitů.
byte led = 13; byte tlacitko = 9; // proměnná pro uložení předchozího stavu tlačítka // budeme zkoumat, jestli se stav nezměnil byte posledniStav = LOW; // led svítí / je zhasnutá byte stavLed = HIGH; void setup() { pinMode(led, OUTPUT); pinMode(tlacitko, INPUT); } void loop() { byte stav = digitalRead(tlacitko); delay(100); // počkáme na odeznění zákmitů if(stav != posledniStav) { // pokud se stav změnil if(stav == LOW) { // tlačítko je stisknuté stavLed = !stavLed; // změníme stav led zhasnuto -> rozsvíceno a naopak } digitalWrite(led, stavLed); posledniStav = stav; } }
Dokážete vymyslet další použití tlačítek? Třeba přepínat postupně mezi jednotlivými LED pomocí jednoho tlačítka?
Tlačítka na analogových pinech
Tlačítka S3 a S4 jsou na desce Tinylab připojená k analogovému pinu A5. Stiskem tlačítek můžeme sledovat změnu měřené analogové hodnoty na pinu A5. Následujícím programem můžeme prozkoumat, jak se tato hodnota při stisku mění. Opět nezapomeneme zapnout spínač u pinu A5.
void setup() { Serial.begin(9600); } void loop() { Serial.println(analogRead(A5)); delay(500); }
V mém případě mi monitor sériové linky vypisuje bez stisku tlačítka hodnotu 0, při stisku S3 hodnotu 205, při stisku S4 hodnotu 510 a při stisku obou současně hodnotu 568. Tyto hodnoty se mohou mírně lišit a jsou závislé například na použitých součástkách. S tím musíme v programu počítat a pracovat s určitou tolerancí (při stisku S3 nemusí být přesně 205, ale třeba 200-210). Vytvořme si program, který nám po sériové lince pošle informace o tom, jaká tlačítka jsou stisknutá. Měření analogové hodnoty na pinu A5 provedeme pomocí funkce analogRead , kterou známe ze článku o potenciometru.
void setup() { Serial.begin(9600); } void loop() { int hodnota = analogRead(A5); if(hodnota >= 0 && hodnota <= 10) { // hodnota je mezi 0 a 10 Serial.println("Zadne tlacitko"); } else if (hodnota >= 200 && hodnota <= 210){ Serial.println("S3 stisknuto"); } else if (hodnota >= 505 && hodnota <= 515){ Serial.println("S4 stisknuto"); } else if (hodnota >= 563 && hodnota <= 573) { Serial.println("S3 i S4 stisknuta"); } delay(1000); }
Vymyslíte i další využití tlačítek, které jsme si dnes představili? Třeba ovládání výšky tónu bzučáku pomocí dvou tlačítek? Nebo ovládání různých sekvencí blikání LED?