Arduino Arduino ile Simon Says Oyunu By Konuk Yazar Posted on 27 Ekim 2017 24 min read 10 0 19,445 Paylaş ! Facebook Paylaş ! Twitter Paylaş ! Google+ Paylaş ! Reddit Paylaş ! Pinterest Paylaş ! Linkedin Paylaş ! Tumblr Simon Says oyunu bir çeşit Zeka oyunudur. Oyunumuzun amacı yanan ledlerin sırasını zihnimizde ezberleyip o sıralama ile butonlara basmak. Malzemelerimiz : Arduino 4 adet buton 4 adet led 1 adet buzzer breadboard oyunumuzun mantığını bir nebze çözdüysek hadi devre şemamızı inceleyelim DEVRE ŞEMASI : Devre şemasını birde beraber inceleyelim 4 adet led var (farklı renklerde seçmeniz tavsiyedir) ve bu 4 ledi temsil eden 4 adet butonumuz var devremizdeki uyumun senkronizasyonu ve ses içinde 1 adet buzzer kullandık. Devremiz hazırsa kodumuzu yazmaya başlayalım… KOD : #define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978 #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) #define LED_RED 8 #define LED_GREEN 9 #define LED_BLUE 10 #define LED_YELLOW 11 // Button pin definitions #define BUTTON_RED 2 #define BUTTON_GREEN 3 #define BUTTON_BLUE 4 #define BUTTON_YELLOW 5 // Buzzer pin definitions #define BUZZER1 12 #define BUZZER2 13 // Define game parameters #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 // Game state variables 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 void setup() { //Setup hardware inputs/outputs. These pins are defined in the hardware_versions header file //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); pinMode(LED_RED, OUTPUT); pinMode(LED_GREEN, OUTPUT); pinMode(LED_BLUE, OUTPUT); pinMode(LED_YELLOW, OUTPUT); 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) { gameMode = MODE_BATTLE; //Put game into battle mode //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 } play_winner(); // After setup is complete, say hello to the world } void loop() { attractMode(); // Blink lights while waiting for user to press a button // 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 } } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //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) { randomSeed(millis()); // Seed the random generator with random amount of millis() gameRound = 0; // Reset the game to the beginning while (gameRound < ROUNDS_TO_WIN) { add_to_moves(); // Add a button to the current moves, then play them back playMoves(); // Play back the current game board // Then require the player to repeat the sequence. for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++) { byte choice = wait_for_button(); // See what button the user presses 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(1000); // Player was correct, delay before playing moves } return true; // Player made it through all the rounds to win! } // Play the special 2 player battle mode // 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) { gameRound = 0; // Reset the game frame back to one frame while (1) // Loop until someone fails { byte newButton = wait_for_button(); // Wait for user to input next move gameBoard[gameRound++] = newButton; // Add this new button to the game array // 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 void playMoves(void) { for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++) { toner(gameBoard[currentMove], 150); // Wait some amount of time between button playback // Shorten this to make game harder delay(150); // 150 works well. 75 gets fast. } } // Adds a new random button to the game sequence, by sampling the timer void add_to_moves(void) { byte newButton = random(0, 4); //min (included), max (exluded) // We have to convert this number, 0 to 3, to CHOICEs 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; gameBoard[gameRound++] = newButton; // Add this new button to the game array } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //The following functions control the hardware // Lights a given LEDs // Pass in a byte that is made up from CHOICE_RED, CHOICE_YELLOW, etc void setLEDs(byte leds) { 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); 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); } // 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; } } 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. byte checkButton(void) { if (digitalRead(BUTTON_RED) == 0) return(CHOICE_RED); else if (digitalRead(BUTTON_GREEN) == 0) return(CHOICE_GREEN); 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); break; case CHOICE_GREEN: buzz_sound(buzz_length_ms, 568); break; case CHOICE_BLUE: buzz_sound(buzz_length_ms, 851); break; case CHOICE_YELLOW: buzz_sound(buzz_length_ms, 638); break; } setLEDs(CHOICE_OFF); // Turn off all LEDs } // 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. void attractMode(void) { while(1) { setLEDs(CHOICE_RED); delay(100); if (checkButton() != CHOICE_NONE) return; setLEDs(CHOICE_BLUE); delay(100); if (checkButton() != CHOICE_NONE) return; setLEDs(CHOICE_GREEN); delay(100); if (checkButton() != CHOICE_NONE) return; setLEDs(CHOICE_YELLOW); delay(100); if (checkButton() != CHOICE_NONE) return; } } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // The following functions are related to Beegees Easter Egg only // Notes in the melody. Each note is about an 1/8th note, “0”s are rests. int melody[] = { NOTE_G4, NOTE_A4, 0, NOTE_C5, 0, 0, NOTE_G4, 0, 0, 0, NOTE_E4, 0, NOTE_D4, NOTE_E4, NOTE_G4, 0, NOTE_D4, NOTE_E4, 0, NOTE_G4, 0, 0, NOTE_D4, 0, NOTE_E4, 0, NOTE_G4, 0, NOTE_A4, 0, NOTE_C5, 0}; int noteDuration = 115; // This essentially sets the tempo, 115 is just about right for a disco groove 🙂 int LEDnumber = 0; // Keeps track of which LED we are on during 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() { //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 digitalWrite(BUZZER1, LOW); // setup the “BUZZER1” side of the buzzer to stay low, while we play the tone on the other pin. while(checkButton() == CHOICE_NONE) //Play song until you press a button { // iterate over the notes of the melody: for (int thisNote = 0; thisNote < 32; thisNote++) { changeLED(); tone(BUZZER2, melody[thisNote],noteDuration); // to distinguish the notes, set a minimum time between them. // the note’s duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: noTone(BUZZER2); } } } // Each time this function is called the board moves to the next LED void changeLED(void) { setLEDs(1 << LEDnumber); // Change the LED LEDnumber++; // Goto the next LED if(LEDnumber > 3) LEDnumber = 0; // Wrap the counter if needed } Kodumuzu yazdıktan sonra oyunumuzu oynayabiliriz. Eğlenceli oyunlar 🙂