Megistone
Sensori di temperatura
I sensori di temperatura si basano sulla proprietà dei semiconduttori (diodi e transistor) di possedere una tensione o una corrente dipendenti dalla temperatura. I circuiti integrati, come ad esempio il TMP36 presente nello Starter Kit di Arduino, impiegano diversi transistor e ne sfruttano la relazione fra la tensione base-emettitore e la corrente di collettore, in maniera tale che per valori fissati di corrente la tensione dipenda soltanto dalla temperatura.
Si tratta di un sensore di temperatura analogico, il quale fornisce un valore di tensione di 10 mV per grado direttamente proporzionale al valore di temperatura che viene rilevato. Può leggere un range di temperatura da –40 a 125°C. Come possiamo notare dalla figura, possiede tre pin:
- piedino di alimentazione da +2,7 V a 5,5 V;
- piedino di rilevazione tensione analogica di uscita;
- piedino collegato a massa.
In questo esempio utilizziamo la scheda Arduino per rilevare la temperatura esterna e dopo averla esaminata far accendere alcuni LED. Se la temperatura rilevata è fino a 2 gradi sopra al valore minimo, i LED vengono mantenuti spenti. Se la temperatura è superiore fino a 4 gradi sopra al minimo accendiamo il LED verde, se è tra 4 e 6 gradi sopra al minimo accendiamo sia il LED verde che il LED giallo, se infine è superiore ai 6 gradi sopra al minimo accendiamo tutti i LED.
Soluzione
const int sensorPin = A0;
const float baselineTemp = 20;
void setup()
{
//Settaggio della porta seriale a 9600 baud
Serial.begin(9600);
//Settaggio pin LED 2, 3 e 4 in OUTPUT
for(int pinNumber = 2; pinNumber < 5; pinNumber++)
{
pinMode(pinNumber,OUTPUT);
digitalWrite(pinNumber, LOW);
}
}
void loop()
{
//Lettura del valore analogico pin 0
int sensorVal = analogRead(sensorPin);
//Visualizzazione su schermo del valore letto
Serial.print("Valore sensore: ");
Serial.print(sensorVal);
//Conversione temperatura (0-1023) in tensione (0-5)
float volt = (sensorVal/1024.0) * 5.0;
//Visualizzazione su schermo della tensione in Volt
Serial.print(", Tensione: ");
Serial.print(volt);
//Conversione della tensione in gradi (ogni 10 mV un grado)
Serial.print(", Gradi C: ");
float temperatura = (volt - .5) * 100;
Serial.println(temperatura);
//Controllo della temperatura
//Se minore di baselineTemp spengo tutti i LED
if (temperatura < baselineTemp)
{
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}//Se tra 2-4 gradi sopra al minimo accendo il verde
else if (temperatura>=baselineTemp+2 && temperatura< baselineTemp+4)
{
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}//Se tra 4-6 gradi sopra al minimo accendo il verde+giallo
else if (temperatura>=baselineTemp+4 && temperatura< baselineTemp+6)
{
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
}//Se >6 gradi sopra al minimo accendo il verde+giallo+rosso
else if (temperatura>=baselineTemp+6)
{
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
}
delay(1);
}
L’input da sensori analogici
I sensori che inviano informazioni riguardanti l’ambiente al di fuori della scheda, non sempre generano dati digitali del tipo HIGH e LOW, come visto per i pulsanti di tipo micro switch. Nella maggioranza dei casi i sensori sono analogici, con livello di precisione assai superiore ai dati digitali. Il microcontrollore della scheda Arduino è dotato di un convertitore Analogico Digitale a 6 canali collegato ai pin A0...A5 della scheda, con una risoluzione a 10 bit. Il convertitore A/D della scheda Arduino è in grado di convertire un voltaggio elettrico letto in ingresso a un valore digitale compreso tra 0 e 1023. L’istruzione analogRead() prevede come unico parametro il piedino della scheda dal quale ricevere l’informazione analogica.

