Arduino – Gioco di luci (sketch)

Qui potete trovare l’articolo
Il video può essere visualizzato anche su youtube
Supportami su Patreon!
Seguimi anche sulla pagina di facebook! e sul canale di youtube

Di seguito trovate il codice sorgente

Innanzitutto assegnamo a delle costanti descrittive (come ad esempio redLed) il valore del piedino a cui l’oggetto descritto è collegato (nel caso del led rosso il piedino numero 2).
Creiamo tutte le variabili di servizio in cui inserire i valori rilevati dagli interruttori (nello specifico HIGH se il bottone è premuto o LOW se è lasciato aperto).
Creiamo le variabili per tenere il conto del livello raggiunto e del numero di scelte operate (in questo modo sappiamo che quando il numero di scelte eguaglia il livello bisogna creare una nuova sequenza).
Creiamo, le variabili dove immagazziniamo i valori della sequenza assegnati e i valori scelti dal giocatore e infine creiamo un array per immagazzinare i valori delle note da passare al piezo e un oggetto della classe Servo che controllerà il nostro servomotore

#include

const int redLED = 2;
const int blueLED = 3;
const int greenLED = 4;
const int yellowLED = 5;
const int servoPIN = 6;
const int greenControlLED = 7;
const int redControlLED = 8;
const int piezo = 9;
const int redButton = 10;
const int blueButton = 11;
const int greenButton = 12;
const int yellowButton = 13;

int redButtonVal;
int blueButtonVal;
int greenButtonVal;
int yellowButtonVal;

int level = 1;
int chooses = 0;

int color = 0;
int colorsA[10];
int colorsC[10];

int notes[] = {262, 294, 330, 349};

E’ ora il momento di creare la sequenza di setup(), questa sequenza viene eseguita solamente all’accensione del nostro prototipo e serve per inizializzarne tutte le componenti.

Utilizziamo il codice randomSeed(analogRead(0)); per inizializzare la funzione random (che genera numeri casuali). Questo frammento di codice è molto interessante, sfrutta il fatto che abbiamo lasciato il piedino 0 non collegato, soggetto quindi a disturbi di tensione, non c’è quindi modo di stabilire quale valore verrà assegnato al generatore di numeri casuali, creando così una sequenza pseudocasuale praticamente impossibile da prevedere.

Impostiamo i pin legati ai led come OUTPUT, con il codice pinMode(numeropin, OUTPUT).a in seguito accendiamo il led così che l’utente possa verificarne il funzionamento e, già che ci siamo, riproduciamo il suono che sarà associato a quel LED, così l’utente può accertarsi anche del funzionamento del piezo.

randomSeed(analogRead(0));
pinMode(redLED, OUTPUT);
digitalWrite(redLED, HIGH);
tone(piezo, notes[0]);
delay(200);
noTone(piezo);

Nell’inizializzare i LED di controllo (quelli che ci segnalano se la sequenza inserita dall’utente è uguale a quella fornita in precedenza dal PC o meno) riproduciamo, anziché un solo suono, una sequenza di suoni. Nello specifico una scala crescente per il LED verde, che ci segnala una sequenza corretta e una scala calante per il LED rosso, che segnala un errore.

pinMode(greenControlLED, OUTPUT);
digitalWrite(greenControlLED, HIGH);
tone(piezo, notes[3]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[2]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[1]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[0]);
delay(100);
noTone(piezo);
digitalWrite(greenControlLED, LOW);

pinMode(redControlLED, OUTPUT);
digitalWrite(redControlLED, HIGH);
tone(piezo, notes[0]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[1]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[2]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[3]);
delay(100);
noTone(piezo);
digitalWrite(redControlLED, LOW);

impostiamo i pin associati agli interruttori come input, questi pin dovranno infatti leggere il segnale del pulsante.

pinMode(redButton, INPUT);
pinMode(blueButton, INPUT);
pinMode(greenButton, INPUT);
pinMode(yellowButton, INPUT);

con il seguente codice associamo invece al nostro oggetto servo, creato in precedenza, il pin a cui il servomotore è collegato


servo.attach(servoPIN);

per segnalare la fine della sequenza di configuarzione facciamo lampeggiare le quattro luci

digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(yellowLED, LOW);
delay(150);

digitalWrite(redLED, HIGH);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(yellowLED, HIGH);
delay(150);

digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(yellowLED, LOW);
delay(150);

passiamo ora alla sequenza principale di ogni sketch arduino, il loop(), qui viene scritto tutto il corpo del software che gestisce il nostro prototipo e la sequenza continua a ripetersi finché il dispositivo non viene spento.

come prima cosa posizioniamo il braccio del servomotore sul livello appropriato

servo.write(level*18 - 9);

Questo codice dice al servomotore di posizionarsi ad un angolo pari al livello * 18 – 9. Perché questo strano calcolo? in realtà è molto semplice! Il servomotore si muove di 180°, avendo il nostro gioco 10 livelli ci sono sul segnapunti 10 sezioni da 180/10 = 18 gradi ciascuna, il -9 è per posizionare il braccio al centro nella sezione.
La prima sezione va infatti da 0° a 18° (livello 1 * 18 – 9) ci porta a 9°, esattamente a metà della sezione.

con il successivo blocco di codice creiamo una sequenza di luci, la lunghezza della sequenza è parti al livello raggiunto

