Uporaba matrične tipkovnice

Matrična tipkovnica 3x4 ima 12 tipk, razporejenih v 3 stolpce in 4 vrstice. Taka tipkovnica potrebuje vsega 7 priključkov, 3 za stolpce in 4 za vrstice. Če pritisnemo npr. tipko 5, staknemo vodnika drugega stolpca in druge vrstice.

Slika 1: Matrična tipkovnica 3x4

Za uporabljeno matrično tipkovnico moramo najprej ugotoviti, kateri priključki predstavljajo posamezne vrstice in posamezne stolpce. To najlažje ugotovimo z ohmmetrom. Priključimo ga na posamezne priključke matrične tipkovnice ter pritiskamo na tipke, dokler ohmmeter ne reagira. Za našo matrično tipkovnico velja:

Priključek 1 predstavlja stolpec 1 (v tem stolpcu so tipke 1, 4, 7 in *).

Priključek 2 predstavlja stolpec 2 (v tem stolpcu so tipke 2, 5, 8 in 0).

Priključek 3 predstavlja stolpec 3 (v tem stolpcu so tipke 3, 6, 9 in #).

Priključek 4 predstavlja vrstico 1 (v tej vrstici so tipke 1, 2 in 3).

Priključek 5 predstavlja vrstico 2 (v tej vrstici so tipke 4, 5 in 6).

Priključek 6 predstavlja vrstico 3 (v tej vrstici so tipke 7, 8 in 9).

Priključek 7 predstavlja vrstico 4 (v tej vrstici so tipke *, 0 in #).

Slika 2: Priključki (pini) posameznih stolpcev in vrstic naše izbrane matrične tipkovnice

Potrebujemo še knjižnico Keypad za Arduino okolje, ki jo najdemo spodaj v prilogi.

Izdelajmo sedaj program za preizkus delovanja matrične tipkovnice. Na LCD displayu (v našem primeru LCD 20x4) se naj izpiše vrednost pritisnjene tipke. Hkrati še dodajmo LED diodo, ki se naj ob pritisku na tipko 5 vklopi, ob pritisku na tipko 6 pa izklopi.

/*

  * Preizkus delovanja matrične tipkovnice.

  * Avtor: Milan Ivič

  * december 2015

 */

 #include <Keypad.h>

 #include <LiquidCrystal.h>

 /*

 Pini za LCD display:

 RS: Pin A1

 EN: Pin A0

 D4: Pin 2

 D5: Pin 3

 D6: Pin 4

 D7: Pin 5

 */

 LiquidCrystal lcd(A1,A0,A2,3,4,5);     //Priključki LCD na pine Arduino.

 int LED = 2;

 //Deklariramo našo matrično tipkovnico:

 const byte VRSTICE = 4;             //štiri vrstice

 const byte STOLPCI = 3;             //trije stolpci

 char tipke[VRSTICE][STOLPCI] =

 {

   {'1','2','3'},     //Pin 4 na matrični tipkovnici je prva vrstica. (1,2,3)

   {'4','5','6'},     //Pin 5 na matrični tipkovnici je druga vrstica. (4,5,6)

   {'7','8','9'},     //Pin 6 na matrični tipkovnici je tretja vrstica. (7,8,9)

   {'*','0','#'}      //Pin 7 na matrični tipkovnici je četrta vrstica. (*,0,#)

 };                   //Pin 1 na matrični tipkovnici je prvi stolpec. (1,4,7,*)

                      //Pin 2 na matrični tipkovnici je drugi stolpec. (2,5,8,0)

                      //Pin 3 na matrični tipkovnici je tretji stolpec. (3,6,9,#)

                     

 byte vrstice_pini[VRSTICE] =

 {

   9, 8, 7, 6     //Priključimo pine vrstic matrične tipkovnice (pini 4, 5, 6, 7).

 };

 byte stolpci_pini[STOLPCI] =

 {

   12, 11, 10

 };                 //Priključimo pine stolpcev matrične tipkovnice (pini 1, 2, 3).

 int Stevec=0;

 Keypad keypad = Keypad( makeKeymap(tipke), vrstice_pini, stolpci_pini, VRSTICE, STOLPCI);

 void setup()

 {

   pinMode(LED, OUTPUT);

   lcd.begin(20,4);     //LCD 20x4 => štiri vrstice po 20 znakov.

 }

 void loop()

 {

   char Tipka = keypad.getKey();

   if (Tipka != NO_KEY)           //Blok if stavka se izvede, če pritisnemo na katero od tipk.

   {

     lcd.setCursor(0,0);          //Postavitev kurzorja na LCD displayu.

     lcd.print(Tipka);            //Na LCD se izpiše vrednost pritisnjene tipke.

     Stevec++;

     if (Stevec == 13)

     {

       lcd.clear();              //Po 13-tem pritisku na katero od tipk, se LCD pobriše.

       Stevec = 0;               //Inicializacija.

     }

   }

   if(Tipka == '5')                  //Ob pritisku na tipko 5 vklopimo LED diodo.

   {

     digitalWrite(LED, HIGH);

   }

   if(Tipka == '6')                  //Ob pritisku na tipko 6 izklopimo LED diodo.

   {

     digitalWrite(LED, LOW);

   }

 }

Priključitev matrične tipkovnice na Arduino Uno:

V glavni zanki void loop() z if stavkom (if Tipka != NO_KEY) neprestano preverjamo, ali je pritisnjena katera od tipk matrične tipkovnice. Če je, se izvede blok if stavka. Po vsakem pritisku na katero od tipk se spremenljivka Stevec poveča za 1 (Stevec++). Po trinajstem pritisku LDC display pobrišemo in spremenljivko Stevec inicializiramo na vrednost 0. V zunanjem if stavku imamo vgnezdena še dva if stavka. S prvim preverjamo ali je pritisnjena tipka 5, z drugim pa, ali je pritisnjena tipka 6 na matrični tipkovnici. Če je pogoj prvega vgnezdenega if stavka resničen, vklopimo LED diodo, priključeno na pin 2, če pa je resničen pogoj drugega vrinjenega if stavka, jo izklopimo.

Naslednji program vključuje geslo, ki ga je potrebno vpisati preko matrične tipkovnice, da se vklopi LED dioda. Najprej poglejmo program, nato pa ga bomo opisali:

/*

 * Matrična tipkovnica in geslo.

 * Avtor: Milan Ivič

 * Datum: dec. 2015

 */

 //Vključitev knjižnic:

 #include <Keypad.h>

 #include <LiquidCrystal.h>

 /*

 Pini za LCD display:

 RS: Pin A1

 EN: Pin A0

 D4: Pin 2

 D5: Pin 3

 D6: Pin 4

 D7: Pin 5

 */

 LiquidCrystal lcd(A1,A0,A2,3,4,5);         //Priključki LCD na pine Arduino.

 int LED = 2;

 //Deklariramo našo matrično tipkovnico:

 const byte VRSTICE = 4;                       //Štiri vrstice.

 const byte STOLPCI = 3;                       //Trije stolpci.

 char tipke[VRSTICE][STOLPCI] =

 {

   {'1','2','3'},      //Pin 4 na matrični tipkovnici je prva vrstica. (1,2,3)

   {'4','5','6'},      //Pin 5 na matrični tipkovnici je druga vrstica. (4,5,6)

   {'7','8','9'},      //Pin 6 na matrični tipkovnici je tretja vrstica. (7,8,9)

   {'*','0','#'}       //Pin 7 na matrični tipkovnici je četrta vrstica. (*,0,#)

 };                   //Pin 1 na matrični tipkovnici je prvi stolpec. (1,4,7,*)

                       //Pin 2 na matrični tipkovnici je drugi stolpec. (2,5,8,0)

                       //Pin 3 na matrični tipkovnici je tretji stolpec. (3,6,9,#)

                      

 byte vrstice_pini[VRSTICE] =

 {

   9, 8, 7, 6        //Priključimo pine vrstic matrične tipkovnice (pini 4, 5, 6, 7).

 };

 byte stolpci_pini[STOLPCI] =

 {

   12, 11, 10

 };                  //Priključimo pine stolpcev matrične tipkovnice (pini 1, 2, 3).

 Keypad keypad = Keypad( makeKeymap(tipke), vrstice_pini, stolpci_pini, VRSTICE, STOLPCI);

 //*************** Geslo ***********************

 char Geslo[5] =

 {'1','2','3','4','5'};            //Naše geslo predstavljajo zaporedni pritiski na tipke 1, 2, 3, 4 in 5 ter na koncu #.

 char Primerjava[5] =

 {'0','0','0','0','0'};            //Enodimenzionalno polje, kamor se bodo shranjevali pritiski na tipke tipkovnice.

 int z = 0;

 void setup()

 {

   pinMode(LED, OUTPUT);

   lcd.begin(20,4);                    //LCD 20x4 => štiri vrstice po 20 znakov.

   lcd.setCursor(0,0);               //Nastavitev kurzorja.

   lcd.print("Za odpiranje je");    //Izpis besedila.

   lcd.setCursor(0,1);               //Nastavitev kurzorja.

   lcd.print("potrebno geslo!");   //Izpis besedila.

   delay(2000);

   lcd.clear();

   lcd.setCursor(0,0);               //Nastavitev kurzorja.

   lcd.print("Vpisi geslo...");      //Izpis besedila.

 }

 void loop()

 {

   Beri_Tipkovnico();                //Iz glavne zanke kličemo funkcijo Beri_Tipkovnico.

 }

 void Beri_Tipkovnico()

 {

   char Tipka = keypad.getKey();  

   if (Tipka != NO_KEY)               //Blok if stavka se izvede, če pritisnemo na katerokoli tipko.

   {

     Primerjava[z] = Tipka;            //Pritiski na tipke se shranjujejo v polje Primerjava[z].

     z++;

     lcd.setCursor(15,0);

     lcd.print(Tipka);                  //Na LCD-ju se izpisujejo vrednosti pritisnjenih tipk.

     delay(100);

     switch(Tipka)

     {

       case '*':                        //S pritiskom na * postavimo z na 0 in lahko začnemo vpisovati geslo od začetka.

        z = 0;

        break;

       case '#':                        //S pritiskom na # postavimo z na 0 ter kličemo funkcijo za preverjanje gesla.

        z = 0;

        delay(100);                     //Zaradi odbijanja kontaktov tipk.

        lcd.clear();       

        Preverjanje_gesla();         //Kličemo funkcijo za preverjanje gesla.

        break;

     }    

   }  

 }

 void Preverjanje_gesla()          //Funkcija za preverjanje gesla.

 {

   int Pravilno_geslo = 0;         //Inicializacija lokalne spremenljivke.

   int i;

   for (i=0; i<6; i++)                 //For zanka se izvede 5-krat.

   {

     if (Primerjava[i] == Geslo[i])          //Preverjanje posameznih pritiskov na tipkovnici.

     {

       Pravilno_geslo++;                     //V Pravilno_geslo se shranjuje število pravilnih (ujemajočih) pritisnjenih tipk.

     }                                       //Če so vse pravilne, je vrednost spremenljivke Pravilno_geslo enako 4.

     lcd.setCursor(5,1);

     lcd.print(Primerjava[i]);               //Na LCD-ju se izpisujejo vrednosti pritisnjenih tipk.

     delay(1000);

     lcd.clear();

     lcd.setCursor(10,1);                    //Na LCD-ju se izpisuje število pravilnih pritiskov (od 0 naprej).

     lcd.print(Pravilno_geslo);

   }

   if (Pravilno_geslo == 4)        //Če je vpisano geslo pravilno, kličemo funkcijo Geslo_pravilno.

   {

     Geslo_pravilno();

   }

   else

   {

     Geslo_nepravilno();

   }

 }

 void Geslo_pravilno()

 {

   lcd.clear();

   lcd.setCursor(1,2);

   lcd.print("Geslo pravilno");

   digitalWrite(LED, HIGH);

   delay(2000);

   digitalWrite(LED,LOW);

   lcd.clear();

   lcd.setCursor(0,0);                  //Nastavitev kurzorja.

   lcd.print("Za odpiranje je");       //Izpis besedila.

   lcd.setCursor(0,1);                  //Nastavitev kurzorja.

   lcd.print("potrebno geslo!");      //Izpis besedila.

   delay(2000);

   lcd.clear();

   lcd.setCursor(0,0);                  //Nastavitev kurzorja.

   lcd.print("Vpisi geslo...");         //Izpis besedila.

 }

 void Geslo_nepravilno()

 {

   lcd.setCursor(1,2);

   lcd.print("Napacno geslo!");

   delay(1000);

   lcd.clear();

   lcd.setCursor(1,3);

   lcd.print("Poizkusi znova");

   delay(1000);

   lcd.clear();

   lcd.setCursor(0,0);

   lcd.print("Vpisi geslo...");  

   delay(1000);  

 }

V spremenljivko Geslo tipa char zapišemo geslo, ki ga želimo uporabiti. Za spremenljivko Geslo tipa char smo uporabili podatkovno strukturo polje (angl. array) char Geslo[5]. Polje je podatkovna struktura, ki vsebuje množico spremenljivk istega tipa, do katerih dostopamo preko indeksa. Indeks prvega elementa polja je 0. Mi smo uporabili eno-dimenzionalno polje s petimi elementi. Indeks prvega elementa je 0, indeks petega elementa pa je 4.

Za primerjavo vpisanega gesla z našim geslom smo deklarirali še drugo eno-dimenzionalno polje s petimi elementi z imenom Primerjava, tipa char in vsem petim elementom dodelili vrednost 0.

V funkciji void Beri_Tipkovnico() se vrednosti pritisnjenih tipk na matrični tipkovnici shranjujejo v eno-dimenzionalno polje z imenom Primerjava[z]. V tej funkciji smo uporabili stavek switch-case. Uporabimo ga zato, ker nas zanima vrednost pritisnjene tipke. Vrednosti pritisnjenih tipk se shranjujejo v Primerjava[z]. Če je vrednost *, postavimo z na 0 in lahko ponovno začnemo z vpisovanjem gesla. Ko pa pritisnemo na tipko #, pokličemo funkcijo za preverjanje vpisanega gesla Preverjanje_gesla().

V funkciji za preverjanje gesla smo uporabili zanko for. Zanka for ima tri dele: vstopni izraz, pogoj delovanja in izraz povečevanja. For zanka se izvaja tako dolgo, dokler je pogoj delovanja resničen.

Ob vsakem prehodu zanke for preverjamo pravilnost pritisnjene tipke (gesla) na matrični tipkovnici. To preverjamo z stavkom if (if Primerjava [i] == Geslo[i]). Če je pritisnjena tipka pravilna (če se ujema z geslom), se vrednost spremenljivke Pravilno_geslo poveča za 1. Če je vpisano geslo pravilno (če so pritisnjene tipke 1, 2, 3, 4 in 5), je vrednost spremenljivke Pravilno_geslo enako 4 (od 0 do 4). V funkciji Preverjanje_gesla() na LCD display izpisujemo vrednosti pritisnjenih tipk in vrednost spremenljivke Pravilno_geslo le zaradi prikaza delovanja programa. V praksi tega ne smemo prikazovati, saj bi nepooblaščeni hitro lahko ugotovil skrito geslo.