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