Super Simon

Start 

Using the additional buttons in Weather Station 2 we'll be creating a closer representation of the classic game Simon.

Modules 

Gather the following parts to complete this project.

Parts

All Parts
All Parts
Button
Touch
RGB LED
Cable
PartQuantity
Button 3
Touch 1
RGB LED 1
Cable 5

Buttons Buttons Everywhere 

We'll be using a total of four buttons. Three are the standard push buttons while one is the touch button. Our first step is placing the buttons in an up, down, left, and right pattern. And then making sure they are connected the right way.

Take a cable and unwrap it. Plug one side into a button socket and the other into any Digital socket but it is recommended to leave the D8 socket free for the RGB LED. Repeat for the remaining 3 modules. Use a piece of tape and arrange the buttons and touch module in a + pattern.

All the parts you'll need
All the parts you'll need
Take a cable...
... and unwrap it
Plug one side into a button socket
... and the other into any Digital socket
All four in the '+' pattern

Upload

Copy the following code. Change out the place holder variable assignments with the sockets you chose to use.

Download file Copy to clipboard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//Library we use to help with button presses
#include <OneButton.h>

// Button/Socket variables to be changed
#define upSocket 4
#define downSocket 5
#define leftSocket 6
#define rightSocket 7

//Creating the button objects
OneButton upButton(upSocket, false);
OneButton downButton(downSocket, false);
OneButton leftButton(leftSocket, false);
OneButton rightButton(rightSocket, false);

void setup() {
  // Start serial for debugging
  Serial.begin(9600);

  // Create events for buttons
  upButton.attachClick(upClick);
  downButton.attachClick(downClick);
  leftButton.attachClick(leftClick);
  rightButton.attachClick(rightClick);

}

void loop() {
  // Update button states
  upButton.tick();
  downButton.tick();
  leftButton.tick();
  rightButton.tick();
}

// Button Press functions
//Run when the up button is pressed
void upClick() {
  //Print out a statement to the Serial Monitor
  Serial.println("Up Button Pressed");
}

//Run when the down button is pressed
void downClick() {
    //Print out a statement to the Serial Monitor
  Serial.println("Down Button Pressed");
}

//Run when the left button is pressed
void leftClick() {
    //Print out a statement to the Serial Monitor
  Serial.println("Left Button Pressed");
}

//Run when the right button is pressed
void rightClick() {
    //Print out a statement to the Serial Monitor
  Serial.println("Right Button Pressed");
}

Observe

Open up the Serial Monitor. Press the button in the down position. You should see a message saying you've pressed the down button. If nothing or the wrong button message appears double check the sockets you put in the socket variables and re-upload. Check each button and its message.

Pressing down
Pressing down
Correct serial message
Pressing right
Correct serial message
Pressing up
Correct serial message
Pressing left
Correct serial message

Adding Some Color 

Take a cable and unwrap it. Plug one side into the IN socket of a chainable RGB LED and the other into the D8 socket.

Take a cable
Take a cable
Unwrap it
Plug one side into the IN socket of a chainable RGB LED
The other into the D8 socket

Upload

Copy the following code. Replace the button variables with yours from above. Then upload the code.

Download file Copy to clipboard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//Library we use to help with button presses and RGB LED
#include <OneButton.h>
#include <ChainableLED.h>

//Number of RGB LED modules
#define NUM_LEDS  1

// Button/Socket variables to be changed
#define upSocket 4
#define downSocket 5
#define leftSocket 6
#define rightSocket 7

//RGB Led object
ChainableLED led(8, 9, NUM_LEDS);

//Creating the button objects
OneButton upButton(upSocket, false);
OneButton downButton(downSocket, false);
OneButton leftButton(leftSocket, false);
OneButton rightButton(rightSocket, false);

void setup() {
  // Start serial for debugging
  Serial.begin(9600);

  //Intialize the led and set to white
  led.init();
  led.setColorRGB(0, 255, 255, 255);


  // Create events for buttons
  upButton.attachClick(upClick);
  downButton.attachClick(downClick);
  leftButton.attachClick(leftClick);
  rightButton.attachClick(rightClick);

}

