Questo progetto mostra come replicare con Arduino, il gioco Simon Says, utilizzando poche componenti base.
Lo scopo del gioco, è riuscire a ricordare la sequenza di accensione corretta dei LED (decisa da Arduino) per il maggior numero di turni.

Materiale utilizzato

Arduino UNO R3
– 1x breadboard
– 4x LED colorati
– 4x pulsanti pushbutton
– 4x resistenze da 100\330 ohm (valore in base al colore dei LED)
– 1x altoparlante (in alternativa un buzzer)

Iniziamo a costruire il circuito sulla breadboard come in figura:

SimonSays2

1) Posizioniamo i pulsanti al centro della breadboard, da un lato collegati a massa, e dall’altro ai pin digitali di Arudino (2,3,4,5)
2) Posizioniamo un LED vicino ad ogni pulsante, collegando il catodo dalla parte dove abbiamo il negativo del pushbutton
3) Posizioniamo le resistenze su ogni LED, un capo collegato all’anodo e l’altro capo ai pin digitali di Arduino (8,9,10,11)
4) Colleghiamo l’altoparlante (o buzzer) al pin digitale 12 e a massa (generalmente i buzzer hanno il simbolo ‘+’ impresso sopra per distinguere il verso)

SimonSays1

Il circuito è finito, carichiamo ora lo sketch su Arduino e verifichiamone il funzionamento.

***  Per il corretto funzionamento e compilazione dello Sketch è necessario installare la libreria Tone,
***  per farlo è sufficiente copiare la cartella Tone nel percorso ‘libraries’ dove è installato l’IDE di Arduino
***  e riavviare il programma.

Il codice è così suddiviso:

Parte iniziale

Viene inclusa la libreria Tone.h e definite le variabili globali del programma.

Setup()

Viene inizializzata la comunicazione seriale, definito il pin dell’altoparlante, i pin dei led, i pin dei pulsanti, ‘randomizzato’ il generatore random, e fatta partire una musichetta iniziale con accensione dei led a seguito.

***   Il comando randomSeed() inizializza il generatore di numeri pseudo-casuali,
***  facendolo iniziare in un punto arbitrario nella sua sequenza casuale. 

***  Questa sequenza anche se molto lunga è sempre la stessa, per questo lo si inizializza passando il valore
***  di un analogRead(), rendendo così la sequenza abbastanza casuale.
Loop()

All’interno del loop, vengono gestite:

– Inizio partita
– Inizio turno
– Calcolo singolo step sequenza
– Attesa input dell’utente

Input()

In questa funzione si effettua il confronto tra i pulsanti che preme l’utente e la sequenza decisa da Arduino, se ok si prosegue altrimenti si richiama la funzione Fail()

Fail()

Questa funzione fa lampeggiare i led ed emette un suono per far capire all’utente che la sequenza inserita è errata. Fa inoltre ricominciare il gioco impostando la variabile turn a -1

***  Durante l’esecuzione del programma, nel serial monitor compariranno tutti i vari stati,
***  compresa la sequenza da inserire 😀

DOWNLOAD RAR CODICE + LIBRERIA

#include <Tone.h>
Tone speakerpin;
int starttune[] = {NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_F4, NOTE_G4};
int duration2[] = {100, 200, 100, 200, 100, 400, 100, 100, 100, 100, 200, 100, 500};
int note[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5};
int duration[] = {100, 100, 100, 300, 100, 300};
byte button[] = {2, 3, 4, 5};
byte ledpin[] = {8, 9, 10, 11};  
int turn = 0;  
int buttonstate = 0;  
int randomArray[100]; 
int inputArray[100];  


void setup() 
{
  Serial.begin(9600);
  speakerpin.begin(12); 
  
  for(int x=0; x<4; x++)  
  {
    pinMode(ledpin[x], OUTPUT);
  }
  
  for(int x=0; x<4; x++) 
  {
    pinMode(button[x], INPUT); 
    digitalWrite(button[x], HIGH); 
  }

  randomSeed(analogRead(0)); 
  for (int thisNote = 0; thisNote < 13; thisNote ++) {
    
     speakerpin.play(starttune[thisNote]);

     if (thisNote==0 || thisNote==2 || thisNote==4 || thisNote== 6)
     {
       digitalWrite(ledpin[0], HIGH);
     }
     if (thisNote==1 || thisNote==3 || thisNote==5 || thisNote== 7 || thisNote==9 || thisNote==11)
     {
       digitalWrite(ledpin[1], HIGH);
     }
     if (thisNote==8 || thisNote==12)
     {
       digitalWrite(ledpin[2], HIGH);
     }  
     if (thisNote==10)
     {   
       digitalWrite(ledpin[3], HIGH);
     }
     delay(duration2[thisNote]);

     speakerpin.stop();
     digitalWrite(ledpin[0], LOW);
     digitalWrite(ledpin[1], LOW);
     digitalWrite(ledpin[2], LOW);
     digitalWrite(ledpin[3], LOW);
     delay(25);
    }
  delay(1000);
}
 
