V jednom z predchádzajúcich blogov sme si ukázali ako jednoducho zapojiť segmentový displej. V dnešnom blogu si ukážeme jednoduchý program, pomocou ktorého na segmentovom displeji vypíšeme čísla stlačené na klávesnici. Budeme pracovať s klávesnicou 4×4 AVR 16 klávesov ako je na obrázku nižšie:
V blogu sa pokúsime vysvetliť princíp fungovania takejto klávesnice. Ak potrebujete klávesnicu len použiť a nie je pre Vás dôležité zistiť princíp fungovania, odporúčame prejsť nižšie na časť “Použitie knižnice”.
Obsah článku
Princíp fungovania klávesnice
Na klávesnici sa nachádza 16 tlačidiel, usporiadaných v 4 riadkoch a 4 stĺpcoch. Vnútorný obvod v klávesnici vyzerá nasledovne:
Všetky riadky aj stĺpce sú v počiatočnej polohe, kedy žiadne tlačidlo nie je stlačené, elektricky rozpojené. Stlačením tlačidla sa riadok a stĺpec elektricky prepojí.
Aby sme zistili, v ktorom riadku sa stlačené tlačidlo nachádza, všetky piny napojené na stĺpce nastavíme ako “výstupné” a nastavíme na hodnotu HIGH. Piny napojené na riadky nastavíme ako “vstupné” a kontrolujeme, či a na niektorom z riadkov je taktiež hodnota HIGH. Ak na niektorom z riadkov je HIGH, znamená to, že jedno z tlačidiel v danom riadku je stlačené.
Následne podobným spôsobom zistíme v ktorom stĺpci bolo tlačidlo stlačené. Nastavíme piny stĺpcov ako “vstupné”, piny riadkov ako “výstupné” a výstup na HIGH. Prečítame na ktorom stĺpcovom pine je HIGH a tak zistíme stĺpec.
Takéto čítanie vykonáme v kóde hneď po sebe, takže prebehne rádovo v mikrosekundách a stihneme zaregistrovať, ktoré presne tlačidlo bolo stlačené.
Takto dokáže Arduino zistiť riadok aj stĺpec, v ktorom sa nachádza stlačené tlačidlo. Tabuľka nižšie popisuje, ktorý riadok a ktorý stĺpec sú nastavené na HIGH pri stláčaní jednotlivých tlačidiel klávesnice ak sú riadky a stĺpce pripojené podľa obrázka vyššie.
Ak nastavím stĺpec.. | a súčasne zistím, že… | stlačené tlačidlo je… |
Stĺpec 0 = HIGH | Riadok 0 = HIGH | 1 |
Stĺpec 1 = HIGH | Riadok 0 = HIGH | 2 |
Stĺpec 2 = HIGH | Riadok 0 = HIGH | 3 |
Stĺpec 0 = HIGH | Riadok 1 = HIGH | 4 |
Stĺpec 1 = HIGH | Riadok 1 = HIGH | 5 |
Stĺpec 2 = HIGH | Riadok 1 = HIGH | 6 |
Stĺpec 0 = HIGH | Riadok 2 = HIGH | 7 |
Stĺpec 1 = HIGH | Riadok 2 = HIGH | 8 |
Stĺpec 2 = HIGH | Riadok 2 = HIGH | 9 |
Stĺpec 1 = HIGH | Riadok 3 = HIGH | 0 |
Stĺpec 0 = HIGH | Riadok 3 = HIGH | * |
Stĺpec 2 = HIGH | Riadok 3 = HIGH | # |
Stĺpec 3 = HIGH | Riadok 0 = HIGH | A |
Stĺpec 3 = HIGH | Riadok 1 = HIGH | B |
Stĺpec 3 = HIGH | Riadok 2 = HIGH | C |
Stĺpec 3 = HIGH | Riadok 3 = HIGH | D |
Pri takomto spôsobe rozpoznávania stlačeného tlačidla môže nastať problém, ak máme stlačených viacero tlačidiel naraz alebo stláčanie je rýchle. Tieto problémy by sa dali vyriešiť komplexnejším programom alebo použitím prídavného hardvéru.
- Kábliky 65 kusov M-M rôzne veľkosti1.40€ (bez DPH 1.17€ )
- Klávesnica 4×4 AVR 16 klávesov1.50€ (bez DPH 1.25€ )
- Nepájivé pole 830 bodov2.30€ (bez DPH 1.92€ )
- Arduino Uno R3 precízny klon9.95€ (bez DPH 8.29€ )
Zapojenie a program
Teraz si ukážeme ako zapojiť klávesnicu a 7-segmentový displej a ako napísať program, aby sa na displeji zobrazovali stlačené tlačidlá.
Tabuľka nižšie popisuje, ktorý riadok/stĺpec zapojíme do ktorého pinu na Arduino doske. Označenie riadkov použijeme R1 až R4 a označenie stĺpcov C1 až C4.
Riadok/stĺpec | Popis | Pin |
R1 | Riadok 1 (hore) | 9 |
R2 | Riadok 2 | 8 |
R3 | Riadok 3 | 7 |
R4 | Riadok 4 (dole) | 6 |
C1 | Stĺpec 1 (vľavo) | 5 |
C2 | Stĺpec 2 | 4 |
C3 | Stĺpec 3 | 3 |
C4 | Stĺpec 4 (vpravo) | 2 |
Pomocou obrázku nižšie vieme určiť ktoré segmenty je potrebné rozsvietiť na zobrazenie jednotlivých číslic. Pre viac informácií odporúčame preštudovať náš predchádzajúci blog o segmentovkách.
Program:
//definujeme do ktorých pinov zapojíme jednotlivé segmenty 7-segmentoveho displeja #define segA 11 #define segB 10 #define segDP A0 #define segC A1 #define segD A2 #define segE A3 #define segF 12 #define segG 13 //zapojenie riadkov a stĺpcov klávesnice do pinov int R1 = 9; int R2 = 8; int R3 = 7; int R4 = 6; int C1 = 5; int C2 = 4; int C3 = 3; int C4 = 2; //piny, do ktorých je zapojený 7-segmentový displej, nastavíme na hodnotu OUTPUT void setup() { for(int i = 0 ; i < 14; i++) { pinMode(i, OUTPUT); } pinMode(A0, OUTPUT); //desatinná bodka, pre náš účel nie je tento pin potrebný pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); pinMode(A3, OUTPUT); } //podľa toho, ktorým riadkom a stĺpcom preteká prúd vypíšeme čísla na displeji. //ak nestlačíme žiadne tlačidlo, na displeji nebude svietiť žiadny segment void loop() { int stlpec = zisti_ktory_stlpec(); //==2 int riadok = zisti_ktory_riadok(); //==2 if(riadok == 1 && stlpec == 1 ) { vypis_jednotku(); } if(riadok == 1 && stlpec == 2 ) { vypis_dvojku(); } if(riadok == 1 && stlpec == 3 ) { vypis_trojku(); } //podobnym spôsobom by sme vedeli vypísať aj ďalšie čísla else { vynuluj_segmentovku(); } } int zisti_ktory_riadok() { pinMode(C1, OUTPUT); pinMode(C2, OUTPUT); pinMode(C3, OUTPUT); pinMode(C4, OUTPUT); digitalWrite(C1,LOW); digitalWrite(C2,LOW); digitalWrite(C3,LOW); digitalWrite(C4,LOW); pinMode(R1, INPUT_PULLUP); pinMode(R2, INPUT_PULLUP); pinMode(R3, INPUT_PULLUP); pinMode(R4, INPUT_PULLUP); if(digitalRead(R1) == LOW) { return 1; } if(digitalRead(R2) == LOW) { return 2; } if(digitalRead(R3) == LOW) { return 3; } if(digitalRead(R4) == LOW) { return 4; } return 0; } int zisti_ktory_stlpec() { pinMode(R1, OUTPUT); pinMode(R2, OUTPUT); pinMode(R3, OUTPUT); pinMode(R4, OUTPUT); digitalWrite(R1, LOW); digitalWrite(R2, LOW); digitalWrite(R3, LOW); digitalWrite(R4, LOW); pinMode(C1, INPUT_PULLUP); pinMode(C2, INPUT_PULLUP); pinMode(C3, INPUT_PULLUP); pinMode(C4, INPUT_PULLUP); if(digitalRead(C1) == LOW) { return 1; } if(digitalRead(C2) == LOW) { return 2; } if(digitalRead(C3) == LOW) { return 3; } if(digitalRead(C4) == LOW) { return 4; } return 0; } //funkcia zabezpečujúca aby segmenty displeja boli zhasnuté void vynuluj_segmentovku () { for (int i = 10; i < 14; i++) { digitalWrite(i, LOW); } digitalWrite(A0, LOW); digitalWrite(A1, LOW); digitalWrite(A2, LOW); digitalWrite(A3, LOW); } //nižšie sú definované funkcie na rozsvietenie jednotlivých segmentov podľa toho akú číslicu chceme mať na displeji práve zobrazenú //zastavíme sa pri číslici 3, aby kód nebol príliš dlhý no podobne by sa dalo pokračovať aj na ďalšie číslice void vypis_jednotku () { digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); } void vypis_dvojku () { digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segG, HIGH); digitalWrite(segE, HIGH); digitalWrite(segD, HIGH); } void vypis_trojku () { digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segG, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); }
Použitie knižnice
V tejto časti blogu použijeme už vytvorenú knižnicu, ktorú pred nami napísal niekto iný. Odporúčame použiť:
keypad.zip
Knižnicu je nutné naimportovať alebo rozbaliť a prekopírovať do priečinku kde je nainštalované IDE na cestu Arduino/libraries
Kód s použitím knižnice:
#include <Keypad.h> const byte rows = 4; //počet riadkov const byte cols = 4; //počet stĺpcov char keys[rows][cols] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[rows] = {9, 8, 7, 6}; //piny pre pripojenie riadkov byte colPins[cols] = {5, 4, 3, 2}; //piny pre pripojenie stĺpcov Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols ); void setup(){ Serial.begin(9600); //nadviažeme komunikáciu s PC } void loop(){ char key = keypad.getKey(); //použijeme vstavanú funkciu if (key != NO_KEY){ Serial.println(key); //ak sme niečo stlačili, vypíšeme to v počítači } }
Knižnica má niekoľko funkcií:
void begin(makeKeymap(userKeymap)) – inicializácia klávesnice
char waitForKey() – čakám na stlačenie klávesy, keď nastane, naspäť dostaneme znak stlačenia
char getKey() – neblokujúca funkcia, na stlačenie sa nečaká, ale keď nastane, dostaneme naspäť znak stlačenia
KeyState getState() – naspäť získame stav stlačenia, môžu byť nasledovné: IDLE, PRESSED, RELEASED and HOLD
boolean keyStateChanged() – naspäť dostaneme hodnotu “true” alebo “false” podľa toho, či nastala zmena stavu stlačenia
setHoldTime(unsigned int time) – funkcia pre nastavenie doby stlačenia tlačidla, aby bolo rátané ako stlačené (v milisekudnách)
setDebounceTime(unsigned int time) – čas pre filtrovanie kmitania pri stlačení tlačidla (v milisekundách)
addEventListener(keypadEvent) – funkciu môžeme použiť iba v prípade, ak mikrokontrolér ktorý používame umožňuje prerušenia. Odporúčame vyskúšať kód z príkladov: Examples -> Keypad -> Examples -> EventSerialKeypad
Použité zdroje a ďalšie čítanie
https://www.hackster.io/
https://www.circuitbasics.com/
https://www.teachmemicro.com/
https://playground.arduino.cc/