Tlačítko

V minulém článku jsme si vyzkoušeli blikání LED diodou, které bylo řízené mikroprocesorem se zpožděním. V tomto návodu navážeme připojením tlačítka pro ruční spínání diody a také další diody. Na obrázku níže je ukázka zapojení pomocí nepájivého pole. V rozepnutém stavu spínače je výstup 2 spojen přes odpor na zem, při sepnutí se pak spojí s napájecím napětím. Tomuto odpovídá stav LOW (log. 0) při zapojení na zem a naopak stav HIGH (log. 1) při zapojení na napájecí napětí.

Do nepájivého pole jsem si zapojil tlačítko dle schématu níže a zároveň jsem připojil i LED diodu, pro tento příklad však poslouží i integrovaná dioda na pinu 13.

Ukázkový kód pro vyzkoušení zapojeného tlačítka v kombinaci s LED diodou je velmi jednoduchý a čerpá z minulé lekce blikání. Je rozšířen o připojení a nadefinování pinu pro tlačítko a nastavení pinu jako výstupního. Na začátku smyčky se při každém průběhu načte do proměnné stavTlac stav tlačítka, kdy stisknuté tlačítko odpovídá logické 1 a rozpojené tlačítko logické 0. Po tomto načtení následuje příkaz if, který v případě logické 1 zapne LED diodu. V ostatních případech (zde pouze logická 0) příkaz else LED diodu vypne.

// Tlacitko
// navody.dratek.cz
int tlacPin = 2;    // číslo pinu připojeného tlačítka
int ledPin =  3;      // číslo pinu připojené LED diody

int stavTlac = 0;         // proměnná stavu tlačítka

void setup() {
  // nastavení LED jako výstup
  pinMode(ledPin, OUTPUT);
  // nastavení tlačítka jako vstup
  pinMode(tlacPin, INPUT);
}

void loop() {
  // načtení stavu tlačítka a uložení do proměnné
  stavTlac = digitalRead(tlacPin);

  // kontrola stisku tlačítka
  // pokud je stisknuto tlačítko, stav je HIGH - log. 1
  if (stavTlac == HIGH) {
    // zapne LED diodu
    digitalWrite(ledPin, HIGH);
  }
  // pokud není stisknuto tlačítko, stav je LOW - log. 0
  else {
    // vypne LED diodu
    digitalWrite(ledPin, LOW);
  }
}

Nyní bych rád vysvětlil funkci millis(). Jedná se o funkci, která do proměnné zapíše uběhnutý čas od připojení napájení k mikrokontroléru. Tento čas je v milisekundách a dá se různě využívat. Já jej například využívám právě jako tzv. debounce funkci pro odstranění problémů se zákmity tlačítek. Při stisku se totiž generují různé zákmity signálu, střídají se tedy stavy 0 a 1 a toto může komplikovat práci mikrokontroléru. Popis funkce je v komentářích programu níže.

// Tlacitko
// navody.dratek.cz
int tlacPin = 2;      // číslo pinu připojeného tlačítka
int ledPin =  3;      // číslo pinu připojené LED diody

int enStisk = 1;      // proměnná povolení stisku
long stiskMil = 0;    // proměnná pro čas stisku
int stisk = LOW;      // proměnná pro kontrolu stisku
int stavTlac = 0;     // proměnná stavu tlačítka

void setup() {
  // nastavení LED jako výstup
  pinMode(ledPin, OUTPUT);
  // nastavení tlačítka jako vstup
  pinMode(tlacPin, INPUT);
}

void loop() {
  // načtení stavu tlačítka a uložení do proměnné
  stavTlac = digitalRead(tlacPin);
  // kontrola stisku tlačítka a stavu proměnné povolení
  if (stavTlac == HIGH & enStisk == 1)
  {
    digitalWrite(ledPin, HIGH);
    stisk = HIGH;
  }
  // kontrola stisku tlačítka  
  if(stisk == HIGH) {
    // pokud je stisknuto, do proměnné stiskMil se uloží
    // čas stisku a zakáže se další stisknutí
    stiskMil=millis();
    enStisk = 0;
    stisk = LOW;
  }
  
  if(enStisk == 0) {
    // pokud je při zákazu stisku naměřen rozdíl času stisku
    // a momentálního času větší jak 1000 ms = 1 s,
    // tak je LED dioda vypnuta a povolen další stisk
    if(millis()-stiskMil > 1000) {
      digitalWrite(ledPin, LOW);
      enStisk = 1;
    }
  }
}

Dalším způsobem detekce stisku tlačítka je využití přerušení. U Arduina jsou na tuto funkci vyhrazeny piny 2 a 3, s knihovnou však lze přerušení použít i na pinech ostatních. V této základní lekci jsem využil připojení tlačítka na pin 2. Přerušení lze nastavit různými způsoby, například pro detekci nástupné či sestupné hrany, změny signálu nebo při logické nule na daném pinu. Probíhá zjednodušeně tak, že při přerušení se zastaví smyčka loop v právě prováděném příkazu, provedou se příkazy napsané uvnitř funkce přerušení prerus a poté se pokračuje dále ve smyčce loop. Příklad je opět uveden s komentáři.

// Tlacitko s prerusenim
// navody.dratek.cz
int tlacPin = 2;      // číslo pinu připojeného tlačítka
int ledPin =  3;      // číslo pinu připojené LED diody

int enStisk = 1;      // proměnná povolení stisku
long stiskMil = 0;    // proměnná pro čas stisku
int stisk = LOW;      // proměnná pro kontrolu stisku
int stavTlac = 0;     // proměnná stavu tlačítka

void setup() {
  // nastavení LED jako výstup
  pinMode(ledPin, OUTPUT);
  // nastavení tlačítka jako vstup
  pinMode(tlacPin, INPUT);
  // nastavení přerušení na pin 2 (int0)
  // při náběžně hraně se vykoná program prerus
  attachInterrupt(0, prerus, RISING);
}

void loop() {
  if(enStisk == 0) {
    // pokud je při zákazu stisku naměřen rozdíl času stisku
    // a momentálního času větší jak 1000 ms = 1 s,
    // tak je LED dioda vypnuta a povolen další stisk
    if(millis()-stiskMil > 1000) {
      digitalWrite(ledPin, LOW);
      enStisk = 1;
    }
  }
}

void prerus()
{
  // načtení stavu tlačítka a uložení do proměnné
  stavTlac = digitalRead(tlacPin);
  // kontrola stisku tlačítka a stavu proměnné povolení
  if (stavTlac == HIGH & enStisk == 1)
  {
    digitalWrite(ledPin, HIGH);
    stisk = HIGH;
  }
  // kontrola stisku tlačítka  
  if(stisk == HIGH) {
    // pokud je stisknuto, do proměnné stiskMil se uloží
    // čas stisku a zakáže se další stisknutí
    stiskMil=millis();
    enStisk = 0;
    stisk = LOW;
  }
}

V tomto případě je použití přerušení poměrně zbytečné, ale chtěl jsem ho ukázat na jednoduchém příkladu, z kterého můžete vyvodit další možnosti jeho využití. Tlačítka a mnoho dalšího lze zakoupit na internetovém obchodu dratek.cz

Další podobné články