void loop() 
{   
  for (int y=0; y<=99; y++)
  {

    digitalWrite(ledpin[0], HIGH);
    digitalWrite(ledpin[1], HIGH);
    digitalWrite(ledpin[2], HIGH);
    digitalWrite(ledpin[3], HIGH);
  
    for (int thisNote = 0; thisNote < 6; thisNote ++) {
   
     speakerpin.play(note[thisNote]);
  
     delay(duration[thisNote]);
  
     speakerpin.stop();
     delay(25);
    }
    
    digitalWrite(ledpin[0], LOW);
    digitalWrite(ledpin[1], LOW);
    digitalWrite(ledpin[2], LOW);
    digitalWrite(ledpin[3], LOW);
    delay(1000);
  
    for (int y=turn; y <= turn; y++)
    {
      Serial.println(""); 
      Serial.print("Turn: ");
      Serial.print(y);
      Serial.println("");
      randomArray[y] = random(1, 5); 
      for (int x=0; x <= turn; x++)
      {
        Serial.print(randomArray[x]);
      
        for(int y=0; y<4; y++)
        {
      
          if (randomArray[x] == 1 && ledpin[y] == 8) 
          {  
            digitalWrite(ledpin[y], HIGH);
            speakerpin.play(NOTE_G3, 100);
            delay(400);
            digitalWrite(ledpin[y], LOW);
            delay(100);
          }

          if (randomArray[x] == 2 && ledpin[y] == 9) 
          {
            digitalWrite(ledpin[y], HIGH);
            speakerpin.play(NOTE_A3, 100);
            delay(400);
            digitalWrite(ledpin[y], LOW);
            delay(100);
          }
  
          if (randomArray[x] == 3 && ledpin[y] == 10) 
          {
            digitalWrite(ledpin[y], HIGH);
            speakerpin.play(NOTE_B3, 100);
            delay(400);
            digitalWrite(ledpin[y], LOW);
            delay(100);
          }

          if (randomArray[x] == 4 && ledpin[y] == 11) 
          {
            digitalWrite(ledpin[y], HIGH);
            speakerpin.play(NOTE_C4, 100);
            delay(400);
            digitalWrite(ledpin[y], LOW);
            delay(100);
          }
        }
      }
    }
    input();
  }
}
 
 
 
void input() { 

  for (int x=0; x <= turn;)
  { 

    for(int y=0; y<4; y++)
    {
      
      buttonstate = digitalRead(button[y]);
    
      if (buttonstate == LOW && button[y] == 2)
      {
        digitalWrite(ledpin[0], HIGH);
        speakerpin.play(NOTE_G3, 100);
        delay(200);
        digitalWrite(ledpin[0], LOW);
        inputArray[x] = 1;
        delay(250);
        Serial.print(" ");
        Serial.print(1);
        if (inputArray[x] != randomArray[x]) {
          fail();                              
        }                                     
        x++;
      }
       if (buttonstate == LOW && button[y] == 3)
      {
        digitalWrite(ledpin[1], HIGH);
        speakerpin.play(NOTE_A3, 100);
        delay(200);
        digitalWrite(ledpin[1], LOW);
        inputArray[x] = 2;
        delay(250);
        Serial.print(" ");
        Serial.print(2);
        if (inputArray[x] != randomArray[x]) {
          fail();
        }
        x++;
      }

      if (buttonstate == LOW && button[y] == 4)
      {
        digitalWrite(ledpin[2], HIGH);
        speakerpin.play(NOTE_B3, 100);
        delay(200);
        digitalWrite(ledpin[2], LOW);
        inputArray[x] = 3;
        delay(250);
        Serial.print(" ");
        Serial.print(3);
        if (inputArray[x] != randomArray[x]) {
          fail();
        }
        x++;
      }

      if (buttonstate == LOW && button[y] == 5)
      {
        digitalWrite(ledpin[3], HIGH);
        speakerpin.play(NOTE_C4, 100);
        delay(200);
        digitalWrite(ledpin[3], LOW);
        inputArray[x] = 4;
        delay(250);
        Serial.print(" ");
        Serial.print(4);
        if (inputArray[x] != randomArray[x]) 
        {
          fail();
        }
        x++;
      }
    }
  }
  delay(500);
  turn++; 
}

void fail() { 
 
  for (int y=0; y<=2; y++)
  { //Flashes lights for failure
    
    digitalWrite(ledpin[0], HIGH);
    digitalWrite(ledpin[1], HIGH);
    digitalWrite(ledpin[2], HIGH);
    digitalWrite(ledpin[3], HIGH);
    speakerpin.play(NOTE_G3, 300);
    delay(200);
    digitalWrite(ledpin[0], LOW);
    digitalWrite(ledpin[1], LOW);
    digitalWrite(ledpin[2], LOW);
    digitalWrite(ledpin[3], LOW);
    speakerpin.play(NOTE_C3, 300);
    delay(200);
  }
  delay(500);
  turn = -1;
}
Considerazioni finali

Spero che questo progetto possa essere utile sia per chi inizia con Arduino, sia per chi ha già un po di esperienza, e vuole partire da un progetto e modificarlo a suo piacimento, si potrebbero infatti aggiungere altri pulsanti e led, aumentare la velocità, mostrare il numero del turno su un display, ecc ecc.. il limite è solo la fantasia.

Enrico Mazzalovo