Igra reakcije
Igra reakcije na Arduinu: automat stanja sa switch i case, nasumično čekanje s random(), mjerenje vremena s millis() i zvukovi s tone() bez čekanja

Pravi fliper uvijek je u nekom stanju. Dok nitko ne igra, lampice trepere, a zaslon vrti natpis. To je attract mode, način u kojem aparat mami igrače. Kada igrač pritisne Start, počinje igra. Kada kuglica padne u rupu, aparat čeka sljedeću kuglicu, a na kraju pokaže rezultat i opet počne mamiti igrače. Ista tipka u svakom stanju znači nešto drugo, a svako stanje ima svoje lampice i svoje zvukove.
Program koji tako radi zove se automat stanja (engleski state machine). Danas ćemo ga napisati za malu igru, igru reakcije. Usput ćemo naučiti puštati zvukove koji ne zaustavljaju program.
Što to znači za fliper?

Na tlocrtu našeg flipera plavim je krugom označen dio lijevog zvučnika i prve od četiri LED matrice na zaslonu, a u velikom krugu isti su dijelovi uvećani. Svijetle točke na matrici dio su slova P iz natpisa PINBALL, koji zaslon vrti dok aparat mami igrače, a iz zvučnika dolaze zvukovi igre. Što znače ostali dijelovi crteža, piše na stranici o fliperu.
Glavni Arduino flipera bit će automat stanja, samo s više stanja: aparat mami igrače, igra je u tijeku, kuglica je izgubljena, igrač je prejako gurnuo aparat (tilt) i igra je gotova. Svako stanje ima svoje lampice, zvukove i pravila za tipke. Kada budemo projektirali fliper, pravila ćemo prvo nacrtati kao dijagram stanja, a tek onda pisati program.
U fliperu se uvijek događa više stvari odjednom: lampice trepere, zvuk svira, a program mora u svakom trenutku primijetiti kuglicu. Zato ni tamo ne smije biti delay().
Kako se igra
- Dok igra čeka igrača, LED-ica polako trepće.
- Pritisneš tipkalo. LED-ica se ugasi, a igra čeka nasumično dugo, od 1 do 4 sekunde.
- LED-ica zasvijetli i zujalica kratko zazuji. Sada pritisni tipkalo što brže možeš!
- Program u Serial Monitoru ispiše koliko ti je trebalo, u milisekundama.
Ako pritisneš tipkalo prije nego što LED-ica zasvijetli, to je prerano. Zujalica tada dugo i duboko zazuji.
Materijal
Svaki polaznik dobiva:
- sve iz lekcije Tipkala kako treba: Arduino Uno i USB kabel, veliki breadboard, malo tipkalo, otpornik 470 Ω (žuto-ljubičasto-smeđe), crvenu LED-icu, otpornik 220 Ω (crveno-crveno-smeđe) i spojne žice, a na računalu biblioteku Bounce2
- aktivnu zujalicu i otpornik 68 Ω (plavo-sivo-crno), kao u lekciji Semafor za automobile i pješake
Za dodatni izazov 2 trebaju još jedno tipkalo i još jedan otpornik od 470 Ω.
Spajanje
Pravila za spajanje ista su kao u prošloj lekciji. Kreni od spoja iz prošle lekcije: LED-ica je na D8, a tipkalo na D2. Zujalicu dodaj na isto mjesto kao na pješačkom semaforu, u redak 27.
| Dio | Arduino pin | Žica s Arduina | Otpornik | Desna strana |
|---|---|---|---|---|
| LED-ica | D8 | a3 | 220 Ω: e3–f3 | crvena LED-ica: dulja nožica u j3, kraća u desnu – liniju |
| Tipkalo | D2 | a8 | 470 Ω: b8–b12 | tipkalo u e12, e14, f12, f14; žica iz j14 u desnu – liniju |
| Zujalica | D5 | a27 | 68 Ω: e27–f27 | + nožica zujalice u j27, druga nožica u desnu – liniju |
| Zajednički GND | GND | desna – linija | – | – |