for(int i = 0; i < level; i++) { color = random(3); colorsA[i] = color; switch(color) { case 0 : digitalWrite(redLED, HIGH); tone(piezo, notes[0]); delay(500); digitalWrite(redLED, LOW); noTone(piezo); delay(200); break; case 1: digitalWrite(blueLED, HIGH); tone(piezo, notes[1]); delay(500); digitalWrite(blueLED, LOW); noTone(piezo); delay(200); break; case 2: digitalWrite(greenLED, HIGH); tone(piezo, notes[2]); delay(500); digitalWrite(greenLED, LOW); noTone(piezo); delay(200); break; case 3: digitalWrite(yellowLED, HIGH); tone(piezo, notes[3]); delay(500); digitalWrite(yellowLED, LOW); noTone(piezo); delay(200); break; default: break; } }
z
ovviamente oltre a creare la sequenza e ad immagazzinarla in un array riproduciamo ogni componente illuminando il relativo LED e riproducendo il relativo suono.
Per la creazione di ogni elemento della sequenza utilizziamo la funzione random che come detto in precedenza genera numeri casuali in un intervallo assegnato, nel nostro caso da 0, 1, 2, 3 corrispondenti rispettivamente alle luci rossa, blu, verde e gialla.

Il prossimo frammento di codice ci porta già nella fase del giocatore, in cui questi deve premere i pulsanti per riprodurre la sequenza proposta dal gioco.
Il codice legge i valori dei quattro interruttori, se uno di essi è stato premuto assegna il relativo valore ad un array di risposte (da confrontare poi con quello della sequenza assegnata), inoltre illumina il LED relativo all'interruttore premuto e riproduce il relativo suono.
Se commettiamo un errore il gioco ci segnala immediatamente che la sequenza è errata.

while(chooses <= level) { redButtonVal = digitalRead(redButton); blueButtonVal = digitalRead(blueButton); greenButtonVal = digitalRead(greenButton); yellowButtonVal = digitalRead(yellowButton); if(redButtonVal == HIGH) { colorsC[chooses] = 0; digitalWrite(redLED, HIGH); tone(piezo, notes[0]); delay(500); noTone(piezo); digitalWrite(redLED, LOW); delay(200); if(colorsC[chooses] != colorsA[chooses]) { level = 0; } chooses++; } else if(blueButtonVal == HIGH) { colorsC[chooses] = 1; digitalWrite(blueLED, HIGH); tone(piezo, notes[1]); delay(500); noTone(piezo); digitalWrite(blueLED, LOW); delay(200); if(colorsC[chooses] != colorsA[chooses]) { level = 0; } chooses++; } else if(greenButtonVal == HIGH) { colorsC[chooses] = 2; digitalWrite(greenLED, HIGH); tone(piezo, notes[2]); delay(500); noTone(piezo); digitalWrite(greenLED, LOW); delay(200); if(colorsC[chooses] != colorsA[chooses]) { level = 0; } chooses++; }else if(yellowButtonVal == HIGH) { colorsC[chooses] = 3; digitalWrite(yellowLED, HIGH); tone(piezo, notes[1]); delay(500); noTone(piezo); digitalWrite(yellowLED, LOW); delay(200); if(colorsC[chooses] != colorsA[chooses]) { level = 0; } chooses++; } if(chooses == level) { level++; chooses = 10; digitalWrite(greenControlLED, HIGH); tone(piezo, notes[3]); delay(100); noTone(piezo); delay(50); tone(piezo,notes[2]); delay(100); noTone(piezo); delay(50); tone(piezo,notes[1]); delay(100); noTone(piezo); delay(50); tone(piezo,notes[0]); delay(100); noTone(piezo); digitalWrite(greenControlLED, LOW); } }

Se raggiungiamo il livello 10 viene riprodotta una sequenza per "celebrare" la vittoria

if(level == 10) {
digitalWrite(redLED, HIGH);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(yellowLED, HIGH);
digitalWrite(redControlLED, HIGH);
digitalWrite(greenControlLED, HIGH);
tone(piezo, notes[3]);
delay(400);
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(yellowLED, LOW);
digitalWrite(redControlLED, LOW);
digitalWrite(greenControlLED, LOW);
noTone(piezo);
delay(200);
digitalWrite(redLED, HIGH);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(yellowLED, HIGH);
digitalWrite(redControlLED, HIGH);
digitalWrite(greenControlLED, HIGH);
tone(piezo, notes[2]);
delay(400);
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(yellowLED, LOW);
digitalWrite(redControlLED, LOW);
digitalWrite(greenControlLED, LOW);
noTone(piezo);
delay(200);
digitalWrite(redLED, HIGH);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(yellowLED, HIGH);
digitalWrite(redControlLED, HIGH);
digitalWrite(greenControlLED, HIGH);
tone(piezo, notes[1]);
delay(400);
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(yellowLED, LOW);
digitalWrite(redControlLED, LOW);
digitalWrite(greenControlLED, LOW);
noTone(piezo);
delay(200);
digitalWrite(redLED, HIGH);
digitalWrite(blueLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(yellowLED, HIGH);
digitalWrite(redControlLED, HIGH);
digitalWrite(greenControlLED, HIGH);
tone(piezo, notes[0]);
delay(400);
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(yellowLED, LOW);
digitalWrite(redControlLED, LOW);
digitalWrite(greenControlLED, LOW);
noTone(piezo);
delay(200);

level = 1;
}
chooses = 0;

infine di seguito il frammento di codice che riproduce la sequenza di errore

if(level == 0) {

digitalWrite(redControlLED, HIGH);
tone(piezo, notes[0]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[1]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[2]);
delay(100);
noTone(piezo);
delay(50);
tone(piezo,notes[3]);
delay(100);
noTone(piezo);
digitalWrite(redControlLED, LOW);
level = 1;
}

}

Lascia un commento

XHTML: Puoi usare questi tag: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>