void loop() {
  // Update button states
  upButton.tick();
  downButton.tick();
  leftButton.tick();
  rightButton.tick();
}

//Button Press functions
//Run when the up button is pressed
void upClick() {
  //Print out a statement to the Serial Monitor
  Serial.println("Up Button Pressed");
  //Sets LED to red
  led.setColorRGB(0, 255, 0, 0);
}

//Run when the down button is pressed
void downClick() {
  //Print out a statement to the Serial Monitor
  Serial.println("Down Button Pressed");
    //Sets LED to yellow
  led.setColorRGB(0, 255, 255, 0);
}

//Run when the left button is pressed
void leftClick() {
  //Print out a statement to the Serial Monitor
  Serial.println("Left Button Pressed");
    //Sets LED to green
  led.setColorRGB(0, 0, 255, 0);
}

//Run when the right button is pressed
void rightClick() {
  //Print out a statement to the Serial Monitor
  Serial.println("Right Button Pressed");
    //Sets LED to blue
  led.setColorRGB(0, 0, 0, 255);
}

Observe

Now when you press each button it triggers the button event and will make the RGB LED light up a unique color.

Button Color
Up Red
Down Yellow
Left Green
Right Blue
White default color
White default color
Down = Yellow(ish)
Right = Blue
Up = Red
Left = Green

Modify

You can change the colors defined in the set led.setColorRGB() function for each button and thus putting your own spin on a time tested classic.

Super Simon 

With all the buttons in the correct sockets we can upload the full Super Simon code.

Upload

Copy the following code and again put in your button sockets. Then upload the code.

Download file Copy to clipboard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
//Library we use to help with button presses and RGB LED
#include <OneButton.h>
#include <ChainableLED.h>
#include <LinkedList.h>

//Set the button positions to numbers
#define up 0
#define down 1
#define left 2
#define right 3

//Create the list that stores the pattern
LinkedList<int> pattern;

//Game states
enum possibleStates {
  ADD,
  LISTEN,
  GAMEOVER
};

//Variable to hold the state
int currentState = 0;

//Number of RGB LED modules
#define NUM_LEDS  1

// Button/Socket variables to be changed
#define upSocket 4
#define downSocket 5
#define leftSocket 6
#define rightSocket 7

//RGB Led object
ChainableLED led(8, 9, NUM_LEDS);

//Creating the button objects
OneButton upButton(upSocket, false);
OneButton downButton(downSocket, false);
OneButton leftButton(leftSocket, false);
OneButton rightButton(rightSocket, false);

//Variable to hold loop information
int patternCount = 0;

void setup() {
  // Start serial for debugging
  Serial.begin(9600);

  //Intialize the led and set to white
  led.init();
  //Set color to white
  led.setColorRGB(0, 255, 255, 255);


  // Create events for buttons
  upButton.attachClick(upClick);
  downButton.attachClick(downClick);
  leftButton.attachClick(leftClick);
  rightButton.attachClick(rightClick);

  //Make the pattern actually random
  randomSeed(analogRead(0));

}

void loop() {
  // Update button states
  upButton.tick();
  downButton.tick();
  leftButton.tick();
  rightButton.tick();

  //This is used for debugging
  // Serial.println(currentState);

  //If the game is over then...
  if (currentState == GAMEOVER) {
    //Set led to white
    led.setColorRGB(0, 255, 255, 255);
    //Print out the score which is also the size the pattern was before
    Serial.print("Your score is ");
    Serial.println(pattern.size() - 1);
    //Stall the microcontroller
    while (true) {
      // Wait forever!
    }
  }

  //This state waits for button presses
  if (currentState == LISTEN) {
    //Print out debugging statements
    //Serial.println("Listening...");
    //If you've reached the end of the pattern
    if (patternCount == pattern.size()) {
      //Set pattern counter to 0
      patternCount = 0;
      //Set state to add to pattern
      currentState = ADD;
    }
  }

  //Add a direction to the pattern list
  if (currentState == ADD) {
    //Print out debugging message
    //Serial.println("Adding to pattern");
    //Wait a little
    delay(100);

    //Add a direction to the list
    pattern.add(random(0, 4));

    //Show Pattern
    displayPattern(500);

    //Set state to listen
    currentState = LISTEN;
  }

}

