Guest User

isomorphic85-simon says

a guest
Jun 22nd, 2016
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.96 KB | None | 0 0
  1. /*************************************************
  2. * Public Constants
  3. *************************************************/
  4. #define NOTE_B0 31
  5. #define NOTE_C1 33
  6. #define NOTE_CS1 35
  7. #define NOTE_D1 37
  8. #define NOTE_DS1 39
  9. #define NOTE_E1 41
  10. #define NOTE_F1 44
  11. #define NOTE_FS1 46
  12. #define NOTE_G1 49
  13. #define NOTE_GS1 52
  14. #define NOTE_A1 55
  15. #define NOTE_AS1 58
  16. #define NOTE_B1 62
  17. #define NOTE_C2 65
  18. #define NOTE_CS2 69
  19. #define NOTE_D2 73
  20. #define NOTE_DS2 78
  21. #define NOTE_E2 82
  22. #define NOTE_F2 87
  23. #define NOTE_FS2 93
  24. #define NOTE_G2 98
  25. #define NOTE_GS2 104
  26. #define NOTE_A2 110
  27. #define NOTE_AS2 117
  28. #define NOTE_B2 123
  29. #define NOTE_C3 131
  30. #define NOTE_CS3 139
  31. #define NOTE_D3 147
  32. #define NOTE_DS3 156
  33. #define NOTE_E3 165
  34. #define NOTE_F3 175
  35. #define NOTE_FS3 185
  36. #define NOTE_G3 196
  37. #define NOTE_GS3 208
  38. #define NOTE_A3 220
  39. #define NOTE_AS3 233
  40. #define NOTE_B3 247
  41. #define NOTE_C4 262
  42. #define NOTE_CS4 277
  43. #define NOTE_D4 294
  44. #define NOTE_DS4 311
  45. #define NOTE_E4 330
  46. #define NOTE_F4 349
  47. #define NOTE_FS4 370
  48. #define NOTE_G4 392
  49. #define NOTE_GS4 415
  50. #define NOTE_A4 440
  51. #define NOTE_AS4 466
  52. #define NOTE_B4 494
  53. #define NOTE_C5 523
  54. #define NOTE_CS5 554
  55. #define NOTE_D5 587
  56. #define NOTE_DS5 622
  57. #define NOTE_E5 659
  58. #define NOTE_F5 698
  59. #define NOTE_FS5 740
  60. #define NOTE_G5 784
  61. #define NOTE_GS5 831
  62. #define NOTE_A5 880
  63. #define NOTE_AS5 932
  64. #define NOTE_B5 988
  65. #define NOTE_C6 1047
  66. #define NOTE_CS6 1109
  67. #define NOTE_D6 1175
  68. #define NOTE_DS6 1245
  69. #define NOTE_E6 1319
  70. #define NOTE_F6 1397
  71. #define NOTE_FS6 1480
  72. #define NOTE_G6 1568
  73. #define NOTE_GS6 1661
  74. #define NOTE_A6 1760
  75. #define NOTE_AS6 1865
  76. #define NOTE_B6 1976
  77. #define NOTE_C7 2093
  78. #define NOTE_CS7 2217
  79. #define NOTE_D7 2349
  80. #define NOTE_DS7 2489
  81. #define NOTE_E7 2637
  82. #define NOTE_F7 2794
  83. #define NOTE_FS7 2960
  84. #define NOTE_G7 3136
  85. #define NOTE_GS7 3322
  86. #define NOTE_A7 3520
  87. #define NOTE_AS7 3729
  88. #define NOTE_B7 3951
  89. #define NOTE_C8 4186
  90. #define NOTE_CS8 4435
  91. #define NOTE_D8 4699
  92. #define NOTE_DS8 4978
  93.  
  94. #define CHOICE_OFF 0 //Used to control LEDs
  95. #define CHOICE_NONE 0 //Used to check buttons
  96. #define CHOICE_RED (1 << 0)
  97. #define CHOICE_GREEN (1 << 1)
  98. #define CHOICE_BLUE (1 << 2)
  99. #define CHOICE_YELLOW (1 << 3)
  100. #define CHOICE_START
  101. #define BUTTON_START
  102.  
  103. #define LED_RED 10
  104. #define LED_GREEN 3
  105. #define LED_BLUE 13
  106. #define LED_YELLOW 5
  107.  
  108. // Button pin definitions
  109. #define BUTTON_RED 9
  110. #define BUTTON_GREEN 2
  111. #define BUTTON_BLUE 12
  112. #define BUTTON_YELLOW 6
  113. #define BUTTON_START 13
  114.  
  115. // Buzzer pin definitions
  116. #define BUZZER1 4
  117. #define BUZZER2 7
  118.  
  119. // Define game parameters
  120. #define ROUNDS_TO_WIN 13 //Number of rounds to succesfully remember before you win. 13 is do-able.
  121. #define ENTRY_TIME_LIMIT 3000 //Amount of time to press a button before game times out. 3000ms = 3 sec
  122.  
  123. #define MODE_MEMORY 0
  124. #define MODE_BATTLE 1
  125. #define MODE_BEEGEES 2
  126.  
  127. // Game state variables
  128. byte gameMode = MODE_MEMORY; //By default, let's play the memory game
  129. byte gameBoard[32]; //Contains the combination of buttons as we advance
  130. byte gameRound = 0; //Counts the number of succesful rounds the player has made it through
  131.  
  132. void setup()
  133. {
  134. //Setup hardware inputs/outputs. These pins are defined in the hardware_versions header file
  135.  
  136. //Enable pull ups on inputs
  137. pinMode(BUTTON_RED, INPUT_PULLUP);
  138. pinMode(BUTTON_GREEN, INPUT_PULLUP);
  139. pinMode(BUTTON_BLUE, INPUT_PULLUP);
  140. pinMode(BUTTON_YELLOW, INPUT_PULLUP);
  141. pinMode(BUTTON_START, INPUT_PULLUP);
  142.  
  143. pinMode(LED_RED, OUTPUT);
  144. pinMode(LED_GREEN, OUTPUT);
  145. pinMode(LED_BLUE, OUTPUT);
  146. pinMode(LED_YELLOW, OUTPUT);
  147.  
  148. pinMode(BUZZER1, OUTPUT);
  149. pinMode(BUZZER2, OUTPUT);
  150.  
  151. //Mode checking
  152. gameMode = MODE_MEMORY; // By default, we're going to play the memory game
  153.  
  154. // Check to see if the lower right button is pressed
  155. if (checkButton() == CHOICE_YELLOW) play_beegees();
  156.  
  157. // Check to see if upper right button is pressed
  158. if (checkButton() == CHOICE_GREEN)
  159. {
  160. gameMode = MODE_BATTLE; //Put game into battle mode
  161.  
  162. //Turn on the upper right (green) LED
  163. setLEDs(CHOICE_GREEN);
  164. toner(CHOICE_GREEN, 150);
  165.  
  166. setLEDs(CHOICE_RED | CHOICE_BLUE | CHOICE_YELLOW); // Turn on the other LEDs until you release button
  167.  
  168. while(checkButton() != CHOICE_NONE) ; // Wait for user to stop pressing button
  169.  
  170. //Now do nothing. Battle mode will be serviced in the main routine
  171. }
  172.  
  173. play_winner(); // After setup is complete, say hello to the world
  174. }
  175.  
  176. void loop()
  177. {
  178. attractMode(); // Blink lights while waiting for user to press a button
  179.  
  180. // Indicate the start of game play
  181. setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE | CHOICE_YELLOW); // Turn all LEDs on
  182. delay(1000);
  183. setLEDs(CHOICE_OFF); // Turn off LEDs
  184. delay(250);
  185.  
  186. if (gameMode == MODE_MEMORY)
  187. {
  188. // Play memory game and handle result
  189. if (play_memory() == true)
  190. play_winner(); // Player won, play winner tones
  191. else
  192. play_loser(); // Player lost, play loser tones
  193. }
  194.  
  195. if (gameMode == MODE_BATTLE)
  196. {
  197. play_battle(); // Play game until someone loses
  198.  
  199. play_loser(); // Player lost, play loser tones
  200. }
  201. }
  202.  
  203. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  204. //The following functions are related to game play only
  205.  
  206. // Play the regular memory game
  207. // Returns 0 if player loses, or 1 if player wins
  208. boolean play_memory(void)
  209. {
  210. randomSeed(millis()); // Seed the random generator with random amount of millis()
  211.  
  212. gameRound = 0; // Reset the game to the beginning
  213.  
  214. while (gameRound < ROUNDS_TO_WIN)
  215. {
  216. add_to_moves(); // Add a button to the current moves, then play them back
  217.  
  218. playMoves(); // Play back the current game board
  219.  
  220. // Then require the player to repeat the sequence.
  221. for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
  222. {
  223. byte choice = wait_for_button(); // See what button the user presses
  224.  
  225. if (choice == 0) return false; // If wait timed out, player loses
  226.  
  227. if (choice != gameBoard[currentMove]) return false; // If the choice is incorect, player loses
  228. }
  229.  
  230. delay(1000); // Player was correct, delay before playing moves
  231. }
  232.  
  233. return true; // Player made it through all the rounds to win!
  234. }
  235.  
  236. // Play the special 2 player battle mode
  237. // A player begins by pressing a button then handing it to the other player
  238. // That player repeats the button and adds one, then passes back.
  239. // This function returns when someone loses
  240. boolean play_battle(void)
  241. {
  242. gameRound = 0; // Reset the game frame back to one frame
  243.  
  244. while (1) // Loop until someone fails
  245. {
  246. byte newButton = wait_for_button(); // Wait for user to input next move
  247. gameBoard[gameRound++] = newButton; // Add this new button to the game array
  248.  
  249. // Then require the player to repeat the sequence.
  250. for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
  251. {
  252. byte choice = wait_for_button();
  253.  
  254. if (choice == 0) return false; // If wait timed out, player loses.
  255.  
  256. if (choice != gameBoard[currentMove]) return false; // If the choice is incorect, player loses.
  257. }
  258.  
  259. delay(100); // Give the user an extra 100ms to hand the game to the other player
  260. }
  261.  
  262. return true; // We should never get here
  263. }
  264.  
  265. // Plays the current contents of the game moves
  266. void playMoves(void)
  267. {
  268. for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
  269. {
  270. toner(gameBoard[currentMove], 150);
  271.  
  272. // Wait some amount of time between button playback
  273. // Shorten this to make game harder
  274. delay(150); // 150 works well. 75 gets fast.
  275. }
  276. }
  277.  
  278. // Adds a new random button to the game sequence, by sampling the timer
  279. void add_to_moves(void)
  280. {
  281. byte newButton = random(0, 4); //min (included), max (exluded)
  282.  
  283. // We have to convert this number, 0 to 3, to CHOICEs
  284. if(newButton == 0) newButton = CHOICE_RED;
  285. else if(newButton == 1) newButton = CHOICE_GREEN;
  286. else if(newButton == 2) newButton = CHOICE_BLUE;
  287. else if(newButton == 3) newButton = CHOICE_YELLOW;
  288.  
  289. gameBoard[gameRound++] = newButton; // Add this new button to the game array
  290. }
  291.  
  292. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  293. //The following functions control the hardware
  294.  
  295. // Lights a given LEDs
  296. // Pass in a byte that is made up from CHOICE_RED, CHOICE_YELLOW, etc
  297. void setLEDs(byte leds)
  298. {
  299. if ((leds & CHOICE_RED) != 0)
  300. digitalWrite(LED_RED, HIGH);
  301. else
  302. digitalWrite(LED_RED, LOW);
  303.  
  304. if ((leds & CHOICE_GREEN) != 0)
  305. digitalWrite(LED_GREEN, HIGH);
  306. else
  307. digitalWrite(LED_GREEN, LOW);
  308.  
  309. if ((leds & CHOICE_BLUE) != 0)
  310. digitalWrite(LED_BLUE, HIGH);
  311. else
  312. digitalWrite(LED_BLUE, LOW);
  313.  
  314. if ((leds & CHOICE_YELLOW) != 0)
  315. digitalWrite(LED_YELLOW, HIGH);
  316. else
  317. digitalWrite(LED_YELLOW, LOW);
  318. }
  319.  
  320. // Wait for a button to be pressed.
  321. // Returns one of LED colors (LED_RED, etc.) if successful, 0 if timed out
  322. byte wait_for_button(void)
  323. {
  324. long startTime = millis(); // Remember the time we started the this loop
  325.  
  326. while ( (millis() - startTime) < ENTRY_TIME_LIMIT) // Loop until too much time has passed
  327. {
  328. byte button = checkButton();
  329.  
  330. if (button != CHOICE_NONE)
  331. {
  332. toner(button, 150); // Play the button the user just pressed
  333.  
  334. while(checkButton() != CHOICE_NONE) ; // Now let's wait for user to release button
  335.  
  336. delay(10); // This helps with debouncing and accidental double taps
  337.  
  338. return button;
  339. }
  340.  
  341. }
  342.  
  343. return CHOICE_NONE; // If we get here, we've timed out!
  344. }
  345.  
  346. // Returns a '1' bit in the position corresponding to CHOICE_RED, CHOICE_GREEN, etc.
  347. byte checkButton(void)
  348. {
  349. if (digitalRead(BUTTON_RED) == 0) return(CHOICE_RED);
  350. else if (digitalRead(BUTTON_GREEN) == 0) return(CHOICE_GREEN);
  351. else if (digitalRead(BUTTON_BLUE) == 0) return(CHOICE_BLUE);
  352. else if (digitalRead(BUTTON_YELLOW) == 0) return(CHOICE_YELLOW);
  353.  
  354. return(CHOICE_NONE); // If no button is pressed, return none
  355. }
  356.  
  357. // Light an LED and play tone
  358. // Red, upper left: 440Hz - 2.272ms - 1.136ms pulse
  359. // Green, upper right: 880Hz - 1.136ms - 0.568ms pulse
  360. // Blue, lower left: 587.33Hz - 1.702ms - 0.851ms pulse
  361. // Yellow, lower right: 784Hz - 1.276ms - 0.638ms pulse
  362. void toner(byte which, int buzz_length_ms)
  363. {
  364. setLEDs(which); //Turn on a given LED
  365.  
  366. //Play the sound associated with the given LED
  367. switch(which)
  368. {
  369. case CHOICE_RED:
  370. buzz_sound(buzz_length_ms, 1136);
  371. break;
  372. case CHOICE_GREEN:
  373. buzz_sound(buzz_length_ms, 568);
  374. break;
  375. case CHOICE_BLUE:
  376. buzz_sound(buzz_length_ms, 851);
  377. break;
  378. case CHOICE_YELLOW:
  379. buzz_sound(buzz_length_ms, 638);
  380. break;
  381. }
  382.  
  383. setLEDs(CHOICE_OFF); // Turn off all LEDs
  384. }
  385.  
  386. // Toggle buzzer every buzz_delay_us, for a duration of buzz_length_ms.
  387. void buzz_sound(int buzz_length_ms, int buzz_delay_us)
  388. {
  389. // Convert total play time from milliseconds to microseconds
  390. long buzz_length_us = buzz_length_ms * (long)1000;
  391.  
  392. // Loop until the remaining play time is less than a single buzz_delay_us
  393. while (buzz_length_us > (buzz_delay_us * 2))
  394. {
  395. buzz_length_us -= buzz_delay_us * 2; //Decrease the remaining play time
  396.  
  397. // Toggle the buzzer at various speeds
  398. digitalWrite(BUZZER1, LOW);
  399. digitalWrite(BUZZER2, HIGH);
  400. delayMicroseconds(buzz_delay_us);
  401.  
  402. digitalWrite(BUZZER1, HIGH);
  403. digitalWrite(BUZZER2, LOW);
  404. delayMicroseconds(buzz_delay_us);
  405. }
  406. }
  407.  
  408. // Play the winner sound and lights
  409. void play_winner(void)
  410. {
  411. setLEDs(CHOICE_GREEN | CHOICE_BLUE);
  412. winner_sound();
  413. setLEDs(CHOICE_RED | CHOICE_YELLOW);
  414. winner_sound();
  415. setLEDs(CHOICE_GREEN | CHOICE_BLUE);
  416. winner_sound();
  417. setLEDs(CHOICE_RED | CHOICE_YELLOW);
  418. winner_sound();
  419. }
  420.  
  421. // Play the winner sound
  422. // This is just a unique sound, there is no magic to it
  423. void winner_sound(void)
  424. {
  425. // Toggle the buzzer at various speeds
  426. for (byte x = 250 ; x > 70 ; x--)
  427. {
  428. for (byte y = 0 ; y < 3 ; y++)
  429. {
  430. digitalWrite(BUZZER2, HIGH);
  431. digitalWrite(BUZZER1, LOW);
  432. delayMicroseconds(x);
  433.  
  434. digitalWrite(BUZZER2, LOW);
  435. digitalWrite(BUZZER1, HIGH);
  436. delayMicroseconds(x);
  437. }
  438. }
  439. }
  440.  
  441. // Play the loser sound/lights
  442. void play_loser(void)
  443. {
  444. setLEDs(CHOICE_RED | CHOICE_GREEN);
  445. buzz_sound(255, 1500);
  446.  
  447. setLEDs(CHOICE_BLUE | CHOICE_YELLOW);
  448. buzz_sound(255, 1500);
  449.  
  450. setLEDs(CHOICE_RED | CHOICE_GREEN);
  451. buzz_sound(255, 1500);
  452.  
  453. setLEDs(CHOICE_BLUE | CHOICE_YELLOW);
  454. buzz_sound(255, 1500);
  455. }
  456.  
  457. // Show an "attract mode" display while waiting for user to press button.
  458. void attractMode(void)
  459. {
  460. while(1)
  461. {
  462. setLEDs(CHOICE_RED);
  463. delay(100);
  464. if (checkButton() != CHOICE_NONE) return;
  465.  
  466. setLEDs(CHOICE_BLUE);
  467. delay(100);
  468. if (checkButton() != CHOICE_NONE) return;
  469.  
  470. setLEDs(CHOICE_GREEN);
  471. delay(100);
  472. if (checkButton() != CHOICE_NONE) return;
  473.  
  474. setLEDs(CHOICE_YELLOW);
  475. delay(100);
  476. if (checkButton() != CHOICE_NONE) return;
  477. }
  478. }
  479.  
  480. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  481. // The following functions are related to Beegees Easter Egg only
  482.  
  483. // Notes in the melody. Each note is about an 1/8th note, "0"s are rests.
  484. int melody[] = {
  485. NOTE_G4, NOTE_A4, 0, NOTE_C5, 0, 0, NOTE_G4, 0, 0, 0,
  486. NOTE_E4, 0, NOTE_D4, NOTE_E4, NOTE_G4, 0,
  487. NOTE_D4, NOTE_E4, 0, NOTE_G4, 0, 0,
  488. NOTE_D4, 0, NOTE_E4, 0, NOTE_G4, 0, NOTE_A4, 0, NOTE_C5, 0};
  489.  
  490. int noteDuration = 115; // This essentially sets the tempo, 115 is just about right for a disco groove :)
  491. int LEDnumber = 0; // Keeps track of which LED we are on during the beegees loop
  492.  
  493. // Do nothing but play bad beegees music
  494. // This function is activated when user holds bottom right button during power up
  495. void play_beegees()
  496. {
  497. //Turn on the bottom right (yellow) LED
  498. setLEDs(CHOICE_YELLOW);
  499. toner(CHOICE_YELLOW, 150);
  500.  
  501. setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE); // Turn on the other LEDs until you release button
  502.  
  503. while(checkButton() != CHOICE_NONE) ; // Wait for user to stop pressing button
  504.  
  505. setLEDs(CHOICE_NONE); // Turn off LEDs
  506.  
  507. delay(1000); // Wait a second before playing song
  508.  
  509. digitalWrite(BUZZER1, LOW); // setup the "BUZZER1" side of the buzzer to stay low, while we play the tone on the other pin.
  510.  
  511. while(checkButton() == CHOICE_NONE) //Play song until you press a button
  512. {
  513. // iterate over the notes of the melody:
  514. for (int thisNote = 0; thisNote < 32; thisNote++) {
  515. changeLED();
  516. tone(BUZZER2, melody[thisNote],noteDuration);
  517. // to distinguish the notes, set a minimum time between them.
  518. // the note's duration + 30% seems to work well:
  519. int pauseBetweenNotes = noteDuration * 1.30;
  520. delay(pauseBetweenNotes);
  521. // stop the tone playing:
  522. noTone(BUZZER2);
  523. }
  524. }
  525. }
  526.  
  527. // Each time this function is called the board moves to the next LED
  528. void changeLED(void)
  529. {
  530. setLEDs(1 << LEDnumber); // Change the LED
  531.  
  532. LEDnumber++; // Goto the next LED
  533. if(LEDnumber > 3) LEDnumber = 0; // Wrap the counter if needed
  534. }
Add Comment
Please, Sign In to add comment