A simple Simon Says game using a Grove Base Shield, 3 Grove LED Bars, 1 Grove Buzzer, and 3 Grove Buttons.

Dependencies:   LED_Bar mbed

Components Used

Platform: ST-Nucleo-F401RE

Components / Grove Shield V2
As an expansion board, Base Shield v2 has many Grove connectors, making it convenient for you to use Grove products together
Digital on / off buzzer
Seeed Grove Button module with digital interface
The Grove LED Bar is comprised of a 10 segment LED gauge bar and an MY9221 LED controlling chip.

Component Configuration

LED_Bar mid(D6, D5);    //D5
LED_Bar right(D8, D7);  //D7
LED_Bar left(D4, D3);   //D3
InterruptIn button_left(A2);
InterruptIn button_mid(A1);
InterruptIn button_right(A0);
DigitalOut buzzer(D2);

Gallery

Committer:
jplunkett
Date:
Fri Aug 19 16:42:40 2016 +0000
Revision:
11:2307c5edf18f
Parent:
10:9d48af13dbd0
Child:
12:73cbf84ee24a
added more comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jplunkett 0:67efb4657416 1 #include "mbed.h"
jplunkett 0:67efb4657416 2 #include "LED_Bar.h"
jplunkett 0:67efb4657416 3
jplunkett 6:1c87edbbafe0 4 LED_Bar mid(D6, D5);
jplunkett 6:1c87edbbafe0 5 LED_Bar right(D8, D7);
jplunkett 6:1c87edbbafe0 6 LED_Bar left(D4, D3);
jplunkett 6:1c87edbbafe0 7 InterruptIn button_left(A2);
jplunkett 6:1c87edbbafe0 8 InterruptIn button_mid(A1);
jplunkett 6:1c87edbbafe0 9 InterruptIn button_right(A0);
jplunkett 6:1c87edbbafe0 10 DigitalOut buzzer(D2);
jplunkett 11:2307c5edf18f 11 /* due to the type of InterruptIn .rise function call I am using (callback to
jplunkett 11:2307c5edf18f 12 a void function), the input array has to be global since you can't use
jplunkett 11:2307c5edf18f 13 input parameters (to my knowledge in the interrupted void function */
jplunkett 6:1c87edbbafe0 14 int input_index;
jplunkett 6:1c87edbbafe0 15 int input[100];
jplunkett 5:b6f37ce2a9a3 16 bool start_flag = false;
jplunkett 5:b6f37ce2a9a3 17
jplunkett 10:9d48af13dbd0 18 /* start the game: animation/buzzer sounds */
jplunkett 6:1c87edbbafe0 19 void start_level() {
jplunkett 10:9d48af13dbd0 20 for(int i = 0; i < 3; i++) {
jplunkett 6:1c87edbbafe0 21 right.setLevel(10);
jplunkett 6:1c87edbbafe0 22 mid.setLevel(10);
jplunkett 6:1c87edbbafe0 23 left.setLevel(10);
jplunkett 9:ac887bf9f85d 24 buzzer = 1;
jplunkett 9:ac887bf9f85d 25 wait(0.4 - i*0.1);
jplunkett 6:1c87edbbafe0 26 right.setLevel(0);
jplunkett 6:1c87edbbafe0 27 mid.setLevel(0);
jplunkett 6:1c87edbbafe0 28 left.setLevel(0);
jplunkett 9:ac887bf9f85d 29 buzzer = 0;
jplunkett 9:ac887bf9f85d 30 wait(0.4 - i*0.1);
jplunkett 6:1c87edbbafe0 31 }
jplunkett 5:b6f37ce2a9a3 32 start_flag = true;
jplunkett 5:b6f37ce2a9a3 33 }
jplunkett 1:1aca092ceb7e 34
jplunkett 6:1c87edbbafe0 35 /* generate random simon says sequence:
jplunkett 6:1c87edbbafe0 36 level 1 will have a 3 LED blink combination, with each subsequent level
jplunkett 6:1c87edbbafe0 37 having 1 more LED blink, so level 2 has a 4 blink combination, etc. */
jplunkett 8:7be76afe5597 38 int level(int level_index, int sequence_size, int* sequence) {
jplunkett 6:1c87edbbafe0 39 for(int i = 0; i < sequence_size; i++) {
jplunkett 6:1c87edbbafe0 40 sequence[i] = rand() % 3 + 1;
jplunkett 2:8ff96f7acb45 41 }
jplunkett 5:b6f37ce2a9a3 42 button_right.rise(&start_level);
jplunkett 6:1c87edbbafe0 43 button_mid.rise(&start_level);
jplunkett 5:b6f37ce2a9a3 44 button_left.rise(&start_level);
jplunkett 5:b6f37ce2a9a3 45 while(!start_flag) {
jplunkett 9:ac887bf9f85d 46 wait(0.1);
jplunkett 5:b6f37ce2a9a3 47 }
jplunkett 6:1c87edbbafe0 48 return level_index++;
jplunkett 2:8ff96f7acb45 49 }
jplunkett 2:8ff96f7acb45 50
jplunkett 2:8ff96f7acb45 51 /* simon says loop: turn on corresponding LED Bars according to the #
jplunkett 6:1c87edbbafe0 52 in the sequence array (1=right, 2=mid, 3=left) */
jplunkett 8:7be76afe5597 53 void simon_loop(int sequence_size, int* sequence) {
jplunkett 4:9950f9ec46cf 54 for(int i = 0; i < sequence_size; i++) {
jplunkett 1:1aca092ceb7e 55 if (sequence[i] == 1) {
jplunkett 1:1aca092ceb7e 56 right.setLevel(10);
jplunkett 1:1aca092ceb7e 57 wait(0.4);
jplunkett 1:1aca092ceb7e 58 right.setLevel(0);
jplunkett 5:b6f37ce2a9a3 59 } else if (sequence[i] == 2) {
jplunkett 6:1c87edbbafe0 60 mid.setLevel(10);
jplunkett 1:1aca092ceb7e 61 wait(0.4);
jplunkett 6:1c87edbbafe0 62 mid.setLevel(0);
jplunkett 5:b6f37ce2a9a3 63 } else {
jplunkett 1:1aca092ceb7e 64 left.setLevel(10);
jplunkett 1:1aca092ceb7e 65 wait(0.4);
jplunkett 1:1aca092ceb7e 66 left.setLevel(0);
jplunkett 1:1aca092ceb7e 67 }
jplunkett 9:ac887bf9f85d 68 wait(0.4);
jplunkett 1:1aca092ceb7e 69 }
jplunkett 1:1aca092ceb7e 70 }
jplunkett 1:1aca092ceb7e 71
jplunkett 11:2307c5edf18f 72 /* void callback functions for the InterruptIn buttons - write a button index
jplunkett 11:2307c5edf18f 73 to the input global array depending on which button was pressed */
jplunkett 4:9950f9ec46cf 74 void right_input() {
jplunkett 4:9950f9ec46cf 75 input[input_index] = 1;
jplunkett 5:b6f37ce2a9a3 76 input_index++;
jplunkett 4:9950f9ec46cf 77 while(button_right) {
jplunkett 4:9950f9ec46cf 78 right.setLevel(10);
jplunkett 4:9950f9ec46cf 79 }
jplunkett 4:9950f9ec46cf 80 right.setLevel(0);
jplunkett 4:9950f9ec46cf 81 }
jplunkett 4:9950f9ec46cf 82
jplunkett 6:1c87edbbafe0 83 void mid_input() {
jplunkett 4:9950f9ec46cf 84 input[input_index] = 2;
jplunkett 5:b6f37ce2a9a3 85 input_index++;
jplunkett 6:1c87edbbafe0 86 while(button_mid) {
jplunkett 6:1c87edbbafe0 87 mid.setLevel(10);
jplunkett 4:9950f9ec46cf 88 }
jplunkett 6:1c87edbbafe0 89 mid.setLevel(0);
jplunkett 4:9950f9ec46cf 90 }
jplunkett 4:9950f9ec46cf 91
jplunkett 4:9950f9ec46cf 92 void left_input() {
jplunkett 4:9950f9ec46cf 93 input[input_index] = 3;
jplunkett 5:b6f37ce2a9a3 94 input_index++;
jplunkett 4:9950f9ec46cf 95 while(button_left) {
jplunkett 4:9950f9ec46cf 96 left.setLevel(10);
jplunkett 4:9950f9ec46cf 97 }
jplunkett 4:9950f9ec46cf 98 left.setLevel(0);
jplunkett 4:9950f9ec46cf 99 }
jplunkett 4:9950f9ec46cf 100
jplunkett 6:1c87edbbafe0 101 /* gather user input based on buttons pressed, then store button index into
jplunkett 6:1c87edbbafe0 102 the input array (1=button_right, 2=button_mid, 3=button_left) */
jplunkett 7:b2576b2b916e 103 void input_loop(int sequence_size) {
jplunkett 6:1c87edbbafe0 104 button_right.rise(&right_input);
jplunkett 6:1c87edbbafe0 105 button_mid.rise(&mid_input);
jplunkett 4:9950f9ec46cf 106 button_left.rise(&left_input);
jplunkett 5:b6f37ce2a9a3 107 while(input_index < sequence_size) {
jplunkett 4:9950f9ec46cf 108 wait(0.2);
jplunkett 1:1aca092ceb7e 109 }
jplunkett 5:b6f37ce2a9a3 110 input_index = 0;
jplunkett 1:1aca092ceb7e 111 }
jplunkett 1:1aca092ceb7e 112
jplunkett 2:8ff96f7acb45 113 /* compare input array to simon says sequence array, if they are a match
jplunkett 2:8ff96f7acb45 114 return true, if they are not a match return false */
jplunkett 8:7be76afe5597 115 bool win_or_lose(int sequence_size, int* sequence) {
jplunkett 4:9950f9ec46cf 116 for(int k = 0; k < sequence_size; k++) {
jplunkett 1:1aca092ceb7e 117 if (input[k] == sequence[k]) { continue; }
jplunkett 1:1aca092ceb7e 118 else { return false; }
jplunkett 1:1aca092ceb7e 119 }
jplunkett 1:1aca092ceb7e 120 return true;
jplunkett 1:1aca092ceb7e 121 }
jplunkett 1:1aca092ceb7e 122
jplunkett 3:96879db74ec8 123 /* display a happy LED animation for winning (LED levels 0 to 10 fast) */
jplunkett 1:1aca092ceb7e 124 void success() {
jplunkett 6:1c87edbbafe0 125 for(int i = 0; i < 2; i ++){
jplunkett 6:1c87edbbafe0 126 for(int h = 0; h <=10; h++){
jplunkett 6:1c87edbbafe0 127 mid.setLevel(h);
jplunkett 6:1c87edbbafe0 128 right.setLevel(h);
jplunkett 6:1c87edbbafe0 129 left.setLevel(h);
jplunkett 6:1c87edbbafe0 130 wait(0.05);
jplunkett 6:1c87edbbafe0 131 }
jplunkett 6:1c87edbbafe0 132 }
jplunkett 1:1aca092ceb7e 133 }
jplunkett 1:1aca092ceb7e 134
jplunkett 2:8ff96f7acb45 135 /* display a sad LED animation for losing (LED levels 10 to 0 slow) */
jplunkett 1:1aca092ceb7e 136 void failure() {
jplunkett 1:1aca092ceb7e 137 for(int g = 0; g <= 10; g++){
jplunkett 6:1c87edbbafe0 138 mid.setLevel(10-g);
jplunkett 1:1aca092ceb7e 139 right.setLevel(10-g);
jplunkett 1:1aca092ceb7e 140 left.setLevel(10-g);
jplunkett 1:1aca092ceb7e 141 wait(0.1);
jplunkett 1:1aca092ceb7e 142 }
jplunkett 1:1aca092ceb7e 143 }
jplunkett 0:67efb4657416 144
jplunkett 3:96879db74ec8 145 int main() {
jplunkett 6:1c87edbbafe0 146 int win_count = 0;
jplunkett 6:1c87edbbafe0 147 int lose_count = 0;
jplunkett 6:1c87edbbafe0 148 int level_index = 1;
jplunkett 7:b2576b2b916e 149 int sequence_size = 2;
jplunkett 8:7be76afe5597 150 int sequence[100];
jplunkett 6:1c87edbbafe0 151 while(1) {
jplunkett 6:1c87edbbafe0 152 input_index = 0;
jplunkett 6:1c87edbbafe0 153 mid.setLevel(0);
jplunkett 6:1c87edbbafe0 154 right.setLevel(0);
jplunkett 6:1c87edbbafe0 155 left.setLevel(0);
jplunkett 7:b2576b2b916e 156 sequence_size++;
jplunkett 8:7be76afe5597 157 level_index = level(level_index, sequence_size, sequence);
jplunkett 8:7be76afe5597 158 simon_loop(sequence_size, sequence);
jplunkett 7:b2576b2b916e 159 input_loop(sequence_size);
jplunkett 6:1c87edbbafe0 160 wait(0.3);
jplunkett 8:7be76afe5597 161 bool winner = win_or_lose(sequence_size, sequence);
jplunkett 6:1c87edbbafe0 162 if (winner == true) {
jplunkett 6:1c87edbbafe0 163 win_count++;
jplunkett 6:1c87edbbafe0 164 success();
jplunkett 6:1c87edbbafe0 165 } else {
jplunkett 6:1c87edbbafe0 166 lose_count++;
jplunkett 6:1c87edbbafe0 167 failure();
jplunkett 6:1c87edbbafe0 168 }
jplunkett 11:2307c5edf18f 169 if (lose_count > 0) { // user lost so reset counter/level variables
jplunkett 6:1c87edbbafe0 170 start_flag = false;
jplunkett 6:1c87edbbafe0 171 win_count = 0;
jplunkett 6:1c87edbbafe0 172 lose_count = 0;
jplunkett 7:b2576b2b916e 173 level_index = 1;
jplunkett 7:b2576b2b916e 174 sequence_size = 2;
jplunkett 6:1c87edbbafe0 175 }
jplunkett 6:1c87edbbafe0 176 }
jplunkett 5:b6f37ce2a9a3 177 }