Fiókom
TERMÉK KATEGÓRIÁK
09/28/2022 Használati útmutató: Billentyűzet csatlakoztatása + kód

Használati útmutató: Billentyűzet csatlakoztatása + kód

Az egyik korábbi blogbejegyzésünkben bemutattuk, milyen egyszerűen lehet csatlakoztatni egy szegmenses kijelzőt. A mai bejegyzésben egy egyszerű programot készítünk, amellyel a billentyűzeten megnyomott számokat jelenítjük meg a szegmenses kijelzőn. Egy 4×4-es, 16 gombos AVR billentyűzettel fogunk dolgozni, ahogy az az alábbi ábrán is látható:

Ebben a blogban megpróbáljuk elmagyarázni egy ilyen billentyűzet működési elvét. Ha Önnek csak a billentyűzet használata a fontos, és nem kíván belemerülni a működés elméletébe, ugorjon lejjebb a „Könyvtár használata” című részhez.

A billentyűzet működési elve

A billentyűzeten 16 gomb található, 4 sorba és 4 oszlopba rendezve. A billentyűzet belső kapcsolása a következőképpen néz ki:

Alaphelyzetben, amikor egyik gomb sincs lenyomva, a sorok és oszlopok elektromosan nincsenek összekapcsolva. Gombnyomáskor a megfelelő sor és oszlop vezető összekapcsolódik.

Annak meghatározásához, hogy melyik sorban történt a gombnyomás, a billentyűzet oszlopaihoz csatlakoztatott pineket kimeneti módba állítjuk és HIGH szintre húzzuk. A sorokhoz csatlakoztatott pineket bemenetként konfiguráljuk, és ellenőrizzük, hogy bármelyik soron megjelenik-e a HIGH szint. Ha igen, akkor tudjuk, hogy az adott sor valamelyik gombját megnyomták.

Ezt követően hasonló módon meghatározzuk, melyik oszlopban volt a gombnyomás. Az oszlopokat bemenetre állítjuk, a sorokat kimenetre és HIGH szintre kapcsoljuk. Leolvassuk, melyik oszloppinen jelenik meg HIGH, így megkapjuk a pontos oszlopot.

A sor és oszlop beolvasása a programban közvetlen egymás után történik, ez mikro­szekundumos nagyságrendű, így pontosan detektálható, melyik gombot nyomták meg.

Ilyen módon az Arduino képes meghatározni a sor és oszlop koordinátákat, ahol a gombnyomás történt. Az alábbi táblázat mutatja, melyik sor és oszlop lesz HIGH állapotban az egyes gombok lenyomásakor, ha a bekötés az ábrán látható módon történt.

Ha az oszlopot állítom be..és egyúttal megállapítom, hogy…a lenyomott gomb…
Oszlop 0 = HIGHSor 0 = HIGH1
Oszlop 1 = HIGHSor 0 = HIGH2
Oszlop 2 = HIGHSor 0 = HIGH3
Oszlop 0 = HIGHSor 1 = HIGH4
Oszlop 1 = HIGHSor 1 = HIGH5
Oszlop 2 = HIGHSor 1 = HIGH6
Oszlop 0 = HIGHSor 2 = HIGH7
Oszlop 1 = HIGHSor 2 = HIGH8
Oszlop 2 = HIGHSor 2 = HIGH9
Oszlop 1 = HIGHSor 3 = HIGH0
Oszlop 0 = HIGHSor 3 = HIGH*
Oszlop 2 = HIGHSor 3 = HIGH#
Oszlop 3 = HIGHSor 0 = HIGHA
Oszlop 3 = HIGHSor 1 = HIGHB
Oszlop 3 = HIGHSor 2 = HIGHC
Oszlop 3 = HIGHSor 3 = HIGHD

Ennél a felismerési módszernél előfordulhat, hogy problémák lépnek fel több gomb egyidejű lenyomásakor, illetve nagyon gyors gombnyomások esetén. Ezek kezelhetők összetettebb programozással vagy kiegészítő hardverrel.

Bekötés és program

Most bemutatjuk, hogyan kell bekötni a billentyűzetet és a 7 szegmenses kijelzőt, valamint hogyan lehet programot írni a megnyomott gombok megjelenítésére. 

Az alábbi táblázat meghatározza, hogy a billentyűzet sorait (R1–R4) és oszlopait (C1–C4) mely Arduino pinekhez kell csatlakoztatni.

Sor/oszlopLeírásPin
R1Sor 1 (fel)9
R2Sor 28
R3Sor 37
R4Sor 4 (le)6
C1Oszlop 1 (bal)5
C2Oszlop 24
C3Oszlop 33
C4Oszlop 4 (jobb)2

Az ábra segítségével láthatjuk, hogy az egyes számjegyek megjelenítéséhez mely szegmenseket kell felkapcsolni. Részletesebb információkért ajánljuk a korábbi blogbejegyzésünket a szegmenses kijelzőkről.

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

Könyvtár használata

Ebben a részben egy már elkészült, más által írt könyvtárat fogunk használni. Ajánlott könyvtár:
keypad.zip
A könyvtárat importálni kell, vagy ki kell csomagolni, majd bemásolni az Arduino IDE telepítési mappájába a következő útvonalra: Arduino/libraries

Kód a könyvtár használatával:

#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
  }
}

A könyvtár funkciói:
void begin(makeKeymap(userKeymap)) – a billentyűzet inicializálása
char waitForKey() – várok a billentyű lenyomására; amikor ez megtörténik, visszakapjuk a lenyomott billentyű karakterét.
char getKey() – nem blokkoló függvény – nem vár a billentyű lenyomására, de ha gombnyomás történik, visszaadja a lenyomott billentyű karakterét.
KeyState getState() – visszaadja az aktuális billentyűállapotot: IDLE, PRESSED, RELEASED, HOLD
boolean keyStateChanged() – true/false értéket ad vissza annak alapján, történt-e állapotváltozás
setHoldTime(unsigned int time) – gombnyomás időtartamának beállítása (ms), amelyet tényleges lenyomásként kell érzékelni
setDebounceTime(unsigned int time) – gombnyomás „pergésének” (bounce) szűrési ideje (ms)
addEventListener(keypadEvent) – függvény csak akkor használható, ha a használt mikrokontroller támogatja a megszakításokat.
Javasoljuk, hogy próbálja ki a következő példakódot: Examples → Keypad → Examples → EventSerialKeypad

Felhasznált források és további olvasnivaló

https://www.hackster.io/
https://www.circuitbasics.com/
https://www.teachmemicro.com/
https://playground.arduino.cc/

Vélemény, hozzászólás?

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük