Merging Nate's pull

This commit is contained in:
Mike Hord 2013-02-15 16:27:11 -07:00
commit 5afb82a7ed
3 changed files with 436 additions and 593 deletions

View File

@ -44,521 +44,426 @@
#include "hardware_versions.h" #include "hardware_versions.h"
// Define game parameters // Define game parameters
#define MOVES_TO_WIN 13 #define ROUNDS_TO_WIN 13 //Number of rounds to succesfully remember before you win. 13 is do-able.
#define TIME_LIMIT 3000 //3000ms = 3 sec #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<<pin_number) #define MODE_MEMORY 0
#define cbi(port_name, pin_number) ((port_name) &= (uint8_t)~(1 << pin_number)) #define MODE_BATTLE 1
#define MODE_BEEGEES 2
int battle = 0;
///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
//////////////
// Game state variables // Game state variables
uint8_t moves[32]; byte gameMode = MODE_MEMORY; //By default, let's play the memory game
uint8_t nmoves = 0; 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
//Timer 2 overflow ISR void setup()
ISR (SIG_OVERFLOW2)
{ {
// Prescalar of 1024, Clock = 16MHz, 15,625 clicks per second, 64us per click //Setup hardware inputs/outputs. These pins are defined in the hardware_versions header file
// Preload timer 2 for 125 clicks. Should be 8ms per ISR call //Enable pull ups on inputs
TCNT2 = 131; //256 - 125 = 131 pinMode(BUTTON_RED, INPUT_PULLUP);
} pinMode(BUTTON_GREEN, INPUT_PULLUP);
pinMode(BUTTON_BLUE, INPUT_PULLUP);
pinMode(BUTTON_YELLOW, INPUT_PULLUP);
//General short delays, using internal timer do a fairly accurate 1us pinMode(LED_RED, OUTPUT);
#ifdef CHIP_ATMEGA168 pinMode(LED_GREEN, OUTPUT);
void delay_us(uint16_t delay) pinMode(LED_BLUE, OUTPUT);
{ pinMode(LED_YELLOW, OUTPUT);
while (delay > 256)
pinMode(BUZZER1, OUTPUT);
pinMode(BUZZER2, OUTPUT);
//Mode checking
gameMode = MODE_MEMORY; // By default, we're going to play the memory game
// Check to see if the lower right button is pressed
if (checkButton() == CHOICE_YELLOW) play_beegees();
// Check to see if upper right button is pressed
if (checkButton() == CHOICE_GREEN)
{ {
TIFR0 = (1<<TOV0); // Clear any interrupt flags on Timer0 gameMode = MODE_BATTLE; //Put game into battle mode
TCNT0 = 0;
while ( (TIFR0 & (1<<TOV0)) == 0);
delay -= 256; //Turn on the upper right (green) LED
setLEDs(CHOICE_GREEN);
toner(CHOICE_GREEN, 150);
setLEDs(CHOICE_RED | CHOICE_BLUE | CHOICE_YELLOW); // Turn on the other LEDs until you release button
while(checkButton() != CHOICE_NONE) ; // Wait for user to stop pressing button
//Now do nothing. Battle mode will be serviced in the main routine
} }
TIFR0 = (1<<TOV0); // Clear any interrupt flags on Timer0 play_winner(); // After setup is complete, say hello to the world
// 256 - 125 = 131 : Preload timer 0 for x clicks. Should be 1us per click
TCNT0 = 256 - delay;
while ((TIFR0 & (1<<TOV0)) == 0) {
// Do nothing
}
} }
#endif
//General short delays void loop()
void delay_ms(uint16_t x)
{ {
while (x-- > 0) { attractMode(); // Blink lights while waiting for user to press a button
delay_us(1000);
// Indicate the start of game play
setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE | CHOICE_YELLOW); // Turn all LEDs on
delay(1000);
setLEDs(CHOICE_OFF); // Turn off LEDs
delay(250);
if (gameMode == MODE_MEMORY)
{
// Play memory game and handle result
if (play_memory() == true)
play_winner(); // Player won, play winner tones
else
play_loser(); // Player lost, play loser tones
}
if (gameMode == MODE_BATTLE)
{
play_battle(); // Play game until someone loses
play_loser(); // Player lost, play loser tones
} }
} }
//Light the given set of LEDs //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void set_leds(uint8_t leds) //The following functions are related to game play only
// Play the regular memory game
// Returns 0 if player loses, or 1 if player wins
boolean play_memory(void)
{ {
if ((leds & LED_RED) != 0) { randomSeed(millis()); // Seed the random generator with random amount of millis()
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);
}
}
gameRound = 0; // Reset the game to the beginning
#ifdef BOARD_REV_6_25_08 while (gameRound < ROUNDS_TO_WIN)
void init_gpio(void) {
{ add_to_moves(); // Add a button to the current moves, then play them back
// 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 playMoves(); // Play back the current game board
PORTD = 0b01000000; // Enable pull-up on button 1
}
#endif // End BOARD_REV_6_25_08
#ifdef BOARD_REV_4_9_2009 // Then require the player to repeat the sequence.
void init_gpio(void) for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
{ {
// 1 = output, 0 = input byte choice = wait_for_button(); // See what button the user presses
DDRB = 0b11111100; // Button 2,3 on PB0,1
DDRD = 0b00111110; // LEDs, buttons, buzzer, TX/RX
PORTB = 0b00000011; // Enable pull-ups on buttons 2, 3 if (choice == 0) return false; // If wait timed out, player loses
PORTD = 0b11000000; // Enable pull-up on button 0, 1
}
#endif // End BOARD_REV_4_9_2009
#ifdef BOARD_REV_PTH if (choice != gameBoard[currentMove]) return false; // If the choice is incorect, player loses
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
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
}
#endif
void ioinit(void)
{
init_gpio();
//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<<CS00); // Set Prescaler to 1. CS00=1
TCCR0B = (1<<CS01); // Set Prescaler to 1. CS00=1
// Init timer 2
ASSR = 0;
// Set Prescaler to 1024. CS22=1, CS21=1, CS20=1
TCCR2B = (1<<CS22)|(1<<CS21)|(1<<CS20);
TIMSK2 = (1<<TOIE2); // Enable Timer 2 Interrupt
cli(); //We don't use any interrupt functionality. Let's turn it off so Arduino doesn't screw around with it!
}
// Returns a '1' bit in the position corresponding to LED_RED, etc.
uint8_t check_button(void)
{
uint8_t button_pressed = 0;
if ((BUTTON_RED_PORT & (1 << BUTTON_RED_PIN)) == 0)
button_pressed |= LED_RED;
if ((BUTTON_GREEN_PORT & (1 << BUTTON_GREEN_PIN)) == 0)
button_pressed |= LED_GREEN;
if ((BUTTON_BLUE_PORT & (1 << BUTTON_BLUE_PIN)) == 0)
button_pressed |= LED_BLUE;
if ((BUTTON_YELLOW_PORT & (1 << BUTTON_YELLOW_PIN)) == 0)
button_pressed |= LED_YELLOW;
return button_pressed;
}
// Play the loser sound/lights
void play_loser(void)
{
set_leds(LED_RED|LED_GREEN);
buzz_sound(255, 1500);
set_leds(LED_BLUE|LED_YELLOW);
buzz_sound(255, 1500);
set_leds(LED_RED|LED_GREEN);
buzz_sound(255, 1500);
set_leds(LED_BLUE|LED_YELLOW);
buzz_sound(255, 1500);
}
// Play the winner sound
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);
delay_us(x);
cbi(BUZZER2_PORT, BUZZER2);
sbi(BUZZER1_PORT, BUZZER1);
delay_us(x);
} }
delay(1000); // Player was correct, delay before playing moves
} }
return true; // Player made it through all the rounds to win!
} }
// Play the winner sound and lights // Play the special 2 player battle mode
void play_winner(void) // A player begins by pressing a button then handing it to the other player
// That player repeats the button and adds one, then passes back.
// This function returns when someone loses
boolean play_battle(void)
{ {
set_leds(LED_GREEN|LED_BLUE); gameRound = 0; // Reset the game frame back to one frame
winner_sound();
set_leds(LED_RED|LED_YELLOW); while (1) // Loop until someone fails
winner_sound(); {
set_leds(LED_GREEN|LED_BLUE); byte newButton = wait_for_button(); // Wait for user to input next move
winner_sound(); gameBoard[gameRound++] = newButton; // Add this new button to the game array
set_leds(LED_RED|LED_YELLOW);
winner_sound(); // Then require the player to repeat the sequence.
for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
{
byte choice = wait_for_button();
if (choice == 0) return false; // If wait timed out, player loses.
if (choice != gameBoard[currentMove]) return false; // If the choice is incorect, player loses.
}
delay(100); // Give the user an extra 100ms to hand the game to the other player
}
return true; // We should never get here
} }
// Plays the current contents of the game moves // Plays the current contents of the game moves
void play_moves(void) void playMoves(void)
{ {
uint8_t move; for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
{
toner(gameBoard[currentMove], 150);
for (move = 0; move < nmoves; move++) { // Wait some amount of time between button playback
toner(moves[move], 150); // Shorten this to make game harder
delay_ms(150); delay(150); // 150 works well. 75 gets fast.
} }
} }
// Adds a new random button to the game sequence, by sampling the timer // Adds a new random button to the game sequence, by sampling the timer
void add_to_moves(void) void add_to_moves(void)
{ {
uint8_t new_button; byte newButton = random(0, 4); //min (included), max (exluded)
// Use the lower 2 bits of the timer for the random value // We have to convert this number, 0 to 3, to CHOICEs
new_button = 1 << (TCNT2 & 0x3); if(newButton == 0) newButton = CHOICE_RED;
else if(newButton == 1) newButton = CHOICE_GREEN;
else if(newButton == 2) newButton = CHOICE_BLUE;
else if(newButton == 3) newButton = CHOICE_YELLOW;
moves[nmoves++] = new_button; gameBoard[gameRound++] = 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) //The following functions control the hardware
{
uint8_t new_button;
// wait for user to input next move // Lights a given LEDs
new_button = wait_for_button(); // Pass in a byte that is made up from CHOICE_RED, CHOICE_YELLOW, etc
void setLEDs(byte leds)
toner(new_button, 150);
moves[nmoves++] = new_button;
}
// Toggle buzzer every buzz_delay_us, for a duration of buzz_length_ms.
void buzz_sound(uint16_t buzz_length_ms, uint16_t buzz_delay_us)
{ {
uint32_t buzz_length_us; if ((leds & CHOICE_RED) != 0)
digitalWrite(LED_RED, HIGH);
else
digitalWrite(LED_RED, LOW);
buzz_length_us = buzz_length_ms * (uint32_t)1000; if ((leds & CHOICE_GREEN) != 0)
while (buzz_length_us > buzz_delay_us*2) { digitalWrite(LED_GREEN, HIGH);
buzz_length_us -= buzz_delay_us*2; else
digitalWrite(LED_GREEN, LOW);
// Toggle the buzzer at various speeds if ((leds & CHOICE_BLUE) != 0)
cbi(BUZZER1_PORT, BUZZER1); digitalWrite(LED_BLUE, HIGH);
sbi(BUZZER2_PORT, BUZZER2); else
delay_us(buzz_delay_us); digitalWrite(LED_BLUE, LOW);
if ((leds & CHOICE_YELLOW) != 0)
digitalWrite(LED_YELLOW, HIGH);
else
digitalWrite(LED_YELLOW, LOW);
}
// Wait for a button to be pressed.
// Returns one of LED colors (LED_RED, etc.) if successful, 0 if timed out
byte wait_for_button(void)
{
long startTime = millis(); // Remember the time we started the this loop
while ( (millis() - startTime) < ENTRY_TIME_LIMIT) // Loop until too much time has passed
{
byte button = checkButton();
if (button != CHOICE_NONE)
{
toner(button, 150); // Play the button the user just pressed
while(checkButton() != CHOICE_NONE) ; // Now let's wait for user to release button
delay(10); // This helps with debouncing and accidental double taps
return button;
}
sbi(BUZZER1_PORT, BUZZER1);
cbi(BUZZER2_PORT, BUZZER2);
delay_us(buzz_delay_us);
} }
return CHOICE_NONE; // If we get here, we've timed out!
} }
/* // Returns a '1' bit in the position corresponding to CHOICE_RED, CHOICE_GREEN, etc.
Light an LED and play tone byte checkButton(void)
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)
{ {
set_leds(which); if (digitalRead(BUTTON_RED) == 0) return(CHOICE_RED);
switch (which) { else if (digitalRead(BUTTON_GREEN) == 0) return(CHOICE_GREEN);
case LED_RED: else if (digitalRead(BUTTON_BLUE) == 0) return(CHOICE_BLUE);
else if (digitalRead(BUTTON_YELLOW) == 0) return(CHOICE_YELLOW);
return(CHOICE_NONE); // If no button is pressed, return none
}
// 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(byte which, int buzz_length_ms)
{
setLEDs(which); //Turn on a given LED
//Play the sound associated with the given LED
switch(which)
{
case CHOICE_RED:
buzz_sound(buzz_length_ms, 1136); buzz_sound(buzz_length_ms, 1136);
break; break;
case CHOICE_GREEN:
case LED_GREEN:
buzz_sound(buzz_length_ms, 568); buzz_sound(buzz_length_ms, 568);
break; break;
case CHOICE_BLUE:
case LED_BLUE:
buzz_sound(buzz_length_ms, 851); buzz_sound(buzz_length_ms, 851);
break; break;
case CHOICE_YELLOW:
case LED_YELLOW:
buzz_sound(buzz_length_ms, 638); buzz_sound(buzz_length_ms, 638);
break; break;
} }
// Turn off all LEDs setLEDs(CHOICE_OFF); // Turn off all LEDs
set_leds(0); }
// Toggle buzzer every buzz_delay_us, for a duration of buzz_length_ms.
void buzz_sound(int buzz_length_ms, int buzz_delay_us)
{
// Convert total play time from milliseconds to microseconds
long buzz_length_us = buzz_length_ms * (long)1000;
// Loop until the remaining play time is less than a single buzz_delay_us
while (buzz_length_us > (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)
{
// Toggle the buzzer at various speeds
for (byte x = 250 ; x > 70 ; x--)
{
for (byte y = 0 ; y < 3 ; y++)
{
digitalWrite(BUZZER2, HIGH);
digitalWrite(BUZZER1, LOW);
delayMicroseconds(x);
digitalWrite(BUZZER2, LOW);
digitalWrite(BUZZER1, HIGH);
delayMicroseconds(x);
}
}
}
// Play the loser sound/lights
void play_loser(void)
{
setLEDs(CHOICE_RED | CHOICE_GREEN);
buzz_sound(255, 1500);
setLEDs(CHOICE_BLUE | CHOICE_YELLOW);
buzz_sound(255, 1500);
setLEDs(CHOICE_RED | CHOICE_GREEN);
buzz_sound(255, 1500);
setLEDs(CHOICE_BLUE | CHOICE_YELLOW);
buzz_sound(255, 1500);
} }
// Show an "attract mode" display while waiting for user to press button. // Show an "attract mode" display while waiting for user to press button.
void attract_mode(void) void attractMode(void)
{ {
while (1) { while(1)
set_leds(LED_RED);
delay_ms(100);
if (check_button() != 0x00)
return;
set_leds(LED_BLUE);
delay_ms(100);
if (check_button() != 0x00)
return;
set_leds(LED_GREEN);
delay_ms(100);
if (check_button() != 0x00)
return;
set_leds(LED_YELLOW);
delay_ms(100);
if (check_button() != 0x00)
return;
}
}
// 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 = TIME_LIMIT;
uint8_t released = 0;
uint8_t old_button;
while (time_limit > 0) {
uint8_t button;
// Implement a small bit of debouncing
old_button = button;
button = check_button();
// Make sure we've seen the previous button released before accepting new buttons
if (button == 0)
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) {
return button;
}
}
delay_ms(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(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; setLEDs(CHOICE_RED);
delay(100);
if (checkButton() != CHOICE_NONE) return;
// Add a button to the current moves, then play them back setLEDs(CHOICE_BLUE);
if(battle) delay(100);
add_to_moves_battle(); // If in battle mode, then listen for user input to choose the next step if (checkButton() != CHOICE_NONE) return;
else
add_to_moves();
if(battle) setLEDs(CHOICE_GREEN);
; // 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. delay(100);
else if (checkButton() != CHOICE_NONE) return;
play_moves();
// Then require the player to repeat the sequence. setLEDs(CHOICE_YELLOW);
for (move = 0; move < nmoves; move++) { delay(100);
uint8_t choice = wait_for_button(); if (checkButton() != CHOICE_NONE) return;
// If wait timed out, player loses.
if (choice == 0)
return 0;
toner(choice, 150);
// If the choice is incorect, player loses.
if (choice != moves[move]) {
return 0;
}
}
// Player was correct, delay before playing moves
if(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);
}
else
delay_ms(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();
}
} }
} }
// //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void beegees_loop() //The following functions are related to Beegees Easter Egg only
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
// 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); //Turn on the bottom right (yellow) LED
delay(400); setLEDs(CHOICE_YELLOW);
buzz(4); toner(CHOICE_YELLOW, 150);
rest(1);
delay(600); setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE); // Turn on the other LEDs until you release button
buzz(5);
rest(1); while(checkButton() != CHOICE_NONE) ; // Wait for user to stop pressing button
rest(1);
delay(400); setLEDs(CHOICE_NONE); // Turn off LEDs
buzz(3);
rest(1); delay(1000); // Wait a second before playing song
rest(1);
rest(1); while(checkButton() == CHOICE_NONE) //Play song until you press a button
buzz(2); {
rest(1); buzz(3);
buzz(1); delay(400);
buzz(2); buzz(4);
buzz(3); rest(1);
rest(1); delay(600);
buzz(1); buzz(5);
buzz(2); rest(1);
rest(1); rest(1);
buzz(3); delay(400);
rest(1); buzz(3);
rest(1); rest(1);
buzz(1); rest(1);
rest(1); rest(1);
buzz(2); buzz(2);
rest(1); rest(1);
buzz(3); buzz(1);
rest(1); buzz(2);
buzz(4); buzz(3);
rest(1); rest(1);
buzz(5); buzz(1);
rest(1); buzz(2);
delay(700); 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);
}
} }
// //
@ -568,21 +473,11 @@ void buzz(int tone){
int freq; int freq;
//5 different tones to select. Each tone is a different frequency. //5 different tones to select. Each tone is a different frequency.
if(tone == 1){ if(tone == 1) freq = 2000;
freq = 2000; if(tone == 2) freq = 1800;
} if(tone == 3) freq = 1500;
if(tone == 2){ if(tone == 4) freq = 1350;
freq = 1800; if(tone == 5) freq = 1110;
}
if(tone == 3){
freq = 1500;
}
if(tone == 4){
freq = 1350;
}
if(tone == 5){
freq = 1110;
}
//freq = (freq/2); //freq = (freq/2);
@ -593,46 +488,41 @@ void buzz(int tone){
count = 40; 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. // 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 to the next LED
change_led(); changeLED();
// this next for loop actually makes the buzzer pin move. // this next for loop actually makes the buzzer pin move.
// it uses the "count" variable to know how many times to play the frequency. // it uses the "count" variable to know how many times to play the frequency.
// -this keeps the timing correct. // -this keeps the timing correct.
for(int i = 0; i < count; i++){ for(int i = 0 ; i < count ; i++)
{
digitalWrite(BUZZER1, HIGH); digitalWrite(BUZZER1, HIGH);
digitalWrite(BUZZER2, LOW); digitalWrite(BUZZER2, LOW);
delayMicroseconds(freq); delayMicroseconds(freq);
digitalWrite(BUZZER1, LOW); digitalWrite(BUZZER1, LOW);
digitalWrite(BUZZER2, HIGH); digitalWrite(BUZZER2, HIGH);
delayMicroseconds(freq); delayMicroseconds(freq);
} }
delay(60); delay(60);
} }
// //
void rest(int tone){ void rest(int tone){
int freq; int freq;
if(tone == 1){ if(tone == 1) freq = 2000;
freq = 2000; if(tone == 2) freq = 1800;
} if(tone == 3) freq = 1500;
if(tone == 2){ if(tone == 4) freq = 1350;
freq = 1800; if(tone == 5) freq = 1110;
}
if(tone == 3){
freq = 1500;
}
if(tone == 4){
freq = 1350;
}
if(tone == 5){
freq = 1110;
}
//freq = (freq/2); //freq = (freq/2);
count = 40; count = 40;
count = count*(2000/freq); count = count * (2000/freq);
//change_led(); //change_led();
for(int i = 0 ; i < count ; i++) for(int i = 0 ; i < count ; i++)
@ -642,19 +532,18 @@ void rest(int tone){
digitalWrite(BUZZER1, LOW); digitalWrite(BUZZER1, LOW);
delayMicroseconds(freq); delayMicroseconds(freq);
} }
delay(75); delay(75);
} }
// // Each time this function is called the board moves to the next LED
void change_led() void changeLED(void)
{ {
if(counter > 3) setLEDs(1 << LEDnumber); // Change the LED
{
counter = 0; LEDnumber++; // Goto the next LED
} if(LEDnumber > 3) LEDnumber = 0; // Wrap the counter if needed
set_leds(1 << counter);
counter += 1;
} }

View File

@ -6,119 +6,70 @@
file attempts to map and support all the different hardware versions. 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. // 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_4_9_2009
#define BOARD_REV_PTH //#define BOARD_REV_6_25_2008
#ifdef BOARD_REV_PTH #ifdef BOARD_REV_2_3_2011
// LED pin definitions, these are Arduino pins, not ATmega pins
#define CHIP_ATMEGA168 #define LED_RED 10
#define LED_GREEN 3
#define LED_RED (1 << 0) #define LED_BLUE 13
#define LED_GREEN (1 << 1) #define LED_YELLOW 5
#define LED_BLUE (1 << 2)
#define LED_YELLOW (1 << 3) // Button pin definitions
#define BUTTON_RED 9
/* LED pin definitions */ #define BUTTON_GREEN 2
#define LED_RED_PIN 2 #define BUTTON_BLUE 12
#define LED_RED_PORT PORTB #define BUTTON_YELLOW 6
#define LED_GREEN_PIN 3
#define LED_GREEN_PORT PORTD // Buzzer pin definitions
#define LED_BLUE_PIN 5 #define BUZZER1 4
#define LED_BLUE_PORT PORTB #define BUZZER2 7
#define LED_YELLOW_PIN 5 #endif // End definition for BOARD_REV_2_3_2011
#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
/* Buzzer pin definitions */
#define BUZZER1 4
#define BUZZER1_PORT PORTD
#define BUZZER2 7
#define BUZZER2_PORT PORTD
#endif /* 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 */
#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 /* BOARD_REV_6_25_08 */
#ifdef BOARD_REV_4_9_2009 #ifdef BOARD_REV_4_9_2009
// 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
#define LED_RED (1 << 0) #ifdef BOARD_REV_6_25_2008
#define LED_GREEN (1 << 1) // LED pin definitions, these are Arduino pins, not ATmega pins
#define LED_BLUE (1 << 2) #define LED_RED A3 //PORTC.3
#define LED_YELLOW (1 << 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
#define CHIP_ATMEGA168
/* 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
#endif /* BOARD_REV_4_9_2009 */

3
readme.txt Normal file
View File

@ -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.