Instructables

Arduino Simon Says

Step 2: The Sketch

The sketch was originally made by Robert Spann back in 2009. I used an earlier version of his sketch since i didn't like the way he integrated sound in later versions of the sketch. To give the game sound i decided to use the Tone.h Library. The Library hasn't been updated since the release of Arduino 1.0, so i went ahead and updated it to be compatible with Arduino 1.0. In doing so i cut out any backwards compatibility with older IDEs. So if your running an older version of the IDE then used the link in the next step to download the original library. I've attached a copy of the updated library on this page. So be sure to download it and place it in your Arduino/Libraries folder or the sketch will not compile under Arduino 1.0.

Here is the Sketch. A file of the sketch is also attached. If there are any questions about it please let me know. 
/*Simon Says game. Now with sound effects.

Originaly made by Robert Spann
Code trimmed and sound effects added by digimike

Buttons are to be set on there designated pins without pull down resistors
and connected to ground rather then +5.
*/
#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};
boolean button[] = {2, 3, 4, 5}; //The four button input pins
boolean ledpin[] = {8, 9, 10, 11};  // LED pins
int turn = 0;  // turn counter
int buttonstate = 0;  // button state checker
int randomArray[100]; //Intentionally long to store up to 100 inputs (doubtful anyone will get this far)
int inputArray[100]; 