Realizziamo il circuito di figura e programmiamo uno sketch per scrivere sul Serial Monitor, ogni due secondi, il valore digitale acquisito dall'ingresso analogico a cui è connesso il potenziometro. Inoltre scriviamo a fianco il valore della tensione Vp, sapendo che mentre la tensione del potenziometro varia da 0 V a 5 V, il corrispondente valore digitale varia da 0 a 1023. In questo modo si è realizzato un voltmetro digitale.
Soluzione
int pinPot=A0;
int VpDigit;
float VpVolt;
void setup()
{
Serial.begin(9600);
}
void loop()
{
VpDigit = analogRead(pinPot);
VpVolt=map(VpDigit, 0, 1023, 0, 500);
VpVolt=VpVolt/100;
Serial.print("Valore digitale:");
Serial.print(VpDigit);
Serial.print(" ");
Serial.print("Tensione:");
Serial.print(VpVolt);
Serial.println(" V");
delay(2000);
}
La prima istruzione del loop effettua la lettura del valore analogico di tensione presente sul pin 0 e restituisce un numero, VpDigit, compreso tra 0 e 1023, proporzionale alla tensione. La tensione Vpvolt si calcola da VpDigit con la proporzione:
Vpvolt=(Vpdigit *5)/1023
Per calcolare la proporzione è utile l'istruzione:
VpVolt=map(VpDigit, 0, 1023, 0, 500)
La funzione map converte il valore di VpDigit, compreso nell'intervallo tra 0 e 1023, in un nuovo valore proporzionale, compreso tra 0 e 500; in questo modo, dividendo per 100 nella successiva istruzione, si ottiene una tensione VpVolt che varia tra 0 V e 5 V, con due cifre decimali. Per poter esprimere VpVolt con due cifre decimali, la variabile è stata dichiarata di tipo float. Scriviamo poi i valori di VpDigit e VpVolt sul Monitor Seriale. Naturalmente sull'ingresso del voltmetro (pin AO) possiamo collegare qualunque tensione, compresa tra o Ve 5 V; il potenziometro serve solo per testare il circuito.
Il buzzer
Il buzzer
Il buzzer è un attuatore acustico di piccola potenza, basato sull'effetto piezoelettrico (per questo è detto anche piezo). usato per emettere suoni.
L'effetto piezoelettrico è la proprietà che hanno alcuni cristalli, tra cui il quarzo:
- se sottoposti a tensione si deformano: se la tensione è variabile nel tempo, ad esempio un'onda quadra, la deformazione produce un'onda sonora: questo viene sfruttato per realizzare buzzer o altoparlanti per alte frequenze (tweeter):
- se sottoposti a compressione generano una tensione: ciò consente di realizzare microfoni, sensori di pressione o accendini piezoelettrici.
Il buzzer (piezo) contenuto nello Starter Kit può quindi essere usato come emettitore di suoni, collegandolo direttamente a un'uscita digitale di Ardui no su cui generare un'onda quadra (tensione alternativamente HIGH e LOW) a una certa frequenza. In alternativa, può essere collegato a un ingresso analogico per rivelare vibrazioni acustiche.
Arduino mette a disposizione la funzione tone per semplificare la generazione delle note:
tone (pin, frequenza, durata)
dove i parametri sono:
- pin: il numero del pin d'uscita a cui è collegato il buzzer,
- frequenza: la frequenza della nota;
- durata (facoltativo): la durata in millisecondi della nota.
Con l'istruzione noTone(pin) la nota sul pin s'interrompe.
In commercio esistono anche buzzer che generano una nota fissa se alimentati con una tensione continua, ad esempio 5 V, sono usati come segna latori acustici.
Esercizio. Suonare due note
Suonare le note DO e RE con il buzzer, premendo due pulsanti.
Soluzione Il cuore della funzione loop() è realizzato con due cicli while, uno per pulsante: finché un pulsante è premuto il programma rimane nel ciclo corrispondente, insensibile alla pressione dell'altro. All'uscita del while (pulsante rilasciato) la nota sul buzzer viene interrotta, in attesa della pressione di uno dei due pulsanti.
Esercizio
Si suoni il brano «Fra Martino campanaro»
Premendo un pulsante, il buzzer suona le prime quattro battute del brano.
Soluzione
Lo schema hardware è analogo a quello di sopra, con solo un pulsante collegato al pin 3.
Il metronomo a 240 significa che devi suonare 240/60 = 4 semiminime al secondo; quindi ognuna dura 250 ms.
Iterazione definita
L'iterazione definita è molto più articolata da codificare in quanto sono previste diverse possibilità che rendono questa istruzione particolarmente comoda: ricordiamo che può essere utilizzata solo quando conosciamo a priori il numero di volte che il ciclo deve essere eseguito.
La sintassi da inserire nel blocco che esegue l'iterazione a conteggio è composta da tre parti e ciascuna di esse è una istruzione che ha come "protagonista" una variabile, chiamata variabile di conteggio:
- inizializzazione della variabile che effettua il conteggio: X = 1 (valore iniziale del contatore);
- condizione che fa ripetere il ciclo: x <= 5 (valore finale del contatore);
- aggiornamento della variabile di conteggio che viene fatto a ogni ripetizione: x = x + 1 (incremento o passo).
Queste tre operazioni vengono eseguite ogni volta che il ciclo viene ripetuto.
Vediamo come si può utilizzare il ciclo FOR con arduino: il blocco di istruzioni che accende e spegne il LED è scritto una sola volta, ma viene eseguito per tre volte, che corrispondono al numero di incrementi della variabile cont per arrivare da 1 a nlamp=3. Si noti che, modificando il valore della costante nlamp, si può variare il nu mero dei lampeggi.
const int nLamp=3; // n° di lampeggi = 3
const int timer1 = 200; // tempo di ritardo 200 ms
const int timer2 = 2000; // tempo di ritardo 2 s
void setup() {
pinMode(13, OUTPUT); // inizializza il pin 13 come uscita
}
void loop() {
/*
Ciclo FOR: le istruzioni tra le graffe sono eseguite nLamp=3 volte, cioè
finchè la variabile "cont", inizializzata a 1 e incrementata
di 1 ad ogni ciclo, risulta minore o uguale a nLamp=3
*/
for(int cont = 1; cont <= nLamp; cont++){
digitalWrite(13, HIGH); // poni a livello ALTO il pin 13 (LED ON)
delay(timer1); // attendi 200 ms
digitalWrite(13, LOW); // poni a livello BASSO il pin 13 (LED OFF)
delay(timer1); // attendi 200 ms
}
delay(timer2); // pausa di 2 s dopo i tre lampeggi
}
1.A Lampeggio complesso
Far lampeggiare il LED sulla scheda Arduino, con una sequenza ciclica di 1, 2,3 lampeggi veloci, intervallati da pause di 2 s.
Soluzione
Per contare il numero dei cicli e il numero dei lampeggi crescenti all'interno di ogni ciclo, devi impiegare due FOR uno dentro l'altro (nidificati):
- nel FOR esterno la variabile ciclo si incrementa da 1 a naLmpMax, inizializzato al valore 3, quindi ciclo conta i 3 cicli di lampeggi;
- nel FOR interno la variabile cont si incrementa da 1 al valore corrente di ciclo; quindi conta il numero di lampeggi da effettuare in quel ciclo.
Modificando il valore di nlampMax (numero massimo di lampeggi) si può variare il ciclo dei lampeggi, ad esempio ponendo nLampmax=5, si ottiene una sequenza di 1, 2, 3, 4, 5 lampeggi.
/*
Lampeggio complesso
Cicli di 1, 2, 3 lampeggi (con 2 FOR nidificati)
*/
const int nLampMax = 3; // n° massimo di lampeggi
const int timer1 = 200; // tempo tra le commutazioni degli impulsi (200 ms)
const int timer2 = 2000; // pausa tra ogni serie di impulsi (2 s)
void setup() {
pinMode(13, OUTPUT); // inizializza il pin 13 come uscita
}
void loop() {
/*
Due FOR nidificati:
- nel FOR esterno, la variabile "ciclo", che varia da 1 a nLampMax=3, contiene il
numero del ciclo, corrispondente al numero di lampeggi da effettuare in quel ciclo
- nel FOR interno, la variabile "cont" conta i lampeggi all'interno del ciclo
- al termine di ogni ciclo di lampeggi (1, 2, 3) c'è una pausa di 2 s
*/
for (int ciclo = 1; ciclo <= nLampMax ; ciclo++) { // FOR esterno
for (int cont = 1; cont <= ciclo ; cont++) { // FOR interno
digitalWrite(13, HIGH); // poni a livello ALTO il pin 13 (LED ON)
delay(timer1); // attendi 200 ms
digitalWrite(13, LOW); // poni a livello BASSO il pin 13 (LED OFF)
delay(timer1); // attendi 200 ms
}
delay(timer2); // pausa di 2 s al termine di ogni ciclo di lampeggi
}
}
Monitor Seriale + istruzione DO...WHILE
Durante la scrittura di uno sketch, l'IDE fornisce informazioni sulla correttezza delle parole chiave, colorando in modo differente quelle che riconosce appartenenti al lessico del linguaggio di programmazione, inoltre, in fase di compilazione, l'IDE ci invia messaggi nel caso in cui individui degli errori di sintassi nell'uso delle istruzioni.
Una volta che la compilazione e il caricamento su Arduino sono andati a buon fine, non siamo ancora sicuri che il programma esegua esattamente quello che ci eravamo prefissati: possono esserci degli errori di programmazione, difficilmente individuabili con la sola osservazione del comportamento del circuito.
Durante l'esecuzione di uno sketch, per effettuare la ricerca di eventuali errori di programmazione (debugging), si può interagire con Arduino mediante il Monitor Seriale.
Gli elementi principali della finestra del Monitor Seriale sono:
- Trasmissione da PC verso Arduino
- Trasmissione da Arduino verso PC
Le principali istruzioni per l'impiego del Monitor Seriale sono:
Serial.begin(9600); → imposta in setup la velocità di comunicazione a 9600 bps (bit per secondo).
PC → Arduino
Serial.read(); → restituisce il valore trasmesso dal PC via monitor seriale.
Serial.available(); → restituisce il numero di byte arrivati dal PC sulla porta seriale e disponibili per la lettura.
flush(); → cancella la coda dei dati arrivati dal PC sulla //sulla porta seriale.
Arduino → PC (RX)
Serial.println(val); →stampa sul monitor il valore di val (variabile o costante) e va a capo; al posto di val può esserci una stringa di caratteri compresa tra apici: ad esempio "La velocità è:"
Serial.print(val); //È come Serial.println(val) ma non va a capo dopo la stampa
L'esempio seguente è utile per sperimentare le principali istruzioni per la trasmissione e la ricezione mediante Monitor Seriale.
Scambio di informazioni tra PC e Arduino, con il Monitor Seriale
Invia un carattere dal monitor seriale; Arduino lo riceve e poi lo ritrasmette al PC scrivendo sul monitor «Ho ricevuto»: seguito dal codice ASCII (in decimale) del carattere.
Per esempio, se scrivi il carattere a e premi invio nella linea in alto della finestra, nel campo di ricezione del monitor seriale appare: Ho ricevuto: 97 (il codice ASCII decimale corrispondente alla lettera a minuscola è 97).
Soluzione
Il codice dello sketch
int byteRicevuto = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
byteRicevuto = Serial.read();
Serial.print("Ho ricevuto:");
Serial.println(byteRicevuto);
}
}
Una volta effettuata la messa a punto del programma, le istruzioni relative al Monitor Seriale possono essere rimosse, anche perché Arduino in genere è destinato a funzionare stand alone, senza computer con cui scambiare dati sul Monitor Seriale.
Oltre che per il debugging, il Monitor Seriale può essere utilizzato per sostituire, in fase di sviluppo, un display non ancora disponibile su cui visualizzare dei dati, come nel seguente esercizio.
Visualizza un conteggio con il Monitor Seriale Conta il numero di pressioni di un pulsante (collegato al digital pin 7 di Arduino) e visualizza il risultato sul Monitor Seriale.
Soluzione
il codice dello sketch
bool puls;
const int pinPuls=7;
int cont=0;
void setup()
{
pinMode(pinPuls, INPUT_PULLUP);
Serial.begin(9600);
}
void loop()
{
do{
puls = digitalRead(pinPuls);
}while(puls);
cont++;
Serial.print("N° pressioni:");
Serial.println(cont);
delay(20);
do{
puls = digitalRead(pinPuls);
}while(puls==0);
delay(20);
}
La trasmissione seriale
All'interno di un computer o di un microprocessore/microcontrollore la trasmissione dei dati avviene su più linee contemporaneamente (trasmissione parallela sul bus dati). In questo modo ad ogni clock si possono inviare più bit in uno stesso istante, rendendo veloce la comunicazione.
All'esterno del computer, nella comunicazione con le periferiche, si preferisce inviare un bit alla volta (trasmissione seriale); uno dei motivi è ridurre il numero di fili nei cavi, rendendoli più maneggevoli ed economici.
Uno standard diffuso per la trasmissione seriale è l'USB, acronimo di Universal Serial Bus (Bus Universale Seriale).
Il Monitor Seriale usa la trasmissione seriale per la comunicazione con il computer via USB. Tale comunicazione è replicata sui digital pin 0 (RX dal computer) e pin 1 (TX verso il computer), per cui, se si usa il Monitor Seriale, i digital pin 0 e 1 non devono essere utilizzati per l'input/output.
In realtà, se si impiegano solo istruzioni Serial.print() per la comunicazione di dati verso il computer, in caso di necessità il pin 0 (ricezione dal computer) può essere utilizzato senza creare conflitto, come si vede nel seguente progetto.
Gara di riflessi
Si progetti un circuito per gestire una gara di riflessi tra due concorrenti A e B, utilizzando i seguenti elementi:
- un pulsante e un LED rosso per ogni concorrente;
- un pulsante di start, un LED verde, un buzzer.
Lo svolgimento di una prova è il seguente:
- durante la fase di attesa il LED verde e acceso,
- quando si preme start il LED verde si spegne per un tempo di durata casuale (da 3 s a 8 s);
- al termine del tempo suona il buzzer e si riaccende il LED verde;
- il primo concorrente che preme il proprio pulsante vince: il suo LED lampeggia e il buzzer suona sincrono col LED per 5 s;
- se alla fine del tempo casuale (al suono del buzzer) uno dei due concorrenti sta già premendo il pulsante, vince l'altro, se ha premuto correttamente.
Inoltre, al termine di ogni prova, deve apparire sul Monitor Seriale:
- la scritta: «Ha vinto» seguita dal nome del concorrente vincente (A o B);
- nella riga sotto il punteggio dei due concorrenti, da quando lo sketch è stato caricato o dall'ultimo reset.
Bisogna considerare la possibilità di aggiungere in futuro un display a cristalli liquidi per visualizzare, oltre al vincitore della prova e ai punteggi dei concorrenti, anche il tempo del vincitore e il record.
Soluzione
Si fanno le seguenti scelte hardware.
- pulsanti:
PA (pulsante concorrente A) → pin 13;
PB → pin 0;
Pstart → pin 8
- LED:
LA (LED concorrente A) → pin 10;
LB → pin 6;
Lverde → pin 7
- Buzzer → pin 9
La scelta dei pin tiene conto di una possibile espansione con un display LCD, per il quale si riservano i pin (12, 11, 5, 4, 3, 2), e del fatto che utilizzando il Monitor Seriale solo in TX (pin 1) da Arduino al computer, il pin 0 (RX se riale) può essere collegato al pulsante PB senza conflitto. Analizziamo lo sketch:
/*
Gara di riflessi
3 pulsanti, 3 LED, 1 Buzzer
Risultati su Monitor Seriale
*/
const int pinPA=13; // pin 13 pulsante concorrente A
const int pinPB=0; // pin 0 pulsante concorrente B
const int pinPstart=8; // pin 8 pulsante start
const int pinBuzzer=9; // pin 9 Buzzer
const int pinLA=10; // pin 10 LED concorrente A
const int pinLB=6; // pin 6 LED concorrente B
const int pinLverde=7; // pin 7 LED verde
bool PA; // stato del pulsante A
bool PB; // stato del pulsante B
bool Pstart; // stato del pulsante Start
int totWinA=0; // contatore vittorie concorrente A
int totWinB=0; // contatore vittorie concorrente B
int nota; // frequenza della nota del vincitore
void setup(){
pinMode(pinPA, INPUT_PULLUP); // pin digitale 13 input (pull-up interno)
pinMode(pinPB, INPUT_PULLUP); // pin digitale 0 input (pull-up interno)
pinMode(pinPstart, INPUT_PULLUP); // pin digitale 8 input (pull-up interno)
pinMode(pinBuzzer, OUTPUT); // pin digitale 9 output (Buzzer)
pinMode(pinLA, OUTPUT); // pin digitale 10 output
pinMode(pinLB, OUTPUT); // pin digitale 6 output
pinMode(pinLverde, OUTPUT); // pin digitale 7 output
randomSeed(analogRead(0)); // inizializza la funzione random, leggendo del rumore
// sul pin scollegato analog input 0
Serial.begin(9600); // apri la porta seriale alla velocità di 9600 bps
}
void loop(){
digitalWrite(pinLverde, HIGH); // accendi il LED verde
do{
Pstart = digitalRead(pinPstart); // leggi il pulsante Start
} while (Pstart==1); // finchè il pulsante Start non è premuto
digitalWrite(pinLverde, LOW); // spegni il LED verde
delay(random(3000, 8000)); // attendi un tempo casuale tra 3 s e 8 s
PA = digitalRead(pinPA); // leggi il pulsante PA
PB = digitalRead(pinPB); // leggi il pulsante PB
tone (pinBuzzer, 262); // suona la nota Do (262 Hz)
digitalWrite(pinLverde, HIGH); // riaccendi il LED verde
if(PA==0 || PB==0) { //se uno dei due concorrenti ha premuto in anticipo
if(PA==0 && PB==1) vincitore(pinLB); //se PA è già premuto vince B (chiama la function "vincitore")
if(PA==1 && PB==0) vincitore(pinLA); //se PB è già premuto vince A (chiama la function "vincitore")
if(PA==0 && PB==0) Serial.println("Gara non valida"); // se entrambi hanno premuto in anticipo
}
else { // se è tutto regolare aspetta la prima pressione
do {
PA = digitalRead(pinPA); // leggi il pulsante PA
PB = digitalRead(pinPB); // leggi il pulsante PB
} while(PA && PB); // finchè non viene premuto un pulsante
if(PA==0) vincitore(pinLA); // se P1 è premuto vince A (chiama la function "vincitore")
if(PB==0) vincitore(pinLB); // se P2 è premuto vince B (chiama la function "vincitore")
}
noTone (pinBuzzer); // spegni il buzzer
}
void vincitore (int winner){ // FUNCTION che esegue le operazioni relative al vincitore;
// il pin del LED è passato e associato al parametro winner
digitalWrite(pinLverde, LOW); // spegni il LED verde
if(winner==pinLA){ // se ha vinto A
Serial.println("Ha vinto A"); // scrivi sul serial Monitor "Ha vinto A"
totWinA++; // incrementa i punti di A
nota=440; // assegna alla variabile nota il valore 440 (LA)
}
if(winner==pinLB){ // se ha vinto B
Serial.println("Ha vinto B"); // scrivi sul serial Monitor "Ha vinto B"
totWinB++; // incrementa i punti di B
nota=587; // assegna alla variabile nota il valore 587 (RE)
}
// scrivi sul serial monitor i punti totali di A e di B
Serial.print("Punti totali A:");
Serial.print(totWinA);
Serial.print(" B:");
Serial.println(totWinB);
// fai lampeggiare il LED e suona la nota del vincitore, per 5 volte
for(int cont =1; cont<=5; cont++){ // per 5 volte
tone (pinBuzzer, nota); // suona la nota del vincitore
digitalWrite(winner, HIGH); // accendi il LED del vincitore
delay(500); // aspetta 500 ms
noTone (pinBuzzer); // interrompi la nota
digitalWrite(winner, LOW); // spegni il LED
delay(500); // aspetta 500 ms
}
}
Nella prima parte dello sketch puoi notare, oltre alle varie definizioni e inizializzazioni, l'istruzione
randomSeed(analogRead(0));
che serve ad inizializzare la funzione random, usata nel loop per genera re un tempo casuale tra 3 s e 8 s: analogRead(0) legge la tensione presente sul pin analog input 0, che, essendo scollegato, sarà un valore casuale dovuto al rumore captato sul pin 0.
La seconda parte dello sketch è la funzione loop():
- i commenti descrivono il flusso del programma, che evolve come richiesto dalle specifiche;
- si può notare l'uso della funzione random, come parametro dell'istruzione delay, per ottenere un ritardo casuale, compreso tra 3000 ms e 8000 ms, random(min, max) va usata abbinata a randomSeed(analogRead(0)), contenuta in setup, per ottenere un numero casuale tra i valori min e max;
- nell'istruzione if (PA==| | PB==0), il simbolo realizza la funzione logica OR tra le due espressioni: il risultato è VERO se almeno una delle due è VERA, cioè se almeno un concorrente ha premuto (A o B);
- nell'istruzione if (PA==0 && PB==1), il simbolo && realizza la funzione logica AND tra le due espressioni: il risultato è VERO se le espressioni sono entrambe VERE, cioè se A ha premuto durante il suono mentre B non premeva (quindi vince B);
- notare che in entrambe le istruzioni if le graffe non sono necessarie perché il blocco è di una sola riga;
- in vari punti dello sketch si nomina vincitore(): questa è una chiamata alla function vincitore, definita nella terza parte dello sketch, alla quale si comunica (con il parametro tra parentesi) il pin del LED del vincitore (pinLA o pinLB). La function farà lampeggiare tale LED e altre operazioni relative al vincitore della sfida.
La terza porzione di sketch è costituita dalla function vincitore, scritta fuori dalla funzione loop().
La function vincitore, quando viene nominata nel loop(), esegue le seguenti operazioni:
- riceve il pin del LED del vincitore (pinLA o pinB) e lo associa alla variabile winner;
- scrive sul Monitor chi ha vinto e poi incrementa il contatore dei punti del vincitore;
- scrive sul Monitor i punti totali di A e B;
- fa suonare il buzzer (con note diverse per ciascun concorrente) e fa lampeggiare il LED del vincitore in modo sincrono per 5 volte.
Poi l'esecuzione del programma ritorna al loop() e prosegue dal punto successivo a quello in cui è stata chiamata la function. Nota l'uso delle istruzioni Serial.print() e Serial.println(), per comporre sul Monitor Seriale le scritte richieste.
Pagina 5 di 6