- Zujalica ima polaritet. Nožica + je dulja, a oznaka + nalazi se i na gornjoj strani kućišta. Okrenuta zujalica šuti.
- Otpornik od 68 Ω smanjuje struju kroz pin i ujedno stišava zujalicu.
- Pin A0 ostaje nespojen. Zašto, saznat ćemo u Vježbi 2.
Vježba 1: Zvuk koji ne čeka
Zujalicu smo upoznali na pješačkom semaforu. Aktivna zujalica sama zuji uvijek istim tonom, a tone() je vrlo brzo pali i gasi, pa čujemo drukčije zvukove (više o tome piše u odjeljku Aktivna zujalica). Prvi program pri svakom pritisku kratko zazuji, a LED-ica svijetli dok držimo tipkalo. Tipkalo čitamo s bibliotekom Bounce2, kao tipku Start na kraju prošle lekcije.
// C++
#include <Bounce2.h> // biblioteka za smirivanje tipkala
const int tipkalo = 2;
const int ledPin = 8;
const int zujalica = 5;
Bounce2::Button igrac; // tipkalo igrača
void setup() {
igrac.attach(tipkalo, INPUT_PULLUP); // tipkalo je na D2, s ugrađenim pull-up otpornikom
igrac.interval(10); // promjena vrijedi kada je tipkalo mirno 10 ms
igrac.setPressedState(LOW); // pritisnuto je LOW
pinMode(ledPin, OUTPUT);
pinMode(zujalica, OUTPUT);
}
void loop() {
igrac.update(); // pročitaj i smiri tipkalo
if (igrac.pressed()) {
tone(zujalica, 800, 60); // kratki zvuk pri svakom pritisku
}
digitalWrite(ledPin, igrac.isPressed()); // LED-ica svijetli dok je tipkalo pritisnuto
}
Učitaj program i pritisni tipkalo nekoliko puta, kratko i dugo.
Što je novo u programu?
Bounce2::Button igrac;– Tipkalo je objekt, kao tipka Start u Vježbi 5 prošle lekcije. Zove seigrac, jer je to tipkalo igrača.igrac.update();– Biblioteka pročita i smiri tipkalo. Mora biti u svakom prolazu krozloop(), jednom, prije svih pitanja o tipkalu.igrac.pressed()iigrac.isPressed()– Prvo dajetruesamo u prolazu u kojem je tipkalo upravo pritisnuto, a drugo dok je pritisnuto.tone(zujalica, 800, 60);– Kao na semaforu: zvuk frekvencije 800 Hz traje 60 ms.tone()zvuk samo pokrene i program odmah ide dalje. Zvuk nakon 60 ms ugasi čip Arduina, sam, dok program radi nešto drugo. Zato LED-ica prati tipkalo i dok zujalica zuji.
Fanfara s delay()
Neka sada svaki pritisak svira kratku fanfaru od tri zvuka. U loop() zamijeni redak s tone() ovim recima:
// C++
tone(zujalica, 400, 100);
delay(150);
tone(zujalica, 600, 100);
delay(150);
tone(zujalica, 800, 300);
delay(300);
Učitaj program i isprobaj:
- Pritisni tipkalo i drži ga. Kada LED-ica zasvijetli?
- Pritisni tipkalo pet puta, što brže možeš. Koliko si fanfara čuo?
Zašto LED-ica kasni i zašto se neki pritisci izgube?
delay() program 600 ms samo čeka. Ne gleda tipkalo i ne pali LED-icu, pa LED-ica zasvijetli tek kada fanfara završi. Pritisak koji počne i završi za vrijeme fanfare program uopće ne vidi.Eksperiment: obriši sva tri delay() i ponovo učitaj program. Što sada čuješ?
Zašto se bez delay() čuje samo posljednji zvuk?
tone() ne čeka da zvuk završi. Sva tri poziva izvedu se jedan za drugim, unutar jedne milisekunde, a svaki novi zvuk odmah zamijeni prethodni. Arduino svira samo jedan zvuk odjednom, pa ostane samo posljednji, od 800 Hz.Za fanfaru bez delay() program bi morao pamtiti koji zvuk je sljedeći i kada ga treba pokrenuti. Drugim riječima, morao bi pamtiti gdje je stao. Upravo to radi automat stanja.
Vježba 2: Igra kao automat stanja
Igra reakcije uvijek je u jednom od četiri stanja. Svako stanje ima svoje ime, a iz jednog stanja u drugo igra prelazi kada se nešto dogodi: kada igrač pritisne tipkalo ili kada prođe neko vrijeme.
| Stanje | Što se događa | Kada prelazi | U stanje |
|---|---|---|---|
CEKA | igra čeka igrača | pritisak | PRIPREMA |
PRIPREMA | LED-ica ne svijetli, igra čeka nasumično 1–4 s | prošlo je nasumično vrijeme | KRENI |
| pritisak: prerano! | REZULTAT | ||
KRENI | LED-ica svijetli, mjerimo vrijeme | pritisak: ispiši vrijeme | REZULTAT |
REZULTAT | pauza 2 s | prošle su 2 s | CEKA |
Istu tablicu možemo nacrtati kao dijagram stanja: svako stanje je jedan pravokutnik, a strelice su prijelazi. Uz svaku strelicu piše što pokreće prijelaz. Ovakav dijagram nacrtat ćemo kasnije i za pravila cijelog flipera.