void setup()
{
  Serial.begin(9600);
  speakerpin.begin(12); // speaker is on pin 13

  for(int x=0; x<4; x++)  // LED pins are outputs
  {
    pinMode(ledpin[x], OUTPUT);
  }
 
  for(int x=0; x<4; x++)
  {
    pinMode(button[x], INPUT);  // button pins are inputs
    digitalWrite(button[x], HIGH);  // enable internal pullup; buttons start in high position; logic reversed
  }

  randomSeed(analogRead(0)); //Added to generate "more randomness" with the randomArray for the output function
  for (int thisNote = 0; thisNote < 13; thisNote ++) {
     // play the next note:
     speakerpin.play(starttune[thisNote]);
     // hold the note:
     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]);
     // stop for the next note:
     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++)
  {
    //function for generating the array to be matched by the player
    digitalWrite(ledpin[0], HIGH);
    digitalWrite(ledpin[1], HIGH);
    digitalWrite(ledpin[2], HIGH);
    digitalWrite(ledpin[3], HIGH);
 
    for (int thisNote = 0; thisNote < 6; thisNote ++) {
     // play the next note:
     speakerpin.play(note[thisNote]);
     // hold the note:
     delay(duration[thisNote]);
     // stop for the next note:
     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++)
    { //Limited by the turn variable
      Serial.println(""); //Some serial output to follow along
      Serial.print("Turn: ");
      Serial.print(y);
      Serial.println("");
      randomArray[y] = random(1, 5); //Assigning a random number (1-4) to the randomArray[y], y being the turn count
      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)
          {  //if statements to display the stored values in the array
            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() { //Function for allowing user input and checking input against the generated array

  for (int x=0; x <= turn;)
  { //Statement controlled by turn count

    for(int y=0; y<4; y++)
    {
     
      buttonstate = digitalRead(button[y]);
   
      if (buttonstate == LOW && button[y] == 2)
      { //Checking for button push
        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]) { //Checks value input by user and checks it against
          fail();                              //the value in the same spot on the generated array
        }                                      //The fail function is called if it does not match
        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++; //Increments the turn count, also the last action before starting the output function over again
}

void fail() { //Function used if the player fails to match the sequence

  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; //Resets turn value so the game starts over without need for a reset button
}
 
Remove these adsRemove these ads by Signing Up
mpilchfamily (author) 1 year ago
As the instructions say on the previous step the pin wire was connected to pin 12. The notation is off here but if you want the speaker on pin 13 then put it there and change the sketch as needed.
jhsa1404671 year ago
Hi, I think you have a mistake here..
"speakerpin.begin(12); // speaker is on pin 13"
I think it should be 13 instead of 12??
(removed by author or community request)
mpilchfamily (author)  fgonzalez141 year ago
Are you only seeing errors for the speakerpin and none for notes? These are the kinds of things you see when the library isn't in the correct folder. Make sure you have put it in the correct folder. If the IDE is using a different Arduino folder that is in a different location on your HDD then you'll get these errors. Double check you have the library in the library folder that is in the arduino folder.
@mpilchfamily

Yeah i have now thank you, the instructions i was given on how to install to the library were far from clear, code is working fine and i will be assembling tommorow. Using this for a university project, Product Design
anyone Help?

Simon:10: error: 'Tone' does not name a type
Simon:11: error: 'NOTE_C4' was not declared in this scope
Simon:11: error: 'NOTE_F4' was not declared in this scope
Simon:11: error: 'NOTE_C4' was not declared in this scope
Simon:11: error: 'NOTE_F4' was not declared in this scope
Simon:11: error: 'NOTE_C4' was not declared in this scope
Simon:11: error: 'NOTE_F4' was not declared in this scope
Simon:11: error: 'NOTE_C4' was not declared in this scope
Simon:11: error: 'NOTE_F4' was not declared in this scope
Simon:11: error: 'NOTE_G4' was not declared in this scope
Simon:11: error: 'NOTE_F4' was not declared in this scope
Simon:11: error: 'NOTE_E4' was not declared in this scope
Simon:11: error: 'NOTE_F4' was not declared in this scope
Simon:11: error: 'NOTE_G4' was not declared in this scope
Simon:13: error: 'NOTE_C4' was not declared in this scope
Simon:13: error: 'NOTE_C4' was not declared in this scope
Simon:13: error: 'NOTE_G4' was not declared in this scope
Simon:13: error: 'NOTE_C5' was not declared in this scope
Simon:13: error: 'NOTE_G4' was not declared in this scope
Simon:13: error: 'NOTE_C5' was not declared in this scope
Simon.ino: In function 'void setup()':
Simon:26: error: 'speakerpin' was not declared in this scope
Simon.ino: In function 'void loop()':
Simon:84: error: 'speakerpin' was not declared in this scope
Simon:115: error: 'speakerpin' was not declared in this scope
Simon:115: error: 'NOTE_G3' was not declared in this scope
Simon:124: error: 'speakerpin' was not declared in this scope
Simon:124: error: 'NOTE_A3' was not declared in this scope
Simon:133: error: 'speakerpin' was not declared in this scope
Simon:133: error: 'NOTE_B3' was not declared in this scope
Simon:142: error: 'speakerpin' was not declared in this scope
Simon:142: error: 'NOTE_C4' was not declared in this scope
Simon.ino: In function 'void input()':
Simon:169: error: 'speakerpin' was not declared in this scope
Simon:169: error: 'NOTE_G3' was not declared in this scope
Simon:184: error: 'speakerpin' was not declared in this scope
Simon:184: error: 'NOTE_A3' was not declared in this scope
Simon:200: error: 'speakerpin' was not declared in this scope
Simon:200: error: 'NOTE_B3' was not declared in this scope
Simon:216: error: 'speakerpin' was not declared in this scope
Simon:216: error: 'NOTE_C4' was not declared in this scope
Simon.ino: In function 'void fail()':
Simon:244: error: 'speakerpin' was not declared in this scope
Simon:244: error: 'NOTE_G3' was not declared in this scope
Simon:250: error: 'NOTE_C3' was not declared in this scope
mpilchfamily (author)  Ryan Carter19931 year ago
Make sure you have the tone library installed in the proper folder.
James Mc291 year ago
Hi how do play a specific sequence instead of a random one?
mpilchfamily (author)  James Mc291 year ago
The game generates an array 100 values long and adds a new number too it each turn. The array is generated durring hte void setup();. You'll see the code is noted where the random number is inserted into the array in the void loop();. In order to make this run with a pre defined array you would have to make a few small adjustments.

Just off the top of my head...
In the void setup(); you would have to change:
int randomArray[100]; //Intentionally long to store up to 100 inputs (doubtful anyone will get this far)

to be whatever array you wanted. So sothing like this:
int randomArray[]= {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x};

The x's being the value you want and however long you want it to be. If you make it longer than 100 then you'll have to update the inputArray accordingly.

Then you would have to remove the section where the random number is inserted into the array down in the void loop();.

That's just off the top of my head and you may need to do a few more tweaks to get it running right but its a start.
Taciturnn2 years ago
Thanks a lot. Lots of fun!