o.O wtFAQ – We Tinker, Fix and Question
◀ 2.6. LCD ekrani3. Arduino programiranje ▶

2.7. Tipkovnica
Unos podataka

Uvod u 4x4 tipkovnicu

tipkovnica
Standardna 4x4 tipkovnica ima 16 tipki raspoređenih u 4 reda i 4 stupca (1–9, 0, *, #, A–D). Svaka tipka zapravo je prekidač na spoju jednog reda i jednog stupca, pa tipkovnica ukupno ima samo osam vodova (R1–R4, C1–C4) umjesto 16 zasebnih žica. Arduino tipkovnicu skenira tako da redom postavlja stupce u logičku nulu ili jedinicu i zatim očitava koji je red promijenio stanje – iz kombinacije aktivnog reda i stupca određuje se koja je tipka pritisnuta. Ovakav način spajanja koristi se u kalkulatorima, daljinskim upravljačima, sigurnosnim tipkovnicama i mnogim drugim uređajima.

Shema spajanja tipkovnice je ovakva:

shema

Na primjer: kada pritisneš tipku 5, spojiti ćeš drugi red i drugi stupac; Arduino vidi da je pri skeniranju drugi stupac aktivan i da je u tom trenutku drugi red povučen na nulu, pa zna da je riječ baš o tipki 5.

Kratka povijest tipkovnica
tepelprinter

Prve tipkovnice u elektronici nastale su početkom 20. stoljeća na teleprinterima (teletypes) – elektromehaničkim strojevima koji su slali poruke preko telegrafskih linija, a imali su tipke vrlo slične onima na pisaćim strojevima. Ti uređaji, poput Teletype Model 33 iz 1960‑ih, služili su kao konzole prvih miniračunala: korisnik je tipkao naredbe na tipkovnici, a uređaj je odgovarao ispisom teksta na papir.

Kasnije su s pojavom video terminala tipkovnice postale odvojeni elektronički sklopovi povezani s ekranom, a današnje PC tipkovnice nasljeđuju raspored i ideju tih ranih strojeva. Zanimljivo je da i mnogi parametri serijske komunikacije (npr. "110 baud, 2 stop bita") potječu upravo iz zahtjeva mehaničkih teleprintera.

Biblioteka Keypad.h

Kako bi izbjegli pisanje velike količine koda za skeniranje tipki, iskoristiti ćemo postojeću biblioteku Keypad.h, koja služi da ti sakrije svu niskorazinsku logiku skeniranja matricne tipkovnice i da ti da jednostavno sučelje tipa getKey().
Biblioteku Keypad.h moramo prvo uključiti u Arduino IDE, kako bi je mogli koristiti.
Ova biblioteka:

  • Omogućuje da jednom zadaš raspored tipki (char keys[ROWS][COLS]) i pinove za redove/stupce, a biblioteka iz toga izgradi internu strukturu tipkovnice (Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);).
  • Automatski obavlja skeniranje redova i stupaca, provjerava koje su tipke pritisnute i od toga vraća već preveden znak (npr. ‘5’, ‘#’, ‘A’) umjesto da ti ručno čitaš stanja pinova.
  • Ugrađeno rješava debouncing i praćenje stanja tipke (PRESSED, HOLD, RELEASED, IDLE), pa ne moraš sam raditi vremenska mjerenja; po potrebi se mogu podešavati vremena i koristiti event handleri (addEventListener).
  • Podržava i naprednije stvari kao više istovremenih tipki i više tipkovnica, ali se u tipičnim Arduino projektima najčešće koristi samo getKey() ili getKeys() za jednostavno očitavanje pritisnute tipke.
    U praksi: umjesto da pišeš desetke linija koda za skeniranje, s Keypad.h se cijeli posao svodi na inicijalizaciju mape tipki u setup() i poziv char key = keypad.getKey(); u loop() te provjeru je li key != NO_KEY prije obrade pritiska.

Vježbe

Spoji komponente prema ovoj shemi:

spajanje

Vježba 1 – Prvi dodir s tipkama: očitavanje i ispis na Serial monitor

Spojio si 4x4 tipkovnicu na Arduino tako da si redove i stupce povezao na osam digitalnih pinova. Program će u petlji neprestano skenirati tipkovnicu i svaki put kad se prepozna pritisak tipke, njezin će se simbol (1, 2, 3, A, *, # …) ispisati na Serial monitoru, što jasno pokazuje vezu između fizičkog pritiska i digitalnog signala.
Matrica hexaKeys (definirana u kôdu) će, prilikom deklaracije varijable customKeypad, definirati vezu između spojeva redova i kolona tipkovnice sa znakovima koje želimo prikazati.

// C++
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  char customKey = customKeypad.getKey();
  
  if (customKey){
    Serial.println(customKey);
  }
}

Dodatna pitanja i zadaci:

  • Zašto tipkovnica ima samo 8 žica, iako ima 16 tipki? Kako bi izgledalo spajanje da nema matrice povezivanja?
  • Što bi se dogodilo kada bismo redove postavili kao izlaze, a stupce kao ulaze (zamjena uloga)? Bi li program i dalje radio, uz prilagodbu koda?
  • Što znači debouncing tipke i koje probleme bismo vidjeli na Serial monitoru?
  • Kako su znakovi matrice hexaKeys pohranjeni u Arduino programu (i općenito u računalima)?
Što je to ASCII?
tepelprinter
ASCII (American Standard Code for Information Interchange) je najvažniji rani standard za kodiranje znakova; definira 128 znakova (slova, brojke, interpunkciju, kontrolne znakove) koji se kodiraju pomoću 7 bita. Nastao je početkom 1960‑ih kako bi ujedinio dotadašnje nespojive telegrafske kodove i omogućio da različita računala, terminali i komunikacijski uređaji razmjenjuju tekst na kompatibilan način. ASCII je temelj za kasnije proširene skupove znakova (ISO 8859, Unicode), pa i današnji internet još uvijek u svojoj osnovi razumije te izvorne ASCII kodove.

Vježba 2 – Mala heksadecimalna konzola: unos preko tipkovnice i ispis na LCD

U ovoj vježbi nadograđujemo postojeći kôd i spajamo 4x4 tipkovnicu i LCD 1604, tako da se na LCD‑u prikazuju vrijednosti tipki (0–9, A–D), dok posebne tipke imaju posebnu funkciju:

  • tipke 0–9 i A–D dodaju nove heksadecimalne znamenke,
  • tipka ‘*’ briše ekran i omogućuje unos nove vrijednosti,
  • tipka ‘#’ potvrđuje unesenu vrijednost i na ekranu kratko ispisuje poruku “OK”.

Na ovaj način ćeš stvoriti malo korisničko sučelje (user interface), sličan onome na stvarnim uređajima poput šifratora, digitalnih brava ili mjernih instrumenata.

Kako bi sačuvao podatak koji unosiš preko tipkovnice, koristiti ćemo klasu String, kojoj ćemo dodavati znak pročitan sa tipkovnice.

// C++
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

// Postavi adresu na 0x27 za LCD 1602
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

String data = String();

void setup()
{
  Serial.begin(9600);
  
  lcd.begin();
  lcd.setCursor(0, 0);
  lcd.backlight();
}

void loop()
{
  char customKey = customKeypad.getKey();
  
  if (customKey){
    Serial.println(customKey);
    if(customKey == '*')
    {
      data = "";
      lcd.clear();
    }
    else if (customKey == '#')
    {
      Serial.print("OK: ");
      Serial.println(data.c_str());
      data = "";
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("OK");
      delay(500);
      lcd.clear();
    }
    else
    {
      data += customKey;
    }
    lcd.setCursor(0,0);
    lcd.print(data.c_str());
  }
}

Dodatna pitanja i zadaci:

  • Napravi provjera raspona i prikaz greške:
    • Nakon pritiska # pretvori uneseni broj u decimalni.
    • Ako broj nije u zadanom rasponu (npr. 0–100), na LCD‑u ispisati poruku Greska! i obriši unos nakon kratkog vremena.
    • Ako je u rasponu, osim OK ispiši i decimalnu vrijednost u drugom retku.
  • Kako bi isprogramirao unos i provjeru lozinke, ali na takav način da sam prokramski kôd ne zna koja je to lozinka?

ligtbulb Što smo naučili?

  • Upoznao si princip rada matričnih tipkovnica te razumio zašto su tako raširene u elektronici – omogućuju puno tipki uz malo vodova i jednostavno skeniranje pomoću mikrokontrolera.
  • Cijeli put od fizičkog pritiska tipke, preko digitalnog očitavanja i ASCII kodiranja, do prikaza na LCD‑u i osmišljavanja jednostavnog korisničkog sučelja.
  • Upotrebu Arduino biblioteke za tipkovnicu, serijsku komunikaciju i LCD zaslon.
  • Potrebno znanje kako svoje projekte obogatiti praktičnim i intuitivnim unosom podataka.
◀ 2.6. LCD ekrani3. Arduino programiranje ▶