Mnogo prekidača na malo pinova
Matrica prekidača na Arduinu: membranska tipkovnica 4 × 4 s vlastitim skeniranjem, nizovi i ugniježđene petlje, lažne tipke i diode koje ih uklanjaju

Na stolu našeg flipera bit će 15 senzora: mete, staze i rupa za kuglicu. Uz njih je i tipka Start, pa glavni Arduino mora čitati 16 prekidača. Arduino Uno ima 18 pinova koje možemo slobodno koristiti, a glavnom Arduinu trebaju i za tilt, za vezu s ostalim Unima i za druge poslove. Kada bi svaki prekidač imao svoj pin, pinova ne bi bilo dovoljno.
Zato prekidače slažemo u matricu: u redke i stupce, kao polja u tablici. Za 16 prekidača tada je dovoljno 8 pinova. Danas ćemo napisati program koji čita takvu matricu, upoznat ćemo njezinu najveću zamku, lažne tipke, i popraviti je diodama.
Što to znači za fliper?

Na tlocrtu našeg flipera plavim su krugom označene tri mete na lijevom zidu, a u velikom krugu iste su mete uvećane. Iza svake mete je mikroprekidač, a ispred nje lampica. Što znače ostali dijelovi crteža, piše na stranici o fliperu.
- Glavni Arduino flipera čita 15 senzora i tipku Start kroz matricu 4 × 4, preko 8 pinova. Uz svaki prekidač bit će zalemljena dioda, kao u Vježbi 4, jer kuglica i igrač mogu istodobno pritisnuti više prekidača.
- Cijelu matricu program skenira za manje od pola milisekunde. Udarac kuglice u mikroprekidač traje nekoliko milisekundi, pa ga program sigurno vidi. Izmjerit ćemo ga u sljedećoj lekciji. Zato ni ovdje
loop()ne smije čekati. - Svaki prekidač u matrici ima svoje smirivanje koje reagira na prvi dodir, kao danas.
- Matricu čitamo svojim kodom iz Vježbe 1, a ne bibliotekom Keypad iz Vježbe 3. Zašto, piše na kraju te vježbe.
- Tilt i tipke palica nisu u matrici. Tilt ima svoj pin, a tipke palica spojene su na Arduino koji upravlja palicama, jer palica mora krenuti istog trenutka.
Kako radi matrica
Membranska tipkovnica 4 × 4 ima 16 tipki, a samo 8 nožica. Unutra su četiri vodiča u redcima (R1 do R4) i četiri u stupcima (C1 do C4). Svaka tipka stoji ondje gdje se jedan redak križa s jednim stupcem. Kada je pritisneš, spoji taj redak s tim stupcem.

Arduino tipkovnicu čita redak po redak:
- Jedan redak spoji s GND: pin tog retka je izlaz i šalje
LOW. Ostali redci su isključeni. - Pročita sva četiri stupca. Stupci imaju pull-up otpornik, kao tipkalo, pa čitaju
HIGH. Stupac koji čitaLOWspojen je s uključenim retkom preko pritisnute tipke. - Isključi taj redak i prijeđe na sljedeći.