//Button Press functions
//Runs when up button is pressed
void upClick() {
  //Print debug message
  //Serial.println("Up Button Pressed");
  //If the up button was the one that was correct
  if (patternCorrect(up)) {
    //Increase your place in the pattern
    patternCount++;
    //Set color to Red
    led.setColorRGB(0, 255, 0, 0);
    //Hold for half a second
    delay(500);
    //Turn led off
    led.setColorRGB(0, 0, 0, 0);
    //If it wasn't the right button
  } else {
    //Set game to game over state
    currentState = GAMEOVER;
  }
}

//Runs when the down button is pressed
void downClick() {
  //Print out a debugging message
  //Serial.println("Down Button Pressed");
  //If the down button was the correct one in the pattern
  if (patternCorrect(down)) {
    //Increase place in pattern list
    patternCount++;
    //Set led to Yellow
    led.setColorRGB(0, 255, 255, 0);
    //Hold for half a second
    delay(500);
    //Turn off LED
    led.setColorRGB(0, 0, 0, 0);
    //If down button was wrong....
  } else {
    //Set game to game over state
    currentState = GAMEOVER;
  }
}

//runs if the left button was pressed
void leftClick() {
  //Print out a debugging message
  //Serial.println("Left Button Pressed");
  //If the left button was the correct one in the pattern
  if (patternCorrect(left)) {
    //Increase place in pattern
    patternCount++;
    //set led to Green
    led.setColorRGB(0, 0, 255, 0);
    //Hold for half a second
    delay(500);
    //Turn led off
    led.setColorRGB(0, 0, 0, 0);
    //If the left button was wrong
  } else {
    //Set game to game over state
    currentState = GAMEOVER;
  }
}

//Runs when the right button is pressed
void rightClick() {
  //Print out a debugging message
  //Serial.println("Right Button Pressed");
  //If the right button was the correct one in the pattern
  if (patternCorrect(right)) {
    //Increase place in the pattern
    patternCount++;
    //Set LED to blue
    led.setColorRGB(0, 0, 0, 255);
    //Hold for half a second
    delay(500);
    //Turn LED off
    led.setColorRGB(0, 0, 0, 0);
    //If right button was not the right one
  } else {
    //Set game to game over state
    currentState = GAMEOVER;
  }
}

//Shows the current pattern in memory
void displayPattern(int wait) {
  //Loop through every direction in the pattern
  for (int i = 0; i < pattern.size(); i++) {
    //Switch cases to pick which color to display
    switch (pattern.get(i)) {
      //Case for up
      case 0:
      //Set LED to Red
        led.setColorRGB(0, 255, 0, 0);
        //Break out of loop
        break;
      //Case for down
      case 1:
      //Set LED to Yellow
        led.setColorRGB(0, 255, 255, 0);
        //Break out of loop
        break;
      //Case for Left
      case 2:
      //Set LED to Green
        led.setColorRGB(0, 0, 255, 0);
        //Break out of loop
        break;
      //Case for right
      case 3:
      //Set LED to Blue
        led.setColorRGB(0, 0, 0, 255);
        //Break out of loop
        break;
    }
    //Wait for a while
    delay(wait * 2);
    //Turn LED off
    led.setColorRGB(0, 0, 0, 0);
    //Wait for half as much
    delay(wait);
  }
}

//Return true if the correct direction was pressed
bool patternCorrect(int dir) {
  //Check if the button pressed is correct
  if (pattern.get(patternCount) == dir) {
    //If so return true
    return true;
    //If not
  } else {
    //Return false
    return false;
  }
}

Observe

The RGB LED will flash with which color to press. An incorrect press will send the game into its GAMEOVER state, which prints out your score to the serial monitor and sets the LED to white. The game only restarts after the reset button is pressed. Every correct pattern entry extends the pattern one more.

Modify

Here is a template to download and cutout to make your Super Simon more like the original.

PDF Template

SVG Template

AI Template

Cutout template
Cutout template
Assembled
GAME OVER

Experiment

Try adding the speaker so that each color also has a unique noise.