Program je dulji od dosadašnjih, ali svaki njegov dio je kratak. Tipkalo čitamo s bibliotekom Bounce2, kao u Vježbi 1.
// C++
#include <Bounce2.h> // biblioteka za smirivanje tipkala
const int tipkalo = 2;
const int ledPin = 8;
const int zujalica = 5;
const unsigned long PAUZA = 2000; // toliko traje stanje REZULTAT
// Stanja igre
const int CEKA = 0; // igra čeka igrača
const int PRIPREMA = 1; // nasumično čekanje prije signala
const int KRENI = 2; // LED-ica svijetli: pritisni što brže!
const int REZULTAT = 3; // kratka pauza nakon rezultata
Bounce2::Button igrac; // tipkalo igrača
int stanje = CEKA; // u kojem je stanju igra sada
unsigned long pocetakStanja = 0; // kada je počelo sadašnje stanje
unsigned long cekanje = 0; // koliko dugo traje PRIPREMA
void setup() {
igrac.attach(tipkalo, INPUT_PULLUP);
igrac.interval(10);
igrac.setPressedState(LOW);
pinMode(ledPin, OUTPUT);
pinMode(zujalica, OUTPUT);
Serial.begin(9600);
randomSeed(analogRead(A0)); // A0 je u zraku: svaki put drukčiji početak
Serial.println("Pritisni tipkalo za početak.");
}
void loop() {
igrac.update(); // tipkalo čitamo jednom, na početku
unsigned long uStanju = millis() - pocetakStanja; // koliko je igra već u sadašnjem stanju
switch (stanje) {
case CEKA:
if (igrac.pressed()) {
cekanje = random(1000, 4001); // od 1 do 4 s
Serial.println("Pripremi se...");
promijeniStanje(PRIPREMA);
}
break;
case PRIPREMA:
if (igrac.pressed()) { // pritisak prije signala
tone(zujalica, 150, 400); // dugi niski zvuk
Serial.println("Prerano! Pričekaj da LED-ica zasvijetli.");
promijeniStanje(REZULTAT);
} else if (uStanju >= cekanje) { // vrijeme je za signal
digitalWrite(ledPin, HIGH);
tone(zujalica, 800, 60);
promijeniStanje(KRENI);
}
break;
case KRENI:
if (igrac.pressed()) {
digitalWrite(ledPin, LOW);
Serial.print("Tvoje vrijeme: ");
Serial.print(uStanju); // od signala do pritiska
Serial.println(" ms");
promijeniStanje(REZULTAT);
}
break;
case REZULTAT:
if (uStanju >= PAUZA) {
Serial.println("Pritisni tipkalo za novu igru.");
promijeniStanje(CEKA);
}
break;
}
}
// Prelazak u novo stanje: zapamtimo i kada je počelo.
void promijeniStanje(int novoStanje) {
stanje = novoStanje;
pocetakStanja = millis();
}
Učitaj program, otvori Serial Monitor (9600 baud) i odigraj nekoliko krugova. Pokušaj jednom namjerno pritisnuti prerano.
Što je novo u programu?
const int CEKA = 0;– Stanja su obični brojevi, 0, 1, 2 i 3, ali s imenima.stanje == KRENIlakše se čita odstanje == 2, a ako pogriješimo u imenu, prevođenje javi grešku.int stanje = CEKA;– Varijabla koja pamti u kojem je stanju igra. Na početku igra čeka igrača.switch (stanje) { case CEKA: ... break; }–switchpogleda vrijednost varijablestanjei skoči nacases istom vrijednošću. Izvodi se samo kod tog stanja, do riječibreak, koja završavaswitch. Isto bismo mogli napisati s nizomifielse if, ali ovako se lijepo vidi što radi koje stanje.breakne smijemo zaboraviti. Bez njega program nastavi izvoditi i kod sljedećeg stanja, kao da ga nema.void promijeniStanje(int novoStanje)– Svaki prijelaz ide kroz ovu funkciju. Uz novo stanje zapamti i trenutak u kojem je počelo,pocetakStanja.unsigned long uStanju = millis() - pocetakStanja;– Koliko je milisekundi igra već u sadašnjem stanju. U stanjuPRIPREMAuspoređujemo ga s nasumičnim čekanjem, u stanjuREZULTATs pauzom od 2 s, a u stanjuKRENIto je upravo vrijeme od signala do pritiska: tvoja reakcija.random(1000, 4001)– Nasumični broj od 1000 do 4000. Gornja granica, 4001, nikada ne izađe, zato pišemo za jedan više.randomSeed(analogRead(A0));–random()zapravo nije nasumičan. Nakon svakog pokretanja daje iste brojeve, istim redom, kao da ih čita iz duge tablice.randomSeed()odabire gdje u toj tablici počinjemo. Pin A0 je u zraku, paanalogRead(A0)svaki put pročita nešto drugo. Pin u zraku iz prošle lekcije ovdje nam je koristan.igrac.update();na vrhuloop()– Tipkalo čitamo jednom, na početku svakog prolaza, a stanja samo pitajuigrac.pressed().update()stoji izvanswitch, pa biblioteka prati tipkalo u svakom stanju, i u stanjuREZULTAT, u kojem nas pritisak ne zanima.- Izmjereno vrijeme malo je dulje od tvoje reakcije. Bounce2 javi pritisak tek kada je tipkalo mirno 10 ms, kako smo vidjeli u prošloj lekciji. Zato svako vrijeme ima oko 10 do 15 ms više. Svi igrači dobiju isti dodatak, pa to ne mijenja tko je najbrži.
- U
loop()nema nijednogdelay(). U stanjuPRIPREMAprogram istodobno pazi na vrijeme i na tipkalo. Zato može primijetiti prerani pritisak.
Zašto nasumično čekanje ne pišemo kao delay(cekanje)?
delay() program ne gleda tipkalo. Prerani pritisak tada ne bi primijetio, pa igrač ne bi mogao pogriješiti. Pritisnuo bi tipkalo prije signala i držao ga, a program bi mu izmjerio vrijeme od gotovo 0 ms.Koliko brzo reagiraš?
Većina ljudi na svjetlo reagira za otprilike 200 do 250 ms, dakle za četvrtinu sekunde. Na zvuk reagiramo malo brže. U tom vremenu oko vidi svjetlo, mozak odluči da je vrijeme za pritisak, a živci pokrenu mišiće prsta. Umor i nepažnja to vrijeme produlje, a vježba ga samo malo skrati.
Naša igra uz LED-icu daje i kratki zvuk. Isprobaj kakvo je tvoje vrijeme kada gledaš samo LED-icu, a kakvo kada zatvoriš oči i slušaš samo zujalicu.
Vježba 3: Attract mode i rekord
Igra radi, ali dok čeka igrača ničim ne pokazuje da je spremna. Dodat ćemo joj ono što ima svaki fliper:
- dok igra čeka, LED-ica trepće svakih 500 ms, kao žuto svjetlo semafora u kvaru;
- kratki zvuk kada igra počne;
- rekord: najbolje vrijeme od pokretanja Arduina, uz poseban zvuk kada ga netko obori.
Dijagram stanja ostaje isti. Ne dodajemo nova stanja ni nove prijelaze, nego samo ono što se događa unutar stanja CEKA i KRENI.
Cijeli program
// C++
#include <Bounce2.h> // biblioteka za smirivanje tipkala
const int tipkalo = 2;
const int ledPin = 8;
const int zujalica = 5;
const unsigned long TREPTANJE = 500; // dok igra čeka, LED-ica se mijenja svakih 500 ms
const unsigned long PAUZA = 2000; // toliko traje stanje REZULTAT
// Stanja igre
const int CEKA = 0; // igra čeka igrača: LED-ica trepće
const int PRIPREMA = 1; // nasumično čekanje prije signala
const int KRENI = 2; // LED-ica svijetli: pritisni što brže!
const int REZULTAT = 3; // kratka pauza nakon rezultata
Bounce2::Button igrac; // tipkalo igrača
int stanje = CEKA; // u kojem je stanju igra sada
unsigned long pocetakStanja = 0; // kada je počelo sadašnje stanje
unsigned long cekanje = 0; // koliko dugo traje PRIPREMA
unsigned long rekord = 0; // najbolje vrijeme; 0 znači da rekorda još nema
bool ledUpaljena = false; // za treptanje dok igra čeka
unsigned long zadnjeTreptanje = 0; // kada se LED-ica zadnji put promijenila
void setup() {
igrac.attach(tipkalo, INPUT_PULLUP);
igrac.interval(10);
igrac.setPressedState(LOW);
pinMode(ledPin, OUTPUT);
pinMode(zujalica, OUTPUT);
Serial.begin(9600);
randomSeed(analogRead(A0)); // A0 je u zraku: svaki put drukčiji početak
Serial.println("Pritisni tipkalo za početak.");
}
void loop() {
igrac.update(); // tipkalo čitamo jednom, na početku
unsigned long uStanju = millis() - pocetakStanja; // koliko je igra već u sadašnjem stanju
switch (stanje) {
case CEKA:
if (millis() - zadnjeTreptanje >= TREPTANJE) { // LED-ica trepće bez delay()
zadnjeTreptanje = millis();
ledUpaljena = !ledUpaljena;
digitalWrite(ledPin, ledUpaljena);
}
if (igrac.pressed()) {
ledUpaljena = false;
digitalWrite(ledPin, LOW);
tone(zujalica, 400, 50); // kratki zvuk: igra počinje
cekanje = random(1000, 4001); // od 1 do 4 s
Serial.println("Pripremi se...");
promijeniStanje(PRIPREMA);
}
break;
case PRIPREMA:
if (igrac.pressed()) { // pritisak prije signala
tone(zujalica, 150, 400); // dugi niski zvuk
Serial.println("Prerano! Pričekaj da LED-ica zasvijetli.");
promijeniStanje(REZULTAT);
} else if (uStanju >= cekanje) { // vrijeme je za signal
digitalWrite(ledPin, HIGH);
tone(zujalica, 800, 60);
promijeniStanje(KRENI);
}
break;
case KRENI:
if (igrac.pressed()) {
digitalWrite(ledPin, LOW);
Serial.print("Tvoje vrijeme: ");
Serial.print(uStanju); // od signala do pritiska
Serial.println(" ms");
if (rekord == 0 || uStanju < rekord) {
rekord = uStanju;
tone(zujalica, 1000, 300); // dugi visoki zvuk: novi rekord
Serial.println("Novi rekord!");
} else {
tone(zujalica, 600, 100);
}
promijeniStanje(REZULTAT);
}
break;
case REZULTAT:
if (uStanju >= PAUZA) {
Serial.print("Rekord: ");
Serial.print(rekord);
Serial.println(" ms. Pritisni tipkalo za novu igru.");
promijeniStanje(CEKA);
}
break;
}
}
// Prelazak u novo stanje: zapamtimo i kada je počelo.
void promijeniStanje(int novoStanje) {
stanje = novoStanje;
pocetakStanja = millis();
}
Učitaj program i odigraj nekoliko krugova. Neka igra i netko pokraj tebe: tko ima rekord?
Što je novo u programu?
- Treptanje je samo u stanju
CEKA. Isti oblik smillis()koristili smo za treptanje žutog u lekciji Dva semafora na križanju. Kod ucase CEKA:izvodi se samo dok igra čeka, pa u ostalim stanjima LED-ica ne trepće, a da to nigdje ne moramo zabraniti. To je velika prednost automata stanja: svako stanje ima svoj kod. ledUpaljena = false;idigitalWrite(ledPin, LOW);– Kada igra krene, LED-icu ugasimo. Inače bi mogla ostati upaljena, jer je zadnje treptanje možda bilo baš upali.unsigned long rekord = 0;– Najbolje vrijeme. Vrijednost 0 znači da rekorda još nema, jer reakcija od 0 ms nije moguća.if (rekord == 0 || uStanju < rekord)–||znači ili. Uvjet je istinit ako rekorda još nema ili ako je novo vrijeme bolje od rekorda. U prošloj lekciji upoznali smo&&, koji znači i.- Svaki važan događaj ima svoj zvuk: početak igre, signal, prerani pritisak, obično vrijeme i novi rekord. Svi zvukovi pokreću se s
tone()i ne zaustavljaju program. - Rekord se ne pamti kada Arduino isključimo. Na fliperu ćemo rekorde kasnije spremati u memoriju koja ih pamti i kada je Arduino isključen.
Ako nešto ne radi
- Zujalica šuti ⇒ Je li dulja nožica, s oznakom +, u j27, a druga u desnoj – liniji? Je li žica s D5 u a27, a otpornik od e27 do f27?
- LED-ica ne svijetli ili ne reagira na tipkalo ⇒ Spoj LED-ice i tipkala isti je kao u prošloj lekciji. Pogledaj odjeljak Ako nešto ne radi u njoj.
- Serial Monitor ne pokazuje ništa ili pokazuje čudne znakove ⇒ Odaberi 9600 baud.
- Nasumično čekanje svaki put je isto, nakon svakog pokretanja ⇒ Je li na pinu A0 nešto spojeno? Je li u
setup()redak srandomSeed()? - Igra preskače stanja ili radi nešto što nije u dijagramu ⇒ Je li na kraju svakog
casenapisanbreak;? - Igra ne reagira na tipkalo ⇒ Je li
igrac.update();na početkuloop()? Bez njega biblioteka tipkalo nikada ne pročita. - Greška
Bounce2.h: No such file or directory⇒ Biblioteka Bounce2 nije instalirana. Instaliraj je kao u prošloj lekciji. - Program se ne može učitati ⇒ Provjeri jesu li u Arduino IDE-u odabrani ploča Arduino Uno i pravi port.
Dodatni izazovi
- Zaspao si? Ako igrač u stanju
KRENIne pritisne tipkalo za 3 s, neka program ispiše Prespor! i prijeđe u stanjeREZULTAT. Koju strelicu tada treba dodati u dijagram stanja? - Dva igrača. Dodaj drugo tipkalo na D4, spojeno kao u dodatnom izazovu 1 prošle lekcije. U stanju
KRENIpobjeđuje igrač koji prvi pritisne svoje tipkalo. Tko pritisne prerano, gubi. Savjet: drugo tipkalo dobije svoj objekt, na primjerigrac2, a na početkuloop()pozoviupdate()za oba. - Fanfara bez
delay(). Neka igra na početku svira fanfaru od tri zvuka iz Vježbe 1, ali bezdelay(). Savjet: frekvencije spremi u niz,int note[] = {400, 600, 800};. Niz je varijabla s više vrijednosti, a do svake dolazimo po rednom broju:note[0]je 400,note[2]je 800. Program treba pamtiti koja je nota sljedeća i kada ju treba pokrenuti. To je mali automat stanja unutar igre. - Prosjek. Neka program nakon svakih pet krugova ispiše prosječno vrijeme tih pet krugova. Prerani pritisak ne računa se kao krug.
Što smo naučili?
- Automat stanja je program koji je uvijek u jednom od nekoliko stanja. U svakom stanju radi nešto drugo, a u drugo stanje prelazi kada se nešto dogodi.
- Stanja i prijelaze crtamo kao dijagram stanja: pravokutnici su stanja, a strelice prijelazi.
- Stanja su brojevi s imenima (
const int CEKA = 0;), a varijablastanjepamti sadašnje stanje. switchicaseizvode kod samo onog stanja u kojem je program. Svakicasezavršava sbreak.- Ako pri svakom prijelazu zapamtimo vrijeme,
millis() - pocetakStanjakaže koliko je program već u tom stanju. - S bibliotekom Bounce2 tipkalo čitamo jednom, s
update()na početku svakog prolaza, a stanja pitajupressed(). tone(pin, frekvencija, trajanje)zvuk samo pokrene i ne čeka da završi. Arduino svira jedan zvuk odjednom: novi zamijeni prethodni.delay()zaustavlja cijeli program. Za to vrijeme Arduino ne vidi tipkalo.random(od, do)daje nasumični broj, a gornja granica nikada ne izađe.randomSeed(analogRead(A0))s pinom u zraku daje drukčije brojeve nakon svakog pokretanja.||znači ili, a&&znači i.
Mali kviz
1. Što je automat stanja?
2. Zašto LED-ica u Vježbi 1 prati tipkalo i dok zujalica zuji?
tone(zujalica, 800, 60) zvuk samo pokrene i program odmah ide dalje. Zvuk nakon 60 ms ugasi čip Arduina, sam, a program za to vrijeme i dalje čita tipkalo i pali LED-icu.3. Što se dogodi ako na kraju jednog case zaboravimo break?
switch, nego nastavi izvoditi i kod sljedećeg stanja. Igra tada radi stvari koje nisu u dijagramu stanja, na primjer preskoči stanje.4. Što znači uStanju u stanju KRENI?
KRENI. Kada igrač pritisne tipkalo, to je njegovo vrijeme reakcije.5. Može li random(1000, 4001) dati 4001?
6. Zašto pin A0 u ovoj igri mora ostati nespojen?
randomSeed(analogRead(A0)) treba nasumičnu vrijednost. Pin u zraku svaki put pročita nešto drugo, pa igra nakon svakog pokretanja čeka drukčije dugo. Kada bi pin bio spojen, čitao bi uvijek isto, a igra bi nakon svakog pokretanja čekala jednako dugo, istim redom.7. Kako igra primijeti prerani pritisak?
PRIPREMA program u svakom prolazu kroz loop() gleda i vrijeme i tipkalo. Ako je tipkalo pritisnuto prije nego što je čekanje prošlo, to je prerani pritisak, pa igra prelazi u stanje REZULTAT.8. Zašto u stanju KRENI LED-ica ne trepće, iako je kod za treptanje u programu?
case CEKA:, pa se izvodi samo dok je igra u stanju CEKA. U stanju KRENI izvodi se samo kod iz case KRENI:.