Na slici je jedna tipka izbliza. Sivo je nacrtano ono što je unutar Arduina (isprekidani okvir): ugrađeni pull-up otpornik od 20 do 50 kΩ spaja pin stupca C1 s 5 V. Dok je tipka 1 otpuštena, kroz otpornik ne teče struja i stupac čita HIGH. Kada je pritisneš dok je redak R1 na LOW, tipka spoji stupac s retkom, pa stupac čita LOW.
Redak i stupac zajedno kažu koja je tipka pritisnuta: LOW na stupcu C2 dok je uključen redak R1 znači tipku 2. Ovako pročitati cijelu tipkovnicu zove se skeniranje. Arduino je skenira za manje od pola milisekunde, pa to ponavlja tisuće puta u sekundi.
| Prekidača | Svaki na svom pinu | U matrici |
|---|---|---|
| 16 | 16 pinova | 4 redka + 4 stupca = 8 pinova |
| 64 | 64 pina | 8 redaka + 8 stupaca = 16 pinova |
Isključeni redak nije HIGH
Redak koji ne skeniramo program ne postavlja na HIGH, nego ga pretvori u ulaz (INPUT). Tada nije spojen ni s čim i kroz njega ne može teći struja.
Kada bi isključeni redak bio HIGH, dvije pritisnute tipke u istom stupcu spojile bi redak koji šalje HIGH s retkom koji šalje LOW. Bio bi to kratki spoj između dva pina, a on može oštetiti Arduino.
Materijal
Svaki polaznik dobiva:
- Arduino Uno i USB kabel
- membransku tipkovnicu 4 × 4 i 8 spojnih žica s iglicama na oba kraja
- veliki breadboard, četiri mala tipkala, četiri diode i spojne žice
Za pokaznu vježbu na kraju Vježbe 1 voditelj treba osciloskop s dva kanala i dvije sonde, mali breadboard i nekoliko spojnih žica.
Spoj iz prošle lekcije više nam ne treba: rastavi ga, a dijelove vrati u kutiju.
Pravila za spajanje
- Dok spajamo, Arduino je odspojen s USB kabela.
- Prvo učitaj program, a tek onda spoji tipkovnicu. Na Arduinu je možda još neki stari program u kojem su pinovi tipkovnice izlazi, na primjer program semafora. Kada bi takav program radio dok pritišćeš tipke, mogao bi spojiti dva izlaza. Program iz Vježbe 1 zato učitaj dok na Arduino još ništa nije spojeno.
- Prije uključivanja voditelj pregleda spoj.
Vježba 1: Skeniramo tipkovnicu
Program
Ovaj program čita tipkovnicu i u Serial Monitoru ispisuje znak svake tipke koju pritisneš. Isti program koristit ćemo i u Vježbama 2 i 4.
// C++
const unsigned long SMIRIVANJE = 50; // nakon promjene 50 ms ne gledamo tu tipku
const char NO_KEY = 0; // getKey() to vrati kada nijedna tipka nije upravo pritisnuta
const int redci[4] = {12, 11, 10, 9}; // nožice 1 do 4 tipkovnice: redci R1 do R4
const int stupci[4] = {8, 7, 6, 5}; // nožice 5 do 8 tipkovnice: stupci C1 do C4
// Znak svake tipke: prvi broj je redak, drugi stupac.
const char znakovi[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
bool bilaPritisnuta[4][4]; // kakva je svaka tipka bila zadnji put (na početku nijedna)
unsigned long zadnjaPromjena[4][4]; // kada se svaka tipka zadnji put promijenila
// Skenira tipkovnicu i vrati znak tipke koja je upravo pritisnuta, ili NO_KEY.
char getKey() {
for (int r = 0; r < 4; r++) { // redom svaki redak
pinMode(redci[r], OUTPUT); // uključi redak: izlaz...
digitalWrite(redci[r], LOW); // ...spojen s GND
delayMicroseconds(10); // pričekaj da se napon na stupcima ustali
for (int s = 0; s < 4; s++) { // redom svaki stupac
bool pritisnuta = digitalRead(stupci[s]) == LOW;
if (pritisnuta != bilaPritisnuta[r][s] && millis() - zadnjaPromjena[r][s] >= SMIRIVANJE) {
bilaPritisnuta[r][s] = pritisnuta;
zadnjaPromjena[r][s] = millis();
if (pritisnuta) { // tipka je upravo pritisnuta
pinMode(redci[r], INPUT); // isključi redak prije povratka
return znakovi[r][s]; // vrati znak i izađi iz funkcije
}
}
}
pinMode(redci[r], INPUT); // isključi redak prije sljedećeg
}
return NO_KEY; // nijedna tipka nije upravo pritisnuta
}
void setup() {
for (int r = 0; r < 4; r++) {
pinMode(redci[r], INPUT); // redak je isključen
}
for (int s = 0; s < 4; s++) {
pinMode(stupci[s], INPUT_PULLUP); // stupac čitamo, kao tipkalo
}
Serial.begin(9600);
}
void loop() {
char tipka = getKey(); // znak upravo pritisnute tipke ili NO_KEY
if (tipka != NO_KEY) {
Serial.println(tipka);
}
}
Učitaj program dok na Arduino još ništa nije spojeno.
Što je novo u programu?
const int redci[4] = {12, 11, 10, 9};– Niz: jedna varijabla s više vrijednosti, ovdje četiri broja pinova. Do svake vrijednosti dolazimo po rednom broju u uglatim zagradama, a brojimo od nule:redci[0]je 12, aredci[3]je 9.const char znakovi[4][4]– Dvodimenzionalni niz: tablica s četiri retka i četiri stupca.znakovi[1][2]je znak u retku 1 i stupcu 2, dakle'6', jer i ovdje brojimo od nule. Tipcharsprema jedan znak, napisan u jednostrukim navodnicima:'6','#'.bool bilaPritisnuta[4][4];iunsigned long zadnjaPromjena[4][4];– Svaka od 16 tipki pamti svoje stanje i vrijeme zadnje promjene, kao jedno tipkalo u lekciji o tipkalima. Nizovi napisani iznadsetup()na početku su puni nula, pa nijedna tipka nije pritisnuta.char getKey()– Vlastita funkcija koja vraća vrijednost, kaoprocitajBrojKoraka()u lekciji 2.1.charispred imena kaže da funkcija vraća jedan znak. U funkciju smo premjestili cijelo skeniranje, pa jeloop()kratak. Dali smo joj englesko ime getKey (dohvati tipku), jer se tako zove i funkcija biblioteke iz Vježbe 3. Zatoloop()u obje vježbe izgleda gotovo jednako.const char NO_KEY = 0;– Znak koji ne znači nijednu tipku.getKey()ga vrati kada nijedna tipka nije upravo pritisnuta, aloop()tada ništa ne ispiše.for (int r = 0; r < 4; r++)i unutar njegafor (int s = 0; s < 4; s++)– Petlja u petlji. Za svaki od četiri redka unutarnja petlja prođe kroz sva četiri stupca, pa se pri skeniranju cijele tipkovnice tijelo unutarnje petlje izvede 16 puta, jednom za svaku tipku.return znakovi[r][s];–returnvrati znak i odmah izađe iz funkcije, iako su obje petlje još usred posla. Zato redak prije toga isključimo. Inače bi ostao uključen, pa bi program njegove tipke vidio i dok skenira druge redke.- Ako se u istom skeniranju pojave dvije nove tipke,
getKey()vrati prvu. Stanje druge još nije zapamćeno, pa je funkcija u sljedećem prolazu krozloop()opet vidi kao novu i vrati je tada. Tako program ne propusti nijednu tipku. pinMode(redci[r], OUTPUT);…pinMode(redci[r], INPUT);– Pin retka mijenjamo između izlaza i ulaza dok program radi, a ne samo usetup(). Kao izlaz sLOWredak je uključen, a kao ulaz isključen.delayMicroseconds(10);– Čeka 10 mikrosekundi, stotinku milisekunde, da se napon na stupcima ustali nakon uključivanja retka. Program zbog toga ne postaje primjetno sporiji.- Smirivanje svake tipke isto je kao u Vježbi 3 lekcije o tipkalima: prva promjena odmah vrijedi, a zatim 50 ms ne gledamo tu tipku.
Spajanje
Nožice tipkovnice gledamo s prednje strane, s tipkama okrenutim prema nama: nožice 1 do 4 su redci, a nožice 5 do 8 stupci. Spoji ih redom na pinove D12 do D5. U konektor tipkovnice utakni jedan kraj spojne žice, a drugi kraj izravno u pin Arduina. Breadboard nam za sada ne treba.
| Nožica tipkovnice | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| Vodič | R1 | R2 | R3 | R4 | C1 | C2 | C3 | C4 |
| Arduino pin | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 |

Većina membranskih tipkovnica 4 × 4 ima ovakav raspored nožica. Ako tvoja ima drukčiji, program će ispisivati krive znakove. Kako to popraviti, piše u odjeljku Ako nešto ne radi.
Spoji USB kabel, otvori Serial Monitor (9600 baud) i pritisni redom sve tipke. Ispisuje li program za svaku tipku njezin znak?
Pokazna vježba: osciloskop na stupcima
Ovu pokaznu vježbu radi voditelj, a svi gledaju. Osciloskop crta kako se napon na pinu mijenja kroz vrijeme. Za razliku od multimetra, vidi i promjene koje traju samo nekoliko mikrosekundi, pa njime možemo gledati skeniranje dok se događa. Naš osciloskop ima dva kanala, CH1 i CH2, pa istodobno crta dva pina: stupce C1 i C2. Dijelovi našeg osciloskopa i osnovne upute za rad opisani su na stranici Osciloskop.
Štipaljka za masu ide samo na GND
Svaka sonda ima vrh i malu krokodil štipaljku za masu. Mase obiju sondi u osciloskopu su međusobno spojene. Kada bi jedna štipaljka bila na GND, a druga na nekom drugom pinu, osciloskop bi taj pin spojio s GND. Bio bi to kratki spoj. Zato obje štipaljke idu na GND, a na pinove idu samo vrhovi sondi.
Priprema:
- Odspoji USB kabel. Žice stupaca C1 i C2 voditelj ne utakne izravno u Arduino, nego preko breadboarda: žica s tipkovnice ide u svoj redak breadboarda, a iz istog retka druga žica u pin D8 (odnosno D7). U svaki od ta dva retka utakne još jednu kratku žicu, na čiji slobodni kraj zakvači vrh sonde. Još jednom žicom spoji GND Arduina s trećim retkom breadboarda, za mase.
- Vrh sonde kanala CH1 zakvači na stupac C1, a vrh sonde kanala CH2 na stupac C2. Obje štipaljke za masu zakvači na redak s GND.
- Prekidač na sondi (1X ili 10X) i postavka sonde u izborniku osciloskopa moraju biti isti, za oba kanala. Obično je to 10X.
- Oba kanala postavi na 2 V po podjeljku. CH1 pomakni u gornju polovicu zaslona, a CH2 u donju, da se krivulje ne preklapaju.
- Vremensku bazu postavi na 50 µs po podjeljku.
- Okidanje (engleski trigger) kaže osciloskopu kada da počne crtati. Postavi izvor CH1, padajući brid i razinu oko 2,5 V: osciloskop crta od trenutka kada napon na CH1 padne ispod 2,5 V. Tipkom MODE odaberi način Auto, u kojem osciloskop crta i kada okidanja nema.
- Spoji USB kabel.
Izvođenje:
- Nijedna tipka nije pritisnuta. Obje krivulje su ravne crte na 5 V.
- Polaznik drži tipku 1. Voditelj tipkom MODE odabere način Normal: osciloskop sada crta samo kada CH1 padne ispod 2,5 V, pa slika stoji mirno. Na CH1 vide se kratki padovi na 0 V, jedan za drugim. Razmak između dva pada je jedno skeniranje cijele tipkovnice. Je li kraći od pola milisekunde, odnosno od 10 podjeljaka?
- Polaznik drži tipke 1 i 2. Padovi na CH1 i CH2 su istodobni.
- Polaznik drži tipke 1 i 5. Pad na CH2 počinje otprilike kada pad na CH1 završi.
- Hvatamo pritisak. Polaznik pusti sve tipke, a voditelj tipkom MODE odabere način Single. Osciloskop čeka. Kada polaznik pritisne tipku 1, osciloskop nacrta trenutak pritiska i zaustavi se. Ako kontakti pri pritisku poskakuju, neki od prvih padova nedostaju ili su kraći od ostalih.
Kanal osciloskopa kaže stupac, a vrijeme pada kaže redak. Na isti način i program zna koja je tipka pritisnuta.
Koji znak je znakovi[2][1]?
'8'. Brojimo od nule, pa je [2] treći redak ('7', '8', '9', 'C'), a [1] drugi stupac u njemu.Zašto su na osciloskopu oba stupca na 5 V dok nijedna tipka nije pritisnuta?
INPUT_PULLUP), a on ih drži na 5 V. Uključeni redak na LOW mogao bi stupac povući na 0 V samo preko pritisnute tipke.Tipku 1 držiš cijelo vrijeme. Zašto je stupac C1 na 0 V samo u kratkim padovima?
LOW samo dok ga program skenira. Ostatak vremena R1 je isključen (INPUT), pa pull-up drži C1 na 5 V. Svaki pad je trenutak u kojem program uključi redak R1, jednom u svakom skeniranju.Zašto su padovi tipki 1 i 2 istodobni, a pad tipke 5 dolazi odmah iza pada tipke 1?
Kako s osciloskopa pročitaš koliko traje jedno skeniranje tipkovnice?
Što bi na stupcu C1 pokazao multimetar dok držiš tipku 1?
Vježba 2: Lažne tipke
Program i spoj ostaju isti. Pritisni tipku 1 i drži je. Zatim pritisni i drži tipku 2, pa dok držiš obje, pritisni još i tipku 4. Što ispisuje program?
Osim 1, 2 i 4 program ispiše i 5, iako tipku 5 nitko nije dirao. To je lažna tipka (engleski ghost key).

