Here is the slides, a video and the source code from a 15 minute speed-talk I did for the Tech Talk Tuesday at OSAA yesterday.
It shows the highlights of how to build a clone of the classic Simon game, using an Arduino and some buttons and LEDs. In Danish only!
Slides
View more presentations from giddy.
The Video Demonstration
Source Code
/*
* Arduino Clone of the classic Simon Game
*
* Made at Hack Aarhus / OSAA
* http://www.hackaarhus.dk
* http://www.osaa.dk
*
* Released into the public domain by
* Rene Hangstrup Moeller, July 2010
*
* http://www.giddyplanet.com
*/
//---------------------------------------------------------
// GLOBALS weeeee!
//=========================================================
// the number of leds/switches
int SIZE = 4;
// milliseconds delay between each element in the sequence
int PLAY_DELAY = 250;
int INPUT_DELAY = 200;
// the sequence
int sequence[128];
// current sequence length
int seqlen = 0;
// Sound frequencies for each led-switch pair
int notes[] = {
261/2, 392/2, 587/2, 880/2
};
//---------------------------------------------------------
// PIN MAPPINGS
//=========================================================
// the buzzer control pin
int buzzPin = 11;
// calculate pin for led
int ledPin(int num) {
return (num + 1) * 2;
}
// calculate pin for button
int buttonPin(int num) {
return ledPin(num) + 1;
}
//---------------------------------------------------------
// HELPER FUNCTIONS
//=========================================================
// mute the buzzer and turn off all leds
void turnOff() {
noTone(buzzPin);
for (int n = 0; n < SIZE; n++) {
digitalWrite(ledPin(n), LOW);
}
}
// new game
void newGame() {
// generate random sequence with two entries
sequence[0] = random(SIZE);
sequence[1] = random(SIZE);
seqlen = 2;
// blink leds 10 times to indicate game start
for (int i = 0; i < 10; i++) {
for (int n = 0; n < SIZE; n++) {
digitalWrite(ledPin(n), HIGH);
}
delay(200);
turnOff();
delay(200);
}
}
// add an entry to the sequence
void expand() {
sequence[seqlen++] = random(SIZE);
}
// play the sequence
void playSequence() {
Serial.println("Playing sequence");
for (int i = 0; i < seqlen; i++) {
int v = sequence[i];
tone(buzzPin, notes[v]);
for (int n = 0; n < SIZE; n++) {
digitalWrite(ledPin(n), n == v ? HIGH : LOW);
}
delay(PLAY_DELAY);
noTone(buzzPin);
for (int n = 0; n < SIZE; n++) {
digitalWrite(ledPin(n), LOW);
}
delay(PLAY_DELAY);
}
turnOff();
}
// wait for button press
int nextButton() {
while (true) {
for (int n = 0; n < SIZE; n++) {
if (digitalRead(buttonPin(n)) == HIGH) {
digitalWrite(ledPin(n), HIGH);
while (digitalRead(buttonPin(n)) == HIGH) {
delay(INPUT_DELAY);
}
turnOff();
return n;
}
}
delay(INPUT_DELAY);
}
return 0; // never
}
// read sequence from player
int readSequence() {
for (int i = 0; i < seqlen; i++) {
int nb = nextButton();
if (nb != sequence[i]) {
Serial.println("Error");
return false;
}
}
Serial.println("Accepted");
return true;
}
//---------------------------------------------------------
// ARDUINO ENTRY POINTS
//=========================================================
// initialize the Arduino
void setup() {
// initialize random number sequence
randomSeed(micros() + analogRead(0));
// configure pins for LEDs and buttons
for (int i = 0; i < SIZE; i++) {
pinMode(ledPin(i), OUTPUT);
pinMode(buttonPin(i), INPUT);
}
// configure pin for sound
pinMode(buzzPin, OUTPUT);
// initialize serial communication for debugging
Serial.begin(9600);
Serial.println("Setup completed. Welcome to Simon");
}
// The game loop - each run corresponds to a game
void loop() {
Serial.println("Starting new game");
newGame();
int running = true;
while (running) {
delay(1000);
playSequence();
running = readSequence();
if (running) {
expand();
}
}
delay(250);
}