From 172c744f2875e025d49594dc9413a79f37e718f4 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Wed, 26 Dec 2012 16:35:35 -0700 Subject: [PATCH 1/5] Added global readme. --- readme.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 readme.txt diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..5a6bd42 --- /dev/null +++ b/readme.txt @@ -0,0 +1,3 @@ +Simon Says is an open source hardware memory game. This repo contains the firmware and hardware for the various versions SparkFun has created over the years (originally started in 2007). + +If you have feature suggestions or need support please use the github support page. \ No newline at end of file From a9b242e9b60f2048435bc3eb2a1055463c61d5ca Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Fri, 28 Dec 2012 21:49:19 -0700 Subject: [PATCH 2/5] Lots of porting to Arduino functions and standards. --- Firmware/Simon_Says/Simon_Says.ino | 503 ++++++++++++------------ Firmware/Simon_Says/hardware_versions.h | 64 +-- 2 files changed, 296 insertions(+), 271 deletions(-) diff --git a/Firmware/Simon_Says/Simon_Says.ino b/Firmware/Simon_Says/Simon_Says.ino index 5f5f0e3..ff0e3ce 100644 --- a/Firmware/Simon_Says/Simon_Says.ino +++ b/Firmware/Simon_Says/Simon_Says.ino @@ -44,32 +44,135 @@ #include "hardware_versions.h" // Define game parameters -#define MOVES_TO_WIN 13 -#define TIME_LIMIT 3000 //3000ms = 3 sec +#define MOVES_TO_WIN 13 //Number of rounds to succesfully remember before you win. 13 is do-able. +#define ENTRY_TIME_LIMIT 3000 //Amount of time to press a button before game times out. 3000ms = 3 sec -#define sbi(port_name, pin_number) (port_name |= 1< 0) { - delay_us(1000); - } -} + if ((leds & CHOICE_RED) != 0) + digitalWrite(LED_RED, HIGH); + else + digitalWrite(LED_RED, LOW); + + if ((leds & CHOICE_GREEN) != 0) + digitalWrite(LED_GREEN, HIGH); + else + digitalWrite(LED_GREEN, LOW); -//Light the given set of LEDs -void set_leds(uint8_t leds) -{ - if ((leds & LED_RED) != 0) { - sbi(LED_RED_PORT, LED_RED_PIN); - } - else { - cbi(LED_RED_PORT, LED_RED_PIN); - } - if ((leds & LED_GREEN) != 0) { - sbi(LED_GREEN_PORT, LED_GREEN_PIN); - } - else { - cbi(LED_GREEN_PORT, LED_GREEN_PIN); - } - if ((leds & LED_BLUE) != 0) { - sbi(LED_BLUE_PORT, LED_BLUE_PIN); - } - else { - cbi(LED_BLUE_PORT, LED_BLUE_PIN); - } - if ((leds & LED_YELLOW) != 0) { - sbi(LED_YELLOW_PORT, LED_YELLOW_PIN); - } - else { - cbi(LED_YELLOW_PORT, LED_YELLOW_PIN); - } + if ((leds & CHOICE_BLUE) != 0) + digitalWrite(LED_BLUE, HIGH); + else + digitalWrite(LED_BLUE, LOW); + + if ((leds & CHOICE_YELLOW) != 0) + digitalWrite(LED_YELLOW, HIGH); + else + digitalWrite(LED_YELLOW, LOW); } @@ -154,93 +245,75 @@ void init_gpio(void) PORTB = 0b00000011; // Enable pull-ups on buttons 2, 3 PORTD = 0b11000000; // Enable pull-up on button 0, 1 } -#endif // End BOARD_REV_4_9_2009 +#endif // End BOARD_REV_4_9_2009 #ifdef BOARD_REV_PTH void init_gpio(void) { - // 1 = output, 0 = input - DDRB = 0b11101101; // LEDs and Buttons - DDRC = 0b11111111; // LEDs and Buttons - DDRD = 0b10111011; // LEDs, buttons, buzzer, TX/RX + //Enable pull ups on inputs + pinMode(BUTTON_RED, INPUT_PULLUP); + pinMode(BUTTON_GREEN, INPUT_PULLUP); + pinMode(BUTTON_BLUE, INPUT_PULLUP); + pinMode(BUTTON_YELLOW, INPUT_PULLUP); - PORTB = 0b00010010; // Enable pull-ups on buttons 1, 4 - //PORTC = 0b00100110; // Enable pull-ups on buttons 0, 2, 3 - PORTD = 0b01000100; // Enable pull-up on button 1 + pinMode(LED_RED, OUTPUT); + pinMode(LED_GREEN, OUTPUT); + pinMode(LED_BLUE, OUTPUT); + pinMode(LED_YELLOW, OUTPUT); + + pinMode(BUZZER1, OUTPUT); + pinMode(BUZZER2, OUTPUT); } -#endif +#endif // End BOARD_REV_PTH -void ioinit(void) +// Returns a '1' bit in the position corresponding to CHOICE_RED, CHOICE_GREEN, etc. +byte checkButton(void) { - init_gpio(); + byte buttonPressed = CHOICE_NONE; - //Set Timer 0 Registers to Default Setting to over-ride the timer initialization made in the init() function of the \ - //Arduino Wiring library (Wiring.c in the hardware/core/arduino folder) - TCCR0A = 0; - TIMSK0 = 0; - // Init timer 0 for delay_us timing (1,000,000 / 1 = 1,000,000) - //TCCR0B = (1< 70; x--) { - for (y = 0; y < 3; y++) { - sbi(BUZZER2_PORT, BUZZER2); - cbi(BUZZER1_PORT, BUZZER1); + for (x = 250 ; x > 70 ; x--) { + for (y = 0 ; y < 3 ; y++) { + //sbi(BUZZER2_PORT, BUZZER2); + //cbi(BUZZER1_PORT, BUZZER1); + digitalWrite(BUZZER2, HIGH); + digitalWrite(BUZZER1, LOW); + delayMicroseconds(x); - delay_us(x); - - cbi(BUZZER2_PORT, BUZZER2); - sbi(BUZZER1_PORT, BUZZER1); - - delay_us(x); + //cbi(BUZZER2_PORT, BUZZER2); + //sbi(BUZZER1_PORT, BUZZER1); + digitalWrite(BUZZER2, LOW); + digitalWrite(BUZZER1, HIGH); + delayMicroseconds(x); } } } @@ -248,36 +321,33 @@ void winner_sound(void) // Play the winner sound and lights void play_winner(void) { - set_leds(LED_GREEN|LED_BLUE); + setLEDs(CHOICE_GREEN|CHOICE_BLUE); winner_sound(); - set_leds(LED_RED|LED_YELLOW); + setLEDs(CHOICE_RED|CHOICE_YELLOW); winner_sound(); - set_leds(LED_GREEN|LED_BLUE); + setLEDs(CHOICE_GREEN|CHOICE_BLUE); winner_sound(); - set_leds(LED_RED|LED_YELLOW); + setLEDs(CHOICE_RED|CHOICE_YELLOW); winner_sound(); } // Plays the current contents of the game moves void play_moves(void) { - uint8_t move; + byte currentMove; - for (move = 0; move < nmoves; move++) { - toner(moves[move], 150); - delay_ms(150); + for (currentMove = 0 ; currentMove < nmoves ; currentMove++) + { + toner(moves[currentMove], 150); + delay(150); } } // Adds a new random button to the game sequence, by sampling the timer void add_to_moves(void) { - uint8_t new_button; - - // Use the lower 2 bits of the timer for the random value - new_button = 1 << (TCNT2 & 0x3); - - moves[nmoves++] = new_button; + byte newButton = random(0, 3); + moves[nmoves++] = newButton; //Add this new button to the game array } // Adds a user defined button to the game sequence, by waiting for their input @@ -294,6 +364,7 @@ void add_to_moves_battle(void) } // Toggle buzzer every buzz_delay_us, for a duration of buzz_length_ms. +//Given a length and a void buzz_sound(uint16_t buzz_length_ms, uint16_t buzz_delay_us) { uint32_t buzz_length_us; @@ -303,13 +374,18 @@ void buzz_sound(uint16_t buzz_length_ms, uint16_t buzz_delay_us) buzz_length_us -= buzz_delay_us*2; // Toggle the buzzer at various speeds - cbi(BUZZER1_PORT, BUZZER1); - sbi(BUZZER2_PORT, BUZZER2); - delay_us(buzz_delay_us); + //cbi(BUZZER1_PORT, BUZZER1); + //sbi(BUZZER2_PORT, BUZZER2); + digitalWrite(BUZZER1, LOW); + digitalWrite(BUZZER2, HIGH); +// delay_us(buzz_delay_us); + delayMicroseconds(buzz_delay_us); - sbi(BUZZER1_PORT, BUZZER1); - cbi(BUZZER2_PORT, BUZZER2); - delay_us(buzz_delay_us); + //sbi(BUZZER1_PORT, BUZZER1); + //cbi(BUZZER2_PORT, BUZZER2); + digitalWrite(BUZZER1, HIGH); + digitalWrite(BUZZER2, LOW); + delayMicroseconds(buzz_delay_us); } } @@ -322,52 +398,53 @@ void buzz_sound(uint16_t buzz_length_ms, uint16_t buzz_delay_us) */ void toner(uint8_t which, uint16_t buzz_length_ms) { - set_leds(which); + setLEDs(which); switch (which) { - case LED_RED: - buzz_sound(buzz_length_ms, 1136); + case CHOICE_RED: +// buzz_sound(buzz_length_ms, 1136); + tone(BUZZER1, 440, buzz_length_ms); break; - case LED_GREEN: - buzz_sound(buzz_length_ms, 568); + case CHOICE_GREEN: +// buzz_sound(buzz_length_ms, 568); + tone(BUZZER1, 880, buzz_length_ms); break; - case LED_BLUE: - buzz_sound(buzz_length_ms, 851); + case CHOICE_BLUE: +// buzz_sound(buzz_length_ms, 851); + tone(BUZZER1, 587, buzz_length_ms); break; - case LED_YELLOW: - buzz_sound(buzz_length_ms, 638); + case CHOICE_YELLOW: +// buzz_sound(buzz_length_ms, 638); + tone(BUZZER1, 784, buzz_length_ms); break; } // Turn off all LEDs - set_leds(0); + setLEDs(CHOICE_OFF); } // Show an "attract mode" display while waiting for user to press button. -void attract_mode(void) +void attractMode(void) { - while (1) { - set_leds(LED_RED); - delay_ms(100); - if (check_button() != 0x00) - return; + while(1) + { + setLEDs(CHOICE_RED); + delay(100); + if (checkButton() != CHOICE_NONE) return; - set_leds(LED_BLUE); - delay_ms(100); - if (check_button() != 0x00) - return; + setLEDs(CHOICE_BLUE); + delay(100); + if (checkButton() != CHOICE_NONE) return; - set_leds(LED_GREEN); - delay_ms(100); - if (check_button() != 0x00) - return; + setLEDs(CHOICE_GREEN); + delay(100); + if (checkButton() != CHOICE_NONE) return; - set_leds(LED_YELLOW); - delay_ms(100); - if (check_button() != 0x00) - return; + setLEDs(CHOICE_YELLOW); + delay(100); + if (checkButton() != CHOICE_NONE) return; } } @@ -375,7 +452,7 @@ void attract_mode(void) // Returns one of led colors (LED_RED, etc.) if successful, 0 if timed out uint8_t wait_for_button(void) { - uint16_t time_limit = TIME_LIMIT; + uint16_t time_limit = ENTRY_TIME_LIMIT; uint8_t released = 0; uint8_t old_button; @@ -384,22 +461,22 @@ uint8_t wait_for_button(void) // Implement a small bit of debouncing old_button = button; - button = check_button(); + button = checkButton(); // Make sure we've seen the previous button released before accepting new buttons - if (button == 0) + if (button == CHOICE_NONE) released = 1; if (button == old_button && released == 1) { // Make sure just one button is pressed - if (button == LED_RED || - button == LED_BLUE || - button == LED_GREEN || - button == LED_YELLOW) { + if (button == CHOICE_RED || + button == CHOICE_BLUE || + button == CHOICE_GREEN || + button == CHOICE_YELLOW) { return button; } } - delay_ms(1); + delay(1); time_limit--; } @@ -412,26 +489,24 @@ int game_mode(void) nmoves = 0; int moves_to_win_var = MOVES_TO_WIN; // If in normal mode, then allow the user to win after a #define varialb up top (default is 13). - if(battle) moves_to_win_var = 1000; // If in battle mode, allow the users to go up to 1000 moves! Like anyone could possibly do that :) + if(gameMode == MODE_BATTLE) moves_to_win_var = 1000; // If in battle mode, allow the users to go up to 1000 moves! Like anyone could possibly do that :) while (nmoves < moves_to_win_var) { - uint8_t move; - // Add a button to the current moves, then play them back - if(battle) + if(gameMode == MODE_BATTLE) add_to_moves_battle(); // If in battle mode, then listen for user input to choose the next step else add_to_moves(); - if(battle) + if(gameMode == MODE_BATTLE) ; // If in battle mode, then don't play back the pattern, it's up the the users to remember it - then add on a move. else play_moves(); // Then require the player to repeat the sequence. - for (move = 0; move < nmoves; move++) { - uint8_t choice = wait_for_button(); + for (byte currentMove = 0 ; currentMove < nmoves ; currentMove++) { + byte choice = wait_for_button(); // If wait timed out, player loses. if (choice == 0) @@ -440,88 +515,34 @@ int game_mode(void) toner(choice, 150); // If the choice is incorect, player loses. - if (choice != moves[move]) { + if (choice != moves[currentMove]) { return 0; } } // Player was correct, delay before playing moves - if(battle) + if(gameMode == MODE_BATTLE) { //reduced wait time, because we want to allow the battle to go very fast! //plus, if you use the delay(1000), then it may miss capturing the users next input. - delay_ms(100); + delay(100); } else - delay_ms(1000); + delay(1000); } // Player wins! return 1; } -void setup() -{ - -} - -void loop() -{ - - // Setup IO pins and defaults - ioinit(); - - // Check to see if LOWER LEFT BUTTON is pressed - if (check_button() == LED_YELLOW){ - while(1){ - buzz(5); - delay_ms(750); - if (check_button() == 0x00){ - while (1) beegees_loop(); - } - } - } - - // Check to see if LOWER RIGHT BUTTON is pressed - if (check_button() == LED_GREEN){ - while(1){ - buzz(5); - delay_ms(750); - if (check_button() == 0x00){ - battle = 1; - break; - } - } - } - - - play_winner(); - - // Main loop - while (1) { - // Wait for user to start game - attract_mode(); - - // Indicate the start of game play - set_leds(LED_RED|LED_GREEN|LED_BLUE|LED_YELLOW); - delay_ms(1000); - set_leds(0); - delay_ms(250); - - // Play game and handle result - if (game_mode() != 0) { - // Player won, play winner tones - play_winner(); - } - else { - // Player lost, play loser tones - play_loser(); - } - } -} +//These ints are for the begees loop funtion to work +int counter = 0; // for cycling through the LEDs during the beegees loop +int count = 20; // for keeping rhythm straight in the beegees loop // -void beegees_loop() + +//playBeegees() does nothing but play bad beegees music +void playBeegees() { buzz(3); delay(400); @@ -593,18 +614,20 @@ void buzz(int tone){ count = 40; // In order to keep all 5 notes the same length in time, you must compare them to the longest note (tonic) - aka the "1" note. - count = count*(2000/freq); + count = count * (2000/freq); // this next function simply changes the next LED to turn on. - change_led(); + changeLED(); // this next for loop actually makes the buzzer pin move. // it uses the "count" variable to know how many times to play the frequency. // -this keeps the timing correct. - for(int i = 0; i < count; i++){ + for(int i = 0 ; i < count ; i++) + { digitalWrite(BUZZER1, HIGH); digitalWrite(BUZZER2, LOW); delayMicroseconds(freq); + digitalWrite(BUZZER1, LOW); digitalWrite(BUZZER2, HIGH); delayMicroseconds(freq); @@ -631,8 +654,9 @@ void rest(int tone){ freq = 1110; } //freq = (freq/2); + count = 40; - count = count*(2000/freq); + count = count * (2000/freq); //change_led(); for(int i = 0 ; i < count ; i++) @@ -646,15 +670,10 @@ void rest(int tone){ } // -void change_led() +void changeLED() { - if(counter > 3) - { - counter = 0; - } - set_leds(1 << counter); + setLEDs(1 << counter); + counter += 1; + if(counter > 3) counter = 0; } - - - diff --git a/Firmware/Simon_Says/hardware_versions.h b/Firmware/Simon_Says/hardware_versions.h index f36262b..de67f48 100644 --- a/Firmware/Simon_Says/hardware_versions.h +++ b/Firmware/Simon_Says/hardware_versions.h @@ -6,6 +6,14 @@ file attempts to map and support all the different hardware versions. */ +#define CHOICE_OFF 0 //Used to control LEDs +#define CHOICE_NONE 0 //Used to check buttons +#define CHOICE_RED (1 << 0) +#define CHOICE_GREEN (1 << 1) +#define CHOICE_BLUE (1 << 2) +#define CHOICE_YELLOW (1 << 3) + + // Uncomment one of the following, corresponding to the board you have. //#define BOARD_REV_6_25_08 //#define BOARD_REV_4_9_2009 @@ -15,38 +23,36 @@ #define CHIP_ATMEGA168 -#define LED_RED (1 << 0) -#define LED_GREEN (1 << 1) -#define LED_BLUE (1 << 2) -#define LED_YELLOW (1 << 3) +// LED pin definitions, these are Arduino pins, not ATmega pins +#define LED_RED 10 +#define LED_GREEN 3 +#define LED_BLUE 13 +#define LED_YELLOW 5 -/* LED pin definitions */ -#define LED_RED_PIN 2 -#define LED_RED_PORT PORTB -#define LED_GREEN_PIN 3 -#define LED_GREEN_PORT PORTD -#define LED_BLUE_PIN 5 -#define LED_BLUE_PORT PORTB -#define LED_YELLOW_PIN 5 -#define LED_YELLOW_PORT PORTD +//#define LED_RED_PORT PORTB +//#define LED_GREEN_PORT PORTD +//#define LED_BLUE_PORT PORTB +//#define LED_YELLOW_PORT PORTD -/* Button pin definitions */ -#define BUTTON_RED_PIN 1 -#define BUTTON_RED_PORT PINB -#define BUTTON_GREEN_PIN 2 -#define BUTTON_GREEN_PORT PIND -#define BUTTON_BLUE_PIN 4 -#define BUTTON_BLUE_PORT PINB -#define BUTTON_YELLOW_PIN 6 -#define BUTTON_YELLOW_PORT PIND +// Button pin definitions +#define BUTTON_RED 9 +#define BUTTON_GREEN 2 +#define BUTTON_BLUE 12 +#define BUTTON_YELLOW 6 -/* Buzzer pin definitions */ -#define BUZZER1 4 -#define BUZZER1_PORT PORTD -#define BUZZER2 7 -#define BUZZER2_PORT PORTD +//#define BUTTON_RED_PORT PINB +//#define BUTTON_GREEN_PORT PIND +//#define BUTTON_BLUE_PORT PINB +//#define BUTTON_YELLOW_PORT PIND -#endif /* BOARD_REV_PTH */ +// Buzzer pin definitions +#define BUZZER1 4 +#define BUZZER2 7 + +//#define BUZZER1_PORT PORTD +//#define BUZZER2_PORT PORTD + +#endif // End definition for BOARD_REV_PTH #ifdef BOARD_REV_6_25_08 @@ -121,4 +127,4 @@ #define BUZZER2_PORT PORTD #endif /* BOARD_REV_4_9_2009 */ - + From 078011212b1294b828287d00ac73e9af244d23d5 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Sat, 29 Dec 2012 10:43:19 -0700 Subject: [PATCH 3/5] Improved button checking. Completed port to Arduino v1.0. Button checking is now faster, more responsive, and should handle heavy, slow button presses as well. Now works fully under Arduino v1.0 and have removed the majority of the older C specific code. --- Firmware/Simon_Says/Simon_Says.ino | 756 ++++++++++-------------- Firmware/Simon_Says/hardware_versions.h | 75 +-- 2 files changed, 351 insertions(+), 480 deletions(-) diff --git a/Firmware/Simon_Says/Simon_Says.ino b/Firmware/Simon_Says/Simon_Says.ino index ff0e3ce..48603b6 100644 --- a/Firmware/Simon_Says/Simon_Says.ino +++ b/Firmware/Simon_Says/Simon_Says.ino @@ -44,167 +44,189 @@ #include "hardware_versions.h" // Define game parameters -#define MOVES_TO_WIN 13 //Number of rounds to succesfully remember before you win. 13 is do-able. +#define ROUNDS_TO_WIN 13 //Number of rounds to succesfully remember before you win. 13 is do-able. #define ENTRY_TIME_LIMIT 3000 //Amount of time to press a button before game times out. 3000ms = 3 sec #define MODE_MEMORY 0 #define MODE_BATTLE 1 #define MODE_BEEGEES 2 -int gameMode = MODE_MEMORY; //By default, let's play the memory game - // Game state variables -uint8_t moves[32]; -uint8_t nmoves = 0; - -//Timer 2 overflow ISR -/*ISR (SIG_OVERFLOW2) -{ - // Prescalar of 1024, Clock = 16MHz, 15,625 clicks per second, 64us per click - - // Preload timer 2 for 125 clicks. Should be 8ms per ISR call - TCNT2 = 131; //256 - 125 = 131 -}*/ +int gameMode = MODE_MEMORY; //By default, let's play the memory game +byte gameBoard[32]; //Contains the combination of buttons as we advance +byte gameRound = 0; //Counts the number of succesful rounds the player has made it through void setup() { - - init_gpio(); + //Setup hardware inputs/outputs. These pins are defined in the hardware_versions header file - randomSeed(analogRead(0)); //Seed the random generator with noise on pin A0 + //Enable pull ups on inputs + pinMode(BUTTON_RED, INPUT_PULLUP); + pinMode(BUTTON_GREEN, INPUT_PULLUP); + pinMode(BUTTON_BLUE, INPUT_PULLUP); + pinMode(BUTTON_YELLOW, INPUT_PULLUP); -/* - //Set Timer 0 Registers to Default Setting to over-ride the timer initialization made in the init() function of the \ - //Arduino Wiring library (Wiring.c in the hardware/core/arduino folder) - TCCR0A = 0; - TIMSK0 = 0; - // Init timer 0 for delay_us timing (1,000,000 / 1 = 1,000,000) - //TCCR0B = (1< 256) - { - TIFR0 = (1< (buzz_delay_us * 2)) + { + buzz_length_us -= buzz_delay_us * 2; //Decrease the remaining play time + + // Toggle the buzzer at various speeds + digitalWrite(BUZZER1, LOW); + digitalWrite(BUZZER2, HIGH); + delayMicroseconds(buzz_delay_us); + + digitalWrite(BUZZER1, HIGH); + digitalWrite(BUZZER2, LOW); + delayMicroseconds(buzz_delay_us); + } +} + +// Play the winner sound and lights +void play_winner(void) +{ + setLEDs(CHOICE_GREEN | CHOICE_BLUE); + winner_sound(); + setLEDs(CHOICE_RED | CHOICE_YELLOW); + winner_sound(); + setLEDs(CHOICE_GREEN | CHOICE_BLUE); + winner_sound(); + setLEDs(CHOICE_RED | CHOICE_YELLOW); + winner_sound(); } // Play the winner sound +// This is just a unique (annoying) sound we came up with, there is no magic to it void winner_sound(void) { - byte x, y; - // Toggle the buzzer at various speeds - for (x = 250 ; x > 70 ; x--) { - for (y = 0 ; y < 3 ; y++) { - //sbi(BUZZER2_PORT, BUZZER2); - //cbi(BUZZER1_PORT, BUZZER1); + for (byte x = 250 ; x > 70 ; x--) + { + for (byte y = 0 ; y < 3 ; y++) + { digitalWrite(BUZZER2, HIGH); digitalWrite(BUZZER1, LOW); delayMicroseconds(x); - //cbi(BUZZER2_PORT, BUZZER2); - //sbi(BUZZER1_PORT, BUZZER1); digitalWrite(BUZZER2, LOW); digitalWrite(BUZZER1, HIGH); delayMicroseconds(x); @@ -318,111 +364,20 @@ void winner_sound(void) } } -// Play the winner sound and lights -void play_winner(void) +// Play the loser sound/lights +void play_loser(void) { - setLEDs(CHOICE_GREEN|CHOICE_BLUE); - winner_sound(); - setLEDs(CHOICE_RED|CHOICE_YELLOW); - winner_sound(); - setLEDs(CHOICE_GREEN|CHOICE_BLUE); - winner_sound(); - setLEDs(CHOICE_RED|CHOICE_YELLOW); - winner_sound(); -} + setLEDs(CHOICE_RED | CHOICE_GREEN); + buzz_sound(255, 1500); -// Plays the current contents of the game moves -void play_moves(void) -{ - byte currentMove; + setLEDs(CHOICE_BLUE | CHOICE_YELLOW); + buzz_sound(255, 1500); - for (currentMove = 0 ; currentMove < nmoves ; currentMove++) - { - toner(moves[currentMove], 150); - delay(150); - } -} + setLEDs(CHOICE_RED | CHOICE_GREEN); + buzz_sound(255, 1500); -// Adds a new random button to the game sequence, by sampling the timer -void add_to_moves(void) -{ - byte newButton = random(0, 3); - moves[nmoves++] = newButton; //Add this new button to the game array -} - -// Adds a user defined button to the game sequence, by waiting for their input -void add_to_moves_battle(void) -{ - uint8_t new_button; - - // wait for user to input next move - new_button = wait_for_button(); - - toner(new_button, 150); - - moves[nmoves++] = new_button; -} - -// Toggle buzzer every buzz_delay_us, for a duration of buzz_length_ms. -//Given a length and a -void buzz_sound(uint16_t buzz_length_ms, uint16_t buzz_delay_us) -{ - uint32_t buzz_length_us; - - buzz_length_us = buzz_length_ms * (uint32_t)1000; - while (buzz_length_us > buzz_delay_us*2) { - buzz_length_us -= buzz_delay_us*2; - - // Toggle the buzzer at various speeds - //cbi(BUZZER1_PORT, BUZZER1); - //sbi(BUZZER2_PORT, BUZZER2); - digitalWrite(BUZZER1, LOW); - digitalWrite(BUZZER2, HIGH); -// delay_us(buzz_delay_us); - delayMicroseconds(buzz_delay_us); - - //sbi(BUZZER1_PORT, BUZZER1); - //cbi(BUZZER2_PORT, BUZZER2); - digitalWrite(BUZZER1, HIGH); - digitalWrite(BUZZER2, LOW); - delayMicroseconds(buzz_delay_us); - } -} - -/* - Light an LED and play tone - red, upper left: 440Hz - 2.272ms - 1.136ms pulse - green, upper right: 880Hz - 1.136ms - 0.568ms pulse - blue, lower left: 587.33Hz - 1.702ms - 0.851ms pulse - yellow, lower right: 784Hz - 1.276ms - 0.638ms pulse - */ -void toner(uint8_t which, uint16_t buzz_length_ms) -{ - setLEDs(which); - switch (which) { - case CHOICE_RED: -// buzz_sound(buzz_length_ms, 1136); - tone(BUZZER1, 440, buzz_length_ms); - break; - - case CHOICE_GREEN: -// buzz_sound(buzz_length_ms, 568); - tone(BUZZER1, 880, buzz_length_ms); - break; - - case CHOICE_BLUE: -// buzz_sound(buzz_length_ms, 851); - tone(BUZZER1, 587, buzz_length_ms); - break; - - case CHOICE_YELLOW: -// buzz_sound(buzz_length_ms, 638); - tone(BUZZER1, 784, buzz_length_ms); - break; - } - - // Turn off all LEDs - setLEDs(CHOICE_OFF); + setLEDs(CHOICE_BLUE | CHOICE_YELLOW); + buzz_sound(255, 1500); } // Show an "attract mode" display while waiting for user to press button. @@ -448,138 +403,67 @@ void attractMode(void) } } -// Wait for a button to be pressed. -// Returns one of led colors (LED_RED, etc.) if successful, 0 if timed out -uint8_t wait_for_button(void) -{ - uint16_t time_limit = ENTRY_TIME_LIMIT; - uint8_t released = 0; - uint8_t old_button; +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +//The following functions are related to Beegees Easter Egg only - while (time_limit > 0) { - uint8_t button; - - // Implement a small bit of debouncing - old_button = button; - button = checkButton(); - - // Make sure we've seen the previous button released before accepting new buttons - if (button == CHOICE_NONE) - released = 1; - if (button == old_button && released == 1) { - // Make sure just one button is pressed - if (button == CHOICE_RED || - button == CHOICE_BLUE || - button == CHOICE_GREEN || - button == CHOICE_YELLOW) { - return button; - } - } - - delay(1); - - time_limit--; - } - return 0; //Timed out -} - -// Play the game. Returns 0 if player loses, or 1 if player wins. -int game_mode(void) -{ - nmoves = 0; - int moves_to_win_var = MOVES_TO_WIN; // If in normal mode, then allow the user to win after a #define varialb up top (default is 13). - - if(gameMode == MODE_BATTLE) moves_to_win_var = 1000; // If in battle mode, allow the users to go up to 1000 moves! Like anyone could possibly do that :) - - while (nmoves < moves_to_win_var) - { - // Add a button to the current moves, then play them back - if(gameMode == MODE_BATTLE) - add_to_moves_battle(); // If in battle mode, then listen for user input to choose the next step - else - add_to_moves(); - - if(gameMode == MODE_BATTLE) - ; // If in battle mode, then don't play back the pattern, it's up the the users to remember it - then add on a move. - else - play_moves(); - - // Then require the player to repeat the sequence. - for (byte currentMove = 0 ; currentMove < nmoves ; currentMove++) { - byte choice = wait_for_button(); - - // If wait timed out, player loses. - if (choice == 0) - return 0; - - toner(choice, 150); - - // If the choice is incorect, player loses. - if (choice != moves[currentMove]) { - return 0; - } - } - - // Player was correct, delay before playing moves - if(gameMode == MODE_BATTLE) - { - //reduced wait time, because we want to allow the battle to go very fast! - //plus, if you use the delay(1000), then it may miss capturing the users next input. - delay(100); - } - else - delay(1000); - } - - // Player wins! - return 1; -} - - -//These ints are for the begees loop funtion to work -int counter = 0; // for cycling through the LEDs during the beegees loop +int LEDnumber = 0; // Keeps track of which LED we are on during the beegees loop int count = 20; // for keeping rhythm straight in the beegees loop -// -//playBeegees() does nothing but play bad beegees music -void playBeegees() +// Do nothing but play bad beegees music +// This function is activated when user holds bottom right button during power up +void play_beegees() { - buzz(3); - delay(400); - buzz(4); - rest(1); - delay(600); - buzz(5); - rest(1); - rest(1); - delay(400); - buzz(3); - rest(1); - rest(1); - rest(1); - buzz(2); - rest(1); - buzz(1); - buzz(2); - buzz(3); - rest(1); - buzz(1); - buzz(2); - rest(1); - buzz(3); - rest(1); - rest(1); - buzz(1); - rest(1); - buzz(2); - rest(1); - buzz(3); - rest(1); - buzz(4); - rest(1); - buzz(5); - rest(1); - delay(700); + //Turn on the bottom right (yellow) LED + setLEDs(CHOICE_YELLOW); + toner(CHOICE_YELLOW, 150); + + setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE); // Turn on the other LEDs until you release button + + while(checkButton() != CHOICE_NONE) ; // Wait for user to stop pressing button + + setLEDs(CHOICE_NONE); // Turn off LEDs + + delay(1000); // Wait a second before playing song + + while(checkButton() == CHOICE_NONE) //Play song until you press a button + { + buzz(3); + delay(400); + buzz(4); + rest(1); + delay(600); + buzz(5); + rest(1); + rest(1); + delay(400); + buzz(3); + rest(1); + rest(1); + rest(1); + buzz(2); + rest(1); + buzz(1); + buzz(2); + buzz(3); + rest(1); + buzz(1); + buzz(2); + rest(1); + buzz(3); + rest(1); + rest(1); + buzz(1); + rest(1); + buzz(2); + rest(1); + buzz(3); + rest(1); + buzz(4); + rest(1); + buzz(5); + rest(1); + delay(700); + } } // @@ -589,21 +473,11 @@ void buzz(int tone){ int freq; //5 different tones to select. Each tone is a different frequency. - if(tone == 1){ - freq = 2000; - } - if(tone == 2){ - freq = 1800; - } - if(tone == 3){ - freq = 1500; - } - if(tone == 4){ - freq = 1350; - } - if(tone == 5){ - freq = 1110; - } + if(tone == 1) freq = 2000; + if(tone == 2) freq = 1800; + if(tone == 3) freq = 1500; + if(tone == 4) freq = 1350; + if(tone == 5) freq = 1110; //freq = (freq/2); @@ -616,7 +490,7 @@ void buzz(int tone){ // In order to keep all 5 notes the same length in time, you must compare them to the longest note (tonic) - aka the "1" note. count = count * (2000/freq); - // this next function simply changes the next LED to turn on. + // Change to the next LED changeLED(); // this next for loop actually makes the buzzer pin move. @@ -632,27 +506,19 @@ void buzz(int tone){ digitalWrite(BUZZER2, HIGH); delayMicroseconds(freq); } + delay(60); } // void rest(int tone){ int freq; - if(tone == 1){ - freq = 2000; - } - if(tone == 2){ - freq = 1800; - } - if(tone == 3){ - freq = 1500; - } - if(tone == 4){ - freq = 1350; - } - if(tone == 5){ - freq = 1110; - } + if(tone == 1) freq = 2000; + if(tone == 2) freq = 1800; + if(tone == 3) freq = 1500; + if(tone == 4) freq = 1350; + if(tone == 5) freq = 1110; + //freq = (freq/2); count = 40; @@ -666,14 +532,18 @@ void rest(int tone){ digitalWrite(BUZZER1, LOW); delayMicroseconds(freq); } + delay(75); } -// -void changeLED() +// Each time this function is called the board moves to the next LED +void changeLED(void) { - setLEDs(1 << counter); + setLEDs(1 << LEDnumber); // Change the LED - counter += 1; - if(counter > 3) counter = 0; + LEDnumber++; // Goto the next LED + if(LEDnumber > 3) LEDnumber = 0; // Wrap the counter if needed } + + + diff --git a/Firmware/Simon_Says/hardware_versions.h b/Firmware/Simon_Says/hardware_versions.h index de67f48..714c991 100644 --- a/Firmware/Simon_Says/hardware_versions.h +++ b/Firmware/Simon_Says/hardware_versions.h @@ -19,9 +19,9 @@ //#define BOARD_REV_4_9_2009 #define BOARD_REV_PTH -#ifdef BOARD_REV_PTH -#define CHIP_ATMEGA168 + +#ifdef BOARD_REV_PTH // LED pin definitions, these are Arduino pins, not ATmega pins #define LED_RED 10 @@ -29,41 +29,21 @@ #define LED_BLUE 13 #define LED_YELLOW 5 -//#define LED_RED_PORT PORTB -//#define LED_GREEN_PORT PORTD -//#define LED_BLUE_PORT PORTB -//#define LED_YELLOW_PORT PORTD - // Button pin definitions #define BUTTON_RED 9 #define BUTTON_GREEN 2 #define BUTTON_BLUE 12 #define BUTTON_YELLOW 6 -//#define BUTTON_RED_PORT PINB -//#define BUTTON_GREEN_PORT PIND -//#define BUTTON_BLUE_PORT PINB -//#define BUTTON_YELLOW_PORT PIND - // Buzzer pin definitions #define BUZZER1 4 #define BUZZER2 7 -//#define BUZZER1_PORT PORTD -//#define BUZZER2_PORT PORTD - #endif // End definition for BOARD_REV_PTH #ifdef BOARD_REV_6_25_08 -#define CHIP_ATMEGA168 - -#define LED_RED (1 << 0) -#define LED_GREEN (1 << 1) -#define LED_BLUE (1 << 2) -#define LED_YELLOW (1 << 3) - -/* LED pin definitions */ +// LED pin definitions #define LED_RED_PIN 3 #define LED_RED_PORT PORTC #define LED_GREEN_PIN 2 @@ -73,7 +53,7 @@ #define LED_YELLOW_PIN 5 #define LED_YELLOW_PORT PORTD -/* Button pin definitions */ +// Button pin definitions #define BUTTON_RED_PIN 2 #define BUTTON_RED_PORT PINC #define BUTTON_GREEN_PIN 5 @@ -83,24 +63,18 @@ #define BUTTON_YELLOW_PIN 6 #define BUTTON_YELLOW_PORT PIND -/* Buzzer pin definitions */ +// Buzzer pin definitions #define BUZZER1 3 #define BUZZER1_PORT PORTD #define BUZZER2 4 #define BUZZER2_PORT PORTD -#endif /* BOARD_REV_6_25_08 */ +#endif // End define for BOARD_REV_6_25_08 + #ifdef BOARD_REV_4_9_2009 -#define LED_RED (1 << 0) -#define LED_GREEN (1 << 1) -#define LED_BLUE (1 << 2) -#define LED_YELLOW (1 << 3) - -#define CHIP_ATMEGA168 - -/* LED pin definitions */ +// LED pin definitions #define LED_BLUE_PIN 5 #define LED_BLUE_PORT PORTB #define LED_YELLOW_PIN 5 @@ -110,7 +84,7 @@ #define LED_GREEN_PIN 2 #define LED_GREEN_PORT PORTD -/* Button pin definitions */ +// Button pin definitions #define BUTTON_RED_PIN 0 #define BUTTON_RED_PORT PINB #define BUTTON_GREEN_PIN 1 @@ -120,11 +94,38 @@ #define BUTTON_YELLOW_PIN 6 #define BUTTON_YELLOW_PORT PIND -/* Buzzer pin definitions */ +// Buzzer pin definitions #define BUZZER1 3 #define BUZZER1_PORT PORTD #define BUZZER2 4 #define BUZZER2_PORT PORTD -#endif /* BOARD_REV_4_9_2009 */ +#endif // End define for BOARD_REV_4_9_2009 + +//The following functions are specific to different versions of the board + +#ifdef BOARD_REV_6_25_08 +void init_gpio(void) +{ + // 1 = output, 0 = input + DDRB = 0b11111111; + DDRC = 0b00001001; // LEDs and Buttons + DDRD = 0b00111110; // LEDs, buttons, buzzer, TX/RX + + PORTC = 0b00100110; // Enable pull-ups on buttons 0, 2, 3 + PORTD = 0b01000000; // Enable pull-up on button 1 +} +#endif // End BOARD_REV_6_25_08 + +#ifdef BOARD_REV_4_9_2009 +void init_gpio(void) +{ + // 1 = output, 0 = input + DDRB = 0b11111100; // Button 2,3 on PB0,1 + DDRD = 0b00111110; // LEDs, buttons, buzzer, TX/RX + + PORTB = 0b00000011; // Enable pull-ups on buttons 2, 3 + PORTD = 0b11000000; // Enable pull-up on button 0, 1 +} +#endif // End BOARD_REV_4_9_2009 From 64ff50596158317741896db023e22bdb4ccfa635 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Sat, 29 Dec 2012 10:58:34 -0700 Subject: [PATCH 4/5] Corrected the hardware mapping to older board versions. This new mapping system should work but it is untested. --- Firmware/Simon_Says/hardware_versions.h | 158 ++++++++---------------- 1 file changed, 51 insertions(+), 107 deletions(-) diff --git a/Firmware/Simon_Says/hardware_versions.h b/Firmware/Simon_Says/hardware_versions.h index 714c991..d5fc193 100644 --- a/Firmware/Simon_Says/hardware_versions.h +++ b/Firmware/Simon_Says/hardware_versions.h @@ -15,117 +15,61 @@ // Uncomment one of the following, corresponding to the board you have. -//#define BOARD_REV_6_25_08 +#define BOARD_REV_2_3_2011 //Works with board label '2-3-2011' //#define BOARD_REV_4_9_2009 -#define BOARD_REV_PTH - - - -#ifdef BOARD_REV_PTH - -// LED pin definitions, these are Arduino pins, not ATmega pins -#define LED_RED 10 -#define LED_GREEN 3 -#define LED_BLUE 13 -#define LED_YELLOW 5 - -// Button pin definitions -#define BUTTON_RED 9 -#define BUTTON_GREEN 2 -#define BUTTON_BLUE 12 -#define BUTTON_YELLOW 6 - -// Buzzer pin definitions -#define BUZZER1 4 -#define BUZZER2 7 - -#endif // End definition for BOARD_REV_PTH - -#ifdef BOARD_REV_6_25_08 - -// LED pin definitions -#define LED_RED_PIN 3 -#define LED_RED_PORT PORTC -#define LED_GREEN_PIN 2 -#define LED_GREEN_PORT PORTD -#define LED_BLUE_PIN 0 -#define LED_BLUE_PORT PORTC -#define LED_YELLOW_PIN 5 -#define LED_YELLOW_PORT PORTD - -// Button pin definitions -#define BUTTON_RED_PIN 2 -#define BUTTON_RED_PORT PINC -#define BUTTON_GREEN_PIN 5 -#define BUTTON_GREEN_PORT PINC -#define BUTTON_BLUE_PIN 1 -#define BUTTON_BLUE_PORT PINC -#define BUTTON_YELLOW_PIN 6 -#define BUTTON_YELLOW_PORT PIND - -// Buzzer pin definitions -#define BUZZER1 3 -#define BUZZER1_PORT PORTD -#define BUZZER2 4 -#define BUZZER2_PORT PORTD - -#endif // End define for BOARD_REV_6_25_08 +//#define BOARD_REV_6_25_2008 +#ifdef BOARD_REV_2_3_2011 + // LED pin definitions, these are Arduino pins, not ATmega pins + #define LED_RED 10 + #define LED_GREEN 3 + #define LED_BLUE 13 + #define LED_YELLOW 5 + + // Button pin definitions + #define BUTTON_RED 9 + #define BUTTON_GREEN 2 + #define BUTTON_BLUE 12 + #define BUTTON_YELLOW 6 + + // Buzzer pin definitions + #define BUZZER1 4 + #define BUZZER2 7 +#endif // End definition for BOARD_REV_2_3_2011 #ifdef BOARD_REV_4_9_2009 - -// LED pin definitions -#define LED_BLUE_PIN 5 -#define LED_BLUE_PORT PORTB -#define LED_YELLOW_PIN 5 -#define LED_YELLOW_PORT PORTD -#define LED_RED_PIN 2 -#define LED_RED_PORT PORTB -#define LED_GREEN_PIN 2 -#define LED_GREEN_PORT PORTD - -// Button pin definitions -#define BUTTON_RED_PIN 0 -#define BUTTON_RED_PORT PINB -#define BUTTON_GREEN_PIN 1 -#define BUTTON_GREEN_PORT PINB -#define BUTTON_BLUE_PIN 7 -#define BUTTON_BLUE_PORT PIND -#define BUTTON_YELLOW_PIN 6 -#define BUTTON_YELLOW_PORT PIND - -// Buzzer pin definitions -#define BUZZER1 3 -#define BUZZER1_PORT PORTD -#define BUZZER2 4 -#define BUZZER2_PORT PORTD - + // LED pin definitions, these are Arduino pins, not ATmega pins + #define LED_BLUE 13 //PORTB.5 + #define LED_YELLOW 5 //PORTD.5 + #define LED_RED 10 //PORTB.2 + #define LED_GREEN 1 //PORTD.2 - This may conflict with TX + + // Button pin definitions + #define BUTTON_RED 8 //PINB.0 + #define BUTTON_GREEN 9 //PINB.1 + #define BUTTON_BLUE 7 //PIND.7 + #define BUTTON_YELLOW 6 //PIND.6 + + // Buzzer pin definitions + #define BUZZER1 3 //PORTD.3 + #define BUZZER2 4 //PORTD.4 #endif // End define for BOARD_REV_4_9_2009 +#ifdef BOARD_REV_6_25_2008 + // LED pin definitions, these are Arduino pins, not ATmega pins + #define LED_RED A3 //PORTC.3 + #define LED_GREEN 2 //PORTD.2 + #define LED_BLUE A0 //PORTC.0 + #define LED_YELLOW 5 //PORTD.5 + + // Button pin definitions + #define BUTTON_RED A2 //PINC.2 + #define BUTTON_GREEN A5 //PINC.5 + #define BUTTON_BLUE A1 //PINC.1 + #define BUTTON_YELLOW 6 //PIND.6 + + // Buzzer pin definitions + #define BUZZER1 3 //PORTD.3 + #define BUZZER2 4 //PORTD.4 +#endif // End define for BOARD_REV_6_25_2008 -//The following functions are specific to different versions of the board - -#ifdef BOARD_REV_6_25_08 -void init_gpio(void) -{ - // 1 = output, 0 = input - DDRB = 0b11111111; - DDRC = 0b00001001; // LEDs and Buttons - DDRD = 0b00111110; // LEDs, buttons, buzzer, TX/RX - - PORTC = 0b00100110; // Enable pull-ups on buttons 0, 2, 3 - PORTD = 0b01000000; // Enable pull-up on button 1 -} -#endif // End BOARD_REV_6_25_08 - -#ifdef BOARD_REV_4_9_2009 -void init_gpio(void) -{ - // 1 = output, 0 = input - DDRB = 0b11111100; // Button 2,3 on PB0,1 - DDRD = 0b00111110; // LEDs, buttons, buzzer, TX/RX - - PORTB = 0b00000011; // Enable pull-ups on buttons 2, 3 - PORTD = 0b11000000; // Enable pull-up on button 0, 1 -} -#endif // End BOARD_REV_4_9_2009 From b6ec23b87ca723e38a50d543381cb30576dc96aa Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 7 Jan 2013 12:09:03 -0700 Subject: [PATCH 5/5] Changed variable to byte to save space. --- Firmware/Simon_Says/Simon_Says.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Simon_Says/Simon_Says.ino b/Firmware/Simon_Says/Simon_Says.ino index 48603b6..7da504f 100644 --- a/Firmware/Simon_Says/Simon_Says.ino +++ b/Firmware/Simon_Says/Simon_Says.ino @@ -52,7 +52,7 @@ #define MODE_BEEGEES 2 // Game state variables -int gameMode = MODE_MEMORY; //By default, let's play the memory game +byte gameMode = MODE_MEMORY; //By default, let's play the memory game byte gameBoard[32]; //Contains the combination of buttons as we advance byte gameRound = 0; //Counts the number of succesful rounds the player has made it through @@ -546,4 +546,4 @@ void changeLED(void) } - +