Pogledaj lijevu stranu crteža. Program je uključio redak R2 i čita stupac C2. Tipka 5 nije pritisnuta, ali struja je pronašla zaobilazni put (crveno): iz stupca C2 kroz tipku 2 u redak R1, zatim kroz tipku 1 u stupac C1 i kroz tipku 4 u redak R2. Stupac C2 zato čita LOW i program misli da je pritisnuta tipka 5.
Desna strana crteža pokazuje kako se to popravlja: uz svaku tipku je dioda, koja struju propušta samo u jednom smjeru, od stupca prema retku. Struja iz stupca C2 i dalje stigne kroz tipku 2 u redak R1, ali zaobilazni put morao bi kroz tipku 1 proći unatrag, od retka R1 prema stupcu C1. Dioda tipke 1 to ne dopušta (zelena kvačica), pa stupac C2 ostaje na 5 V i lažne tipke nema. Diode ćemo dodati u Vježbi 4.
Lažna tipka pojavi se kada su pritisnute tri tipke u tri kuta pravokutnika u matrici. Četvrti kut je tada lažna tipka.
Držiš tipke 5, 6 i 8. Koja će se lažna tipka pojaviti?
Lažne tipke na računalu
I tipkovnica računala je matrica. Jeftine tipkovnice nemaju diode, pa neke kombinacije triju ili više tipki ne rade dobro: računalo ili vidi tipku koju nisi pritisnuo, ili ne vidi tipku koju jesi. Tipkovnice za igrice zato često imaju diodu uz svaku tipku, pa računalo ispravno vidi bilo koju kombinaciju tipki.
Vježba 3: Tipkovnica s bibliotekom Keypad (neobavezna)
Ovu vježbu radi ako ti ostane vremena. Tipkovnice su toliko česte da za njih postoji gotova biblioteka, kao Bounce2 za tipkalo u lekciji o tipkalima. Zove se Keypad. Napisat ćemo program koji radi isto što i program iz Vježbe 1, ali skeniranje i smirivanje prepustit ćemo biblioteci. Zatim ćemo vidjeti što biblioteka radi s lažnim tipkama.
Spoj ostaje isti, pa tipkovnicu ne moraš odspajati. I biblioteka u svakom trenutku ima samo jedan pin kao izlaz, pa ne može spojiti dva izlaza.
Instaliranje biblioteke
- U Arduino IDE-u otvori Library Manager: ikona s knjigama na lijevoj strani ili izbornik Sketch ⇒ Include Library ⇒ Manage Libraries…
- U tražilicu upiši Keypad.
- Instaliraj biblioteku koja se zove samo Keypad, autora Mark Stanley i Alexander Brevig. Tražilica pokaže i mnogo drugih biblioteka s riječju Keypad u imenu, ali njih ne trebamo.
Za instaliranje treba internet. Ako ga u radionici nema, voditelj biblioteku unaprijed instalira na svako računalo.
Drugi dio plana isti je kao u Vježbi 1, samo pitamo biblioteku umjesto naše funkcije. Prvi dio plana, funkciju getKey, sada ima biblioteka.
Program s bibliotekom
// C++
#include <Keypad.h> // biblioteka za tipkovnice
byte redci[4] = {12, 11, 10, 9}; // isti pinovi kao u Vježbi 1
byte stupci[4] = {8, 7, 6, 5};
char znakovi[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad tipkovnica(makeKeymap(znakovi), redci, stupci, 4, 4);
void setup() {
Serial.begin(9600);
}
void loop() {
char tipka = tipkovnica.getKey(); // znak upravo pritisnute tipke ili NO_KEY
if (tipka != NO_KEY) {
Serial.println(tipka);
}
}
Učitaj program, otvori Serial Monitor i pritisni redom sve tipke. Program mora ispisivati iste znakove kao program iz Vježbe 1.
Što je novo u programu?
#include <Keypad.h>– Uključuje biblioteku u program. Ako biblioteka nije instalirana, prevođenje javi greškuKeypad.h: No such file or directory.byte redci[4] = {12, 11, 10, 9};– Tipbytesprema cijeli broj od 0 do 255, a to je dovoljno za broj pina. Biblioteka traži pinove baš u nizu tipabyte, i to bezconst, pa ovdje ne možemo napisaticonst intkao u Vježbi 1.Keypad tipkovnica(makeKeymap(znakovi), redci, stupci, 4, 4);–tipkovnicaje objekt, kaostartu lekciji o tipkalima. Biblioteci kažemo znakove tipki, pinove redaka, pinove stupaca te koliko je redaka i stupaca.makeKeymap()pretvara našu tablicu znakova u oblik koji biblioteka traži.setup()ima samoSerial.begin(9600);– Pinove postavlja biblioteka, papinMode()ne pišemo.char tipka = tipkovnica.getKey();– FunkcijagetKey()biblioteke radi isto što i naša iz Vježbe 1: skenira tipkovnicu i vrati znak tipke koja je upravo pritisnuta, a ako takve tipke nema, vratiNO_KEY. Ispred nje pišemotipkovnica., jer je to funkcija objekta. Osim toga,loop()je isti kao u Vježbi 1.- Nema naše funkcije
getKey(), konstanteNO_KEYni nizovabilaPritisnutaizadnjaPromjena. Sve to ima biblioteka.
Prednosti biblioteke:
- Program je mnogo kraći i lakše se čita. Od Vježbe 1 ostali su samo pinovi, tablica znakova i
loop(). - Smirivanje je već ugrađeno, pa ga ne moramo pisati.
- Biblioteka zna više od pritiska: za svaku tipku zna je li upravo pritisnuta, drži li je netko dulje od pola sekunde ili je upravo otpuštena. To dobro dođe za bravu sa šifrom ili izbornik.
- Tipkovnica druge veličine, na primjer telefonska 4 × 3, traži samo druge brojeve i drugu tablicu znakova.
- Biblioteku koriste mnogi ljudi, pa su njezine greške većinom već pronađene i popravljene. U izborniku File ⇒ Examples ⇒ Keypad ima gotove primjere.
Mane su iste kao kod biblioteke Bounce2: treba je instalirati na svako računalo, ne vidimo kako radi i zauzima više memorije. Ovaj program je oko 830 bajtova veći od programa iz Vježbe 1.
Lažne tipke s bibliotekom
Ponovi pokus iz Vježbe 2: pritisni i drži tipku 1, zatim tipku 2, pa dok držiš obje, pritisni još i tipku 4. Što sada ispisuje program?
Program ispiše samo 1. Lažne tipke 5 nema, ali nema ni tipki 2 i 4, koje si stvarno pritisnuo/la.
Biblioteka lažne tipke ne uklanja. I ona skenira tipkovnicu bez dioda, pa i ona za tipku 5 pročita LOW, kao naš program u Vježbi 2. Iz napona na pinovima ne može se znati je li tipka 5 stvarno pritisnuta ili je struja našla zaobilazni put. To ne može nijedan program.
Lažnu tipku ne vidimo zbog načina na koji radi getKey() biblioteke. Biblioteka pritisnute tipke pamti u popisu, a getKey() javlja samo novu tipku na prvom mjestu popisa. Dok držiš tipku 1, ona je prva, pa getKey() ne javi ni 2, ni 4, ni lažnu 5. Funkcija getKeys() iz iste biblioteke javlja sve pritisnute tipke, pa bi uz 1, 2 i 4 javila i lažnu tipku 5.
Program bi mogao najviše primijetiti da su pritisnute tri tipke u kutovima pravokutnika i ne vjerovati četvrtoj, kao neke jeftine tipkovnice računala, koje tada radije ne vide jednu tipku. Biblioteka Keypad ni to ne radi. Lažne tipke stvarno uklanjaju tek diode, a njih ćemo dodati u Vježbi 4.
Je li biblioteka Keypad uklonila lažnu tipku?
LOW. Lažnu tipku ne ispiše samo zato što getKey() dok držiš tipku 1 ne javlja nijednu drugu tipku, pa ne javi ni prave tipke 2 i 4. S funkcijom getKeys() lažna tipka 5 bi se pojavila.Zašto je u fliperu ne koristimo
Za tipkovnicu koju pritišće čovjek biblioteka Keypad dobar je izbor. Glavni Arduino flipera ipak će matricu čitati našim kodom iz Vježbe 1, jer biblioteka radi tri stvari koje fliperu smetaju:
- Skenira tipkovnicu najviše jednom u 10 ms. Ako od zadnjeg skeniranja nije prošlo 10 ms,
getKey()odmah vratiNO_KEY, a da tipkovnicu nije ni pogledao. Tako biblioteka smiruje tipke. Prst tipku drži mnogo dulje, pa to ne smeta. Udarac kuglice u mikroprekidač traje samo nekoliko milisekundi i može cijeli proći između dva skeniranja. Program ga tada uopće ne vidi. Naš program skenira cijelu matricu u svakom prolazu krozloop(). getKey()biblioteke javlja samo jednu tipku. Dok držiš tipku 1, bibliotečnagetKey()ne javi druge tipke, kao što si vidio/la u pokusu s lažnim tipkama. NašagetKey()iz Vježbe 1 javi ih. U fliperu kuglica i igrač često istodobno pritisnu više prekidača. Biblioteka ima i funkcijugetKeys()za više tipki, ali s njom program više nije kratak.- Skenira obrnutim smjerom. Naš program uključuje redke i čita stupce, pa struja kroz pritisnutu tipku teče od stupca prema retku. Biblioteka uključuje stupce (
LOW) i čita redke (pull-up), pa struja teče od retka prema stupcu. U Vježbi 4 dodat ćemo diode koje struju propuštaju samo od stupca prema retku. S njima biblioteka ne bi vidjela nijednu tipku dok joj u programu ne zamijenimo redke i stupce.
Zašto biblioteka Keypad u fliperu može propustiti udarac kuglice?
Vježba 4: Diode protiv lažnih tipki
Dioda je jednosmjerni ventil za struju: propušta je samo u jednom smjeru, od anode prema katodi. Jednu diodu već dobro poznaješ: LED-ica je dioda koja pritom svijetli. Na običnoj diodi katoda je označena prugom.
U našoj matrici struja kroz pritisnutu tipku teče od stupca, koji pull-up otpornik drži na 5 V, prema uključenom retku na LOW. Zato uz svaku tipku stavimo diodu: anoda je prema tipki, a katoda prema retku. Kroz pritisnutu tipku struja tada teče kao i prije. Ali zaobilazni put mora kroz tipku 1 proći unatrag, od retka prema stupcu, a to dioda ne dopušta. Pogledaj desnu stranu crteža iz Vježbe 2, koji je ponovljen ovdje:

Tipkovnici ne možemo dodati diode, pa ćemo na breadboardu složiti malu matricu 2 × 2, s četiri tipkala i četiri diode.
Spajanje
Program je onaj iz Vježbe 1. Ako si radio/la Vježbu 3, prvo ponovo učitaj program iz Vježbe 1, jer biblioteka skenira obrnutim smjerom i s ovim diodama ne bi vidjela nijednu tipku. Zatim odspoji USB kabel i izvuci žice iz tipkovnice. Naša mala matrica spojena je na prva dva retka i prva dva stupca, pa su njezina tipkala za program tipke 1, 2, 4 i 5. Ostali pinovi ostaju nespojeni i program na njima ne vidi nijednu tipku.
| Dio | Arduino pin | Na breadboardu |
|---|---|---|
| Tipkalo 1 | – | preko središnjeg utora, u e3, e5, f3, f5 |
| Tipkalo 2 | – | preko središnjeg utora, u e9, e11, f9, f11 |
| Tipkalo 4 | – | preko središnjeg utora, u e15, e17, f15, f17 |
| Tipkalo 5 | – | preko središnjeg utora, u e21, e23, f21, f23 |
| Diode | – | h5–h8, h11–h14, h17–h20 i h23–h26; pruga (katoda) prema dolje, u retke 8, 14, 20 i 26 |
| Stupac C1 | D8 | žica s D8 u a3, žica od b3 do b15 |
| Stupac C2 | D7 | žica s D7 u a9, žica od c9 do c21 |
| Redak R1 | D12 | žica s D12 u f8, žica od i8 do i14 |
| Redak R2 | D11 | žica s D11 u f20, žica od i20 do i26 |


- Svako tipkalo spaja svoja dva retka breadboarda, na primjer tipkalo 1 retke 3 i 5. Redak 3 vodi do stupca, a redak 5 preko diode do retka matrice.
- Matrici ne treba GND na breadboardu. Uključeni redak matrice, pin s
LOW, za tipke je isto što i GND. - Dioda na sebi zadrži oko pola volta, pa stupac pritisnute tipke ne pada sasvim na 0 V. To je i dalje mnogo ispod 1,5 V, pa Arduino sigurno čita
LOW.
Spoji USB kabel i otvori Serial Monitor. Pritisni svako tipkalo: ispisuju se 1, 2, 4 i 5? Zatim pritisni i drži tipkala 1, 2 i 4. Ispisuje li program još i 5?
Eksperimenti
1. Dioda je zaštita. Odspoji USB kabel, izvadi diodu tipkala 1 i na njezino mjesto stavi žicu od h5 do h8. Spoji USB kabel i ponovo drži tipkala 1, 2 i 4. Što se dogodi? Vrati diodu na mjesto.
2. Okrenuta dioda. Okreni diodu tipkala 2, tako da je pruga gore, u h11. Radi li tipkalo 2? Okreni je natrag.
Zašto je u eksperimentu 1 važna baš dioda tipkala 1?
Zašto okrenuta dioda tipkala 2 ne radi?
HIGH i program tipku ne vidi.Ako nešto ne radi
- Program ništa ne ispisuje ⇒ Odaberi 9600 baud. Jesu li sve žice u konektoru tipkovnice? Idu li redom s nožica 1 do 8 na D12 do D5?
- Program ispisuje krive znakove, na primjer 4 kada pritisneš 2 ⇒ Kod tvoje tipkovnice redci i stupci su zamijenjeni. U programu zamijeni brojeve u nizovima:
redcineka bude{8, 7, 6, 5}, astupci{12, 11, 10, 9}. - Program ispisuje znakove obrnutim redom, na primjer D kada pritisneš 1 ⇒ Žice su u konektoru okrenute. Spoji nožicu 1 na D12, a nožicu 8 na D5.
- Ne radi cijeli redak ili cijeli stupac tipki ⇒ Jedna žica nije dobro utaknuta. Iz tablice pročitaj koja i provjeri je.
- U Vježbi 4 jedno tipkalo ne radi ⇒ Je li njegova dioda okrenuta? Pruga mora biti dolje, u retku 8, 14, 20 ili 26. Je li tipkalo preko središnjeg utora?
- U Vježbi 4 i dalje se pojavljuje lažna tipka ⇒ Neka dioda nedostaje ili je premoštena žicom. Provjeri da su sve četiri diode na mjestu.
- Program se ne može učitati ⇒ Provjeri jesu li u Arduino IDE-u odabrani ploča Arduino Uno i pravi port.
Dodatni izazovi
- Brava sa šifrom. Neka program pamti posljednje četiri pritisnute tipke. Kada pritisneš #, neka ispiše Otvoreno ako su to bile 1, 9, 7 i 0, a inače Krivo. Savjet: četiri znaka spremi u niz
char sifra[4];. - Koliko tipki odjednom? Neka program svakih pola sekunde ispiše koliko je tipki sada pritisnuto. Na tipkovnici bez dioda pokušaj pronaći četiri tipke koje možeš pritisnuti odjednom, a da se ne pojavi lažna tipka.
- Koliko traje skeniranje?
micros()radi kaomillis(), ali vraća mikrosekunde. S njom izmjeri koliko traje jedno skeniranje cijele tipkovnice. Je li kraće od udarca kuglice, koji traje nekoliko milisekundi?
Što smo naučili?
- U matrici prekidači su u redcima i stupcima. 16 prekidača u matrici 4 × 4 treba samo 8 pinova.
- Arduino matricu skenira: uključi jedan redak (
LOW), pročita sve stupce (INPUT_PULLUP), isključi redak i prijeđe na sljedeći. - Na osciloskopu stupac pritisnute tipke kratko padne na 0 V jednom u svakom skeniranju, dok je uključen redak te tipke.
- Isključeni redak je ulaz (
INPUT), a neHIGH. Inače bi dvije tipke u istom stupcu spojile dva izlaza. - Niz je varijabla s više vrijednosti. Do vrijednosti dolazimo po rednom broju, a brojimo od nule:
redci[0]. - Dvodimenzionalni niz je tablica:
znakovi[redak][stupac]. Tipcharsprema jedan znak. - Petlja u petlji prođe kroz sve redke i u svakom kroz sve stupce.
- Tri pritisnute tipke u tri kuta pravokutnika daju lažnu tipku u četvrtom kutu, jer struja nađe zaobilazni put.
- Biblioteka Keypad skenira tipkovnicu umjesto nas, pa je program mnogo kraći, ali lažne tipke ne uklanja. U fliperu je ne koristimo, jer skenira najviše jednom u 10 ms i može propustiti kratak udarac kuglice.
- Dioda propušta struju samo od anode prema katodi. Pruga na diodi je katoda.
- Dioda uz svaku tipku zaustavi zaobilazni put, pa lažnih tipki nema.
Mali kviz
1. Koliko pinova treba matrica s 8 redaka i 8 stupaca, i koliko prekidača može imati?
2. Kako program zna koja je tipka pritisnuta?
LOW dok je uključen neki redak, pritisnuta je tipka u kojoj se križaju taj redak i taj stupac.3. Zašto isključeni redak nije HIGH, nego INPUT?
HIGH s retkom na LOW. To je kratki spoj između dva pina. Ulaz nije spojen ni s čim, pa kroz njega struja ne teče.4. Zašto prvo učitavamo program, a tek onda spajamo tipkovnicu?
HIGH s izlazom na LOW. Naš program redke drži kao ulaze dok ih ne skenira, pa je siguran.5. Što je redci[0] u programu iz Vježbe 1?
- Brojimo od nule, pa je
redci[0]prva vrijednost u nizu{12, 11, 10, 9}: pin retka R1.
6. Koliko puta se izvede tijelo unutarnje petlje kada getKey() skenira cijelu tipkovnicu?
7. Kada se pojavi lažna tipka?
LOW, kao da je pritisnuta i četvrta tipka.