Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET
Nauč se s námi víc. Využij 50% zdarma na e-learningové kurzy.
C# week

Lekce 19 - Arduino a práce s tlačítky

V minulé lekci, Tvorba vlastní Arduino knihovny - Dokončení, jsme si ukázali, jak vytvořit vlastní plnohodnotnou Arduino knihovnu.

Tlačítko je asi nejjednodušší a zároveň nejproblematič­tější součástka, se kterou může Arduino pracovat. Kromě tlačítka totiž musíme zapojit na daný pin přes rezistor i nějakou výchozí hodnotu, aby nedocházelo k rušení ve chvíli, kdy není stisknuté a na pinu by nebyla přivedena ani 0 ani 1. Úplně snadné není ani, aby jedním stisknutím tlačítka došlo k zapnutí a opětovným stisknutím toho samého tlačítka k vypnutí obvodu. Také můžeme chtít, aby držení tlačítka zvyšovalo hodnotu rychleji, než opakované mačkání tlačítka. To vše si v kurzu ukážeme.

Co je vlastně tlačítko

Tlačítko, nebo chcete-li mikrospínač, je elektromechanická součástka. Slouží k vytvoření krátkodobých ovládacích impulzů tak, že sepne nebo přeruší elektrický obvod:

Tlačítek existuje více druhů

Nejčastější tlačítka ve slaboproudé elektronice se skládají z plastového hmatníku, kovového plíšku a kontaktů. Impulz pak vzniká stlačováním hmatníku, čímž se prohýbá plíšek, který vodivě spojuje kontakty. Po uvolnění tlačítka se plíšek narovná do původní polohy, čímž funguje i jako vratná pružina:

Princip tlačítka

Zapojení tlačítka

V programování se při práci s tlačítky používá jednoduché čtení stavů na digitálním (nebo analogovém) pinu. Tam rozlišujeme pouhé dva stavy:

  • logická jednička (1, HIGH, true).
  • logická nula (0, LOW, false).

Jako logickou 1 bere digitální vstup hodnotu napětí vyšší než 3,0 V (pro desky s napětím 3,3 V je to hodnota 2 V). Jako logickou 0 napětí menší než 1,5 V (1 V pro desky s napětím 3,3 V). Oblast mezi 1,5 V - 3,0 V je tzv. "zakázaná oblast" a procesor na ni nijak nereaguje.

Nestačí ovšem přivést na pin hodnotu jen při stisknutí tlačítka, potřebujeme, aby tam neustále byla jasně definovaná hodnota 1 nebo 0, jinak by došlo k rušení. Výchozí stav se tedy řeší zapojením rezistoru a přivedením permanentně buď stavu 0 nebo 1 na pin, na který je tlačítko připojeno. Těmto dvěma režimům (podle stavu, který permanentně přivedeme) se říká INPUT (pull down) a INPUT_PULLUP (pull up) a každý má své výhody i nevýhody.

Režim INPUT (pull down)

Tento způsob vyžaduje externě připojený "pull-down" rezistor mezi vybraný pin a GND, s hodnotou řádově v kΩ (nepsaným pravidlem je hodnota 10 kΩ). Takto je pin permanentně připojen k zemi přes velký odpor a je na něm tak logická 0 (hodnota LOW). Reagovat pak bude na logickou 1. Tlačítko se poté připojí mezi napájecí napětí 5V a vybraný pin, na který pak stisknutím přivádí hodnotu HIGH.

Osobně mohu tento způsob doporučit, jelikož částečně potlačuje vlivy elektromagnetických rušení, a zvyšuje tak stabilitu projektu.

Pozor! Pokud bychom v této verzi nastavení vstupu zvolili hodnotu rezistoru příliš nízkou, nebo zkratovali pin s GND, může dojít ke zničení procesoru Arduina!

Režim INPUT_PULLUP

Toto je jednodušší varianta, kde se tlačítko připojí mezi pin a GND. Uvnitř procesoru Arduina se připojí k pinu interní "pull-up" rezistor, který na pin přivádí přes velký odpor logickou 1. Tento způsob vyhodnocuje logickou 0 (LOW).

Je vhodný pro ladění na nepájivém kontaktním poli (breadboard), kdy u náročnějších projektů odpadá nutnost externích rezistorů a tedy šetří místo na desce. Avšak v hotovém projektu neodstraňuje vlivy možných rušení.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Rozdíl mezi oběma způsoby je schematicky znázorněn na obrázku:

Arduino pull-up and pull-down rezistory a tlačítko

Příklad programu

Jdeme na praktickou ukázku programu. Ten využívá vestavěnou LED diodu na pinu 13, proto postačí pouze nepájivé pole, pár tlačítek a propojky:

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);
}

Ve smyčce setup() nastavíme piny 3 a 4 jako vstupy. Jeden je typu INPUT a druhý typu INPUT_PULLUP. A samozřejmě nastavíme i výstup na pinu 13. Stisknutím tlačítka na pinu 3 se LEDka rozsvítí, stisknutím tlačítka na pinu 4 zhasne. Vcelku jednoduché a spolehlivé.

Ovládání výstupu jedním tlačítkem

Mít jedno tlačítko na vypnutí a druhé na zapnutí může být někdy na obtíž, protože tlačítko na zapnutí a vypnutí často stačí jen jedno společné. Stisknutím zapneme, dalším stisknutím vypneme atd.

Spolehlivé ovládání jediným tlačítkem se může jevit jako snadný úkol, ale nastává tu řada problémů. Stisk tlačítka totiž nikdy není úplně bez závad.

Špatné řešení - "Zákmity"

Během jediného stisku může být impulz nestálý, jelikož může mít tzv. "zákmity". To vede ke špatnému vyhodnocení signálu. Program si bude myslet, že impulzů bylo během doby jediného stisknutí několik, a podle toho také provede případné operace (inkrementace, dekrementace, změna stavu, vypnutí atd...) spojené s některou proměnnou.

Demonstrativní ukázkou je program níže. Zde je pro jednoduchost použito tlačítko pinu 3 z předchozí ukázky:

bool svitit = false;
void setup()
{
  pinMode(3,INPUT_PULLUP);
  pinMode(13,OUTPUT);
}

void loop()
{
  if(!digitalRead(3))
  {
    svitit = !svitit;
  }
  digitalWrite(13,svitit);
}

Program obsahuje proměnnou typu bool. Každé stisknutí tlačítka na pinu 3 změní její stav z true na false a naopak. Schválně si ho zkuste několikrát stisknout.

Jak jistě vidíte, LED dioda se rozsvěcí a zhasíná ne zcela pravidelně. Každý cyklus programu totiž čte stav tlačítka, a při kmitočtu 16 MHz je to opravdu hodně čtení za jedinou sekundu.

Špatné řešení - Pauza

Problém lze sice ošetřit pauzou prostřednictvím funkce delay() uvnitř těla podmínky, avšak nejedná se o šťastné řešení:

if(!digitalRead(3))
{
  svitit = !svitit;
  delay(200); // doplněná pauza
}

Co je na tomto řešení špatného? Zkuste tlačítko držet stisknuté delší dobu. Jak jistě vidíte, LED dioda vám bliká. To může v některých případech způsobit problém. Pokud obsluha nechtěně přidrží tlačítko, může se pak výsledné zařízení chovat jinak, než je v daný moment žádoucí.

Správné řešení - Cyklus

Možné řešení je pomocí cyklu while. Není zvlášť složité, a jeho výsledek jistě uspokojí nespočet projektů. V programu je použita funkce millis(), která nezávisle na běhu programu počítá čas od spuštění Arduina v milisekundách. Jedná se o velice užitečnou funkci, která na rozdíl od funkce delay() nezasekne běh programu. Daní je ale o trošku složitější práce s ní:

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 proměnnou typu unsigned long casomira, která slouží k měření času. Jakmile dojde ke stisknutí tlačítka, spustí se cyklus, který se provádí tak dlouho, dokud je tlačítko stisknuté. Uvnitř cyklu se měří doba stisku, kdy se od proměnné casomira odečítá hodnota millis(). Tento rozdíl se ukládá do proměnné dobaStisku. Po uvolnění tlačítka měření ustává a následně se testuje, zda je doba stisku větší než požadovaný limit (v ukázce 25 ms). Pokud je tato podmínka splněna, změní se stav proměnné svitit, což vede k rozsvícení/zhasnutí LED diody, a vynuluje se proměnná pro dobu stisku. Právě limit 25 ms v drtivé většině případů spolehlivě eliminuje případné zákmity tlačítka i rušivé vlivy.

Pokud by nedošlo k vynulování doby stisku, byl by program stejně nestabilní, jako v předchozích ukázkách!

Takto máme tedy jistotu, že každý stisk tlačítka bude zaznamenán jako jeden. Tento způsob nás samozřejmě neomezuje pouze na změnu stavů true/false, ale lze ho použit i jinde, například při výběru v menu možností, zvyšování/snižování požadované teploty, času, úrovně intenzity světla atd.

Přeci jen dlouhý stisk

Určitě vás napadne, že když budeme chtít změnit postupnými stisky například hodnotu od 0 do 255 pro PWM regulaci, budeme muset desítky vteřin zběsile mačkat tlačítko, než se jas zvýší na maximum. Nešlo by to nějak pořešit? Samozřejmě, že šlo!

Po lehké úpravě můžeme elegantně tlačítkem měnit jas externí LED diody buď mačkáním, nebo dlouhým stiskem. Zapojte obvod podle přiloženého schématu:

AnalogSche Kód bude nyní následující, hned si jej vysvětlí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;
  }
}

Podmínka uvnitř cyklu říká programu, ať přeruší cyklus pokud dobaStisku překročí hodnotu 150 ms (tato hodnota byla zvolena záměrně takto nízká). Tím je samozřejmě splněna i základní limitní podmínka 25 ms, tedy dojde k navýšení hodnoty PWM o 5 a vynulování doby stisku. V základní podmínce je ještě zarážka pro jas pwm < 255. Bez ní by po překročení hodnoty LED dioda nepříjemně blikla.

Určitě bych při programování více než jednoho tlačítka použil pro tlačítko třídu, nebo si rovnou vytvořil vlastní Knihovnu pro přehlednější práci.

Tím jsme se naučili ovládat tlačítkem Arduino. Určitě si můžete vyzkoušet přidat i část pro snižování jasu a nebo lehce experimentovat. Všechny příklady jsou k dispozici ke stažení pod lekcí.

V příští lekci, Arduino a práce s tlačítky - Knihovna, si pro práci s tlačítkem vytvoříme knihovnu, aby se nám s tlačítkem pohodlněji pracovalo.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 71x (1.53 kB)

 

Předchozí článek
Tvorba vlastní Arduino knihovny - Dokončení
Všechny články v sekci
Arduino
Článek pro vás napsal Václav Doškář
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor pracuje jako pedagog v oblasti elektroniky a elektrotechniky. Programování má jako koníčka. Věnuje se jazykům C++ a C#.
Aktivity

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!