Arduino Simon
I My son got a great Xmas present in the shape of a Starter Kit for Arduino from Oomlout. After doing some of the basic projects I decided we needed something that we could get our teeth into. After a little pondering Simon came out as a worthwhile challenge. Back in the 80s I’d written a version of Simon that was published in Commodore Computing International, so I thought it would be fun to do a hardware version. A bit of poking around the web revealed that this has been done before, but I decided to start from scratch rather than copying the design and code from others (otherwise where’s the fun?).
I expected that this would be a project that might take a few weekends of tinkering, but in the end I had a playable system done in around 90 minutes. Arduino/Processing is a really productive environment, especially if you’re already familiar with electronics prototyping and a bit of C.
The electronics
- Lights – 4 LEDs (Red, Green, Yellow and Blue) between digital output pins and ground with appropriate series resistors.
- Sound – a piezo buzzer between a digital output pin and ground.
- Buttons – 4 – between ground and digital inputs. Right now I have 10k pull up resistors, but they’re probably not necessary. Tip – twist the legs of PCB mount buttons through 90 degrees to stop them pinging out of the breadboard.
The code
I’ll let the code speak for itself, but I’ve put it at the bottom to avoid breaking the flow of things[1]. Update 17 Jan – the original code is below, but revised code is on github.
Todo
- Change the tones so that the match up with the original Simon.
- Check for when a correct sequence of 20 is entered, and do some sort of winning ritual (right now the array will just overflow).
- Resequence the inputs. Blue was on Pin 13, but that was before I discovered that Pin 13 is special.
- Make use of the internal pull up resistors for the buttons (and ditch the 10K ones on the board).
- Progressively speed things up when the sequence gets longer.
- Put the code up on Github.
And then
The kids have really got into playing with this, so I’ve bought some components to transfer things onto a more permanent stripboard based version.
I’m also tempted to see if I can transfer things over to an MSP430 based microcontroller. That would be much cheaper to make a permanent toy out of (especially since TI send out free samples), but it brings with it the extra challenge of having to multiplex inputs and outputs as the MSP430s aren’t graced with the number of pins found on Arduino’s ATMega chip. This would probably involve Charlieplexing the LEDs and coming up with a resistor ladder for input.
Update 22 Jan – I did some follow up posts covering the stripboard build and with some diagrams of the original.
[1] The code:
const int led_red = 1; // Output pins for the LEDs const int led_green = 2; const int led_yellow = 3; const int led_blue = 4; const int buzzer = 5; // Output pin for the buzzer const int red_button = 10; // Input pins for the buttons const int green_button = 11; const int yellow_button = 12; const int blue_button = 9; // Pin 13 is special - didn't work as planned long sequence[20]; // Array to hold sequence int count = 0; // Sequence counter long input = 5; // Button indicator /* playtone function taken from Oomlout sample takes a tone variable that is half the period of desired frequency and a duration in milliseconds */ void playtone(int tone, int duration) { for (long i = 0; i < duration * 1000L; i += tone *2) { digitalWrite(buzzer, HIGH); delayMicroseconds(tone); digitalWrite(buzzer, LOW); delayMicroseconds(tone); } } /* functions to flash LEDs and play corresponding tones very simple - turn LED on, play tone for .5s, turn LED off */ void flash_red() { digitalWrite(led_red, HIGH); playtone(1915,500); digitalWrite(led_red, LOW); } void flash_green() { digitalWrite(led_green, HIGH); playtone(1700,500); digitalWrite(led_green, LOW); } void flash_yellow() { digitalWrite(led_yellow, HIGH); playtone(1519,500); digitalWrite(led_yellow, LOW); } void flash_blue() { digitalWrite(led_blue, HIGH); playtone(1432,500); digitalWrite(led_blue, LOW); } // a simple test function to flash all of the LEDs in turn void runtest() { flash_red(); flash_green(); flash_yellow(); flash_blue(); } /* a function to flash the LED corresponding to what is held in the sequence */ void squark(long led) { switch (led) { case 0: flash_red(); break; case 1: flash_green(); break; case 2: flash_yellow(); break; case 3: flash_blue(); break; } delay(50); } // function to build and play the sequence void playSequence() { sequence[count] = random(4); // add a new value to sequence for (int i = 0; i < count; i++) { // loop for sequence length squark(sequence[i]); // flash/beep } count++; // increment sequence length } // function to read sequence from player void readSequence() { for (int i=1; i < count; i++) { // loop for sequence length while (input==5){ // wait until button pressed if (digitalRead(red_button) == LOW) { // Red button input = 0; } if (digitalRead(green_button) == LOW) { // Green button input = 1; } if (digitalRead(yellow_button) == LOW) { // Yellow button input = 2; } if (digitalRead(blue_button) == LOW) { // Blue button input = 3; } } if (sequence[i-1] == input) { // was it the right button? squark(input); // flash/buzz } else { playtone(3830,1000); // low tone for fail squark(sequence[i-1]); // double flash for the right colour squark(sequence[i-1]); count = 0; // reset sequence } input = 5; // reset input } } // standard sketch setup function void setup() { pinMode(led_red, OUTPUT); // configure LEDs and buzzer on outputs pinMode(led_green, OUTPUT); pinMode(led_yellow, OUTPUT); pinMode(led_blue, OUTPUT); pinMode(buzzer, OUTPUT); pinMode(red_button, INPUT); // configure buttons on inputs pinMode(green_button, INPUT); pinMode(yellow_button, INPUT); pinMode(blue_button, INPUT); randomSeed(analogRead(5)); // random seed for sequence generation //runtest(); } // standard sketch loop function void loop() { playSequence(); // play the sequence readSequence(); // read the sequence delay(1000); // wait a sec }
Filed under: Arduino, howto, making | 4 Comments
Tags: arduino, breadboard, button, buzzer, code, electronics, game, LED, pin 13, Simon
Chris,
That’s pretty cool. How old is your son now?
I got the main board as a Christmas present also, but haven’t fired it up yet.
Nick
He’s turning 11 soon. You should definitely get started with your board, though I’m surprised you didn’t lean toward a Netduino ;-)
Fun post. Thank you!
The updated source is now up on github.