Simon & Whack-a-Mole Game Using Arduino (also in Tinkercad)

by botdemy in Circuits > Arduino

15758 Views, 59 Favorites, 0 Comments

Simon & Whack-a-Mole Game Using Arduino (also in Tinkercad)

IMG_2175.jpg
Arduino Simon & Whack-a-Mole Project
simon.JPG
IMG-2190.JPG

If you grew up in '80s, most likely you played an electronic toy game called Simon. In this Instructable, I will be building an Arduino kit that you can code to play Simon and other button-based games such as Whack a Mole. I developed this kit to be used by a local Girls Who Code club that I facilitate.

If you don't want to spend any money buying parts, you can do the complete project in Tinkercad.

You can just copy and tinker this project:
https://www.tinkercad.com/things/lozV8434PFG-simon...

Parts

IMG_2164.jpg
  • Arduino Uno or equivalent
  • 4 x color (red, green, yellow, blue) illuminated momentary push button switch
  • 4 x 220 ohm resistor
  • 5 x 28mm or longer spacer
  • 9v battery and holder
  • wires
  • screws to put them all together
  • case: I'm using a piece of 1x5 pine wood as a base and 4 1/2in x 4 1/2in panel board

Tools Used: soldering iron, cutter, screw drivers, saw, drill, glue gun (optional)

Push Button Switch Unit

IMG_2166.jpg
IMG_2167.jpg
IMG_2169.jpg
Simon - Button Switch Wiring Diagram.jpg

This part requires soldering wires to push button switches. Connect 9 wires to switch buttons as shown in the diagram.

I'm using the following wiring color code:

  • Red = red switch LED
  • Red/striped = red push button switch
  • Blue = blue switch LED
  • Blue/striped - blue push button switch
  • Yellow = blue switch LED
  • Yellow/striped - blue push button switch
  • Green = blue switch LED
  • Green/striped - blue push button switch
  • Black - GND

Attach Button Switch Unit to the Main Board

IMG_2171.jpg
IMG_2172.jpg

Use 5 board spacers to attach the button switch assembly to the main board as shown in the picture. I'm using 28mm spacers here but anything longer than 25mm should work .

Attach Arduino and Battery Holder to the Base Board

IMG_2173.jpg

Use 7 small wood screws to attach Arduino and the battery holder to the base board.

Connect Button Switch Wires to Arduino

IMG_2174.jpg

There are 9 wires coming out of the button switch assembly. Connect them to Arduino according to the following pin assignment:

D2: Red - red switch LED

D3: Blue = blue switch LED

D4: Yellow = yellow switch LED

D5: Green = green switch LED

D6: Red/striped = red push button switch

D7: Blue/striped = blue push button switch

D8: Yellow/striped = yellow push button switch

D9: Green/striped = green push button switch

GND: Black

Tidy Up

IMG_2175.jpg

Use some wire ties to hide all the wires under the button switch unit. I also used hot glue to bond all the connectors to Arduino.

Code #1 Setup & LedOn/Off

First, let's create code to do basic LED on and off.

First thing we will do is create constant variables for the Arduino pin assignment. Rather than using numeric pin numbers in your main code, we'll create constant variable names for these pins so that if we have to change our pin assignment later, we can simply change this section and not in the main code.

const int redLED = 2;
const int blueLED = 3; 
const int yellowLED = 4; 
const int greenLED = 5;
const int redButton = 6;
const int blueButton = 7; 
const int yellowButton = 8;
const int greenButton = 9;

Next, we move over to the setup section and declare these pins as either input or output. Note that I'm using INPUT_PULLUP on switch buttons so that these switches are set to HIGH when open (not pressed) and change to LOW when closed (pressed). If you just declare them as INPUT, you're required to add a resistor and ground the switch. (See Arduino tutorial on digital pin.)

void setup() {
  // initialize LEDs as output.
  pinMode(redLED, OUTPUT);
  pinMode(blueLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);
  pinMode(greenLED, OUTPUT);

  //use "PULLUP" to set open/unpressed to HIGH
pinMode(redButton, INPUT_PULLUP); pinMode(blueButton, INPUT_PULLUP); pinMode(yellowButton, INPUT_PULLUP); pinMode(greenButton, INPUT_PULLUP);
}

Before we start the main section, let's create functions to turn on and off LEDs. This way, our main loop section would just consume these functions.

(Note: Experienced coders will noticed that using arrays for switches and LEDs are much more efficient way to handle these tasks. Since this code will be taught to middle school students, We'll stay away from array for now. For the last coding lesson, however, we have to use an array to store the button sequence for the Simon game so eventually we will have to cover that at the end...but not now.)

Let's create our first function that turns on a specific LED when you specify a color. (Color is actually a numeric value of your constant variable.)

void ledOn(int color) {
   if (color == redLED) {     digitalWrite(redLED, HIGH);   }   
   else if (color == blueLED) {     digitalWrite(blueLED, HIGH);   }   
   else if (color == yellowLED) {     digitalWrite(yellowLED, HIGH);   }   
   else if (color == greenLED) {     digitalWrite(greenLED, HIGH);   }
}

Similarly, create another function that turns off a specific LED.

void ledOff(int color) {
if (color == redLED) { digitalWrite(redLED, LOW); }
else if (color == blueLED) { digitalWrite(blueLED, LOW); }
else if (color == yellowLED) { digitalWrite(yellowLED, LOW); } else if (color == greenLED) { digitalWrite(greenLED, LOW); } }

In our main loop, we would simply consume above functions. Here is an example of our loop section that turns on and off the red led every 1 sec.

void loop() {
  ledOn(RedLED);
  delay(500);
  ledOff(RedLED);    
  delay(500);
}

Doesn't this look alike the blink program where you blink the built-in LED on D13?

Code #2 On/Off ALL

In this code exercise, we will turn on and off ALL LEDs.

Let's add two more functions for turning on and off ALL LEDs.

void ledOnAll() {
  ledOn(redLED);
  ledOn(blueLED);
  ledOn(yellowLED);
  ledOn(greenLED);
}

And for the off:

void ledOffAll() {
  ledOff(redLED);
  ledOff(blueLED);
  ledOff(yellowLED);
  ledoff(greenLED);
}

Once we have these functions ready, we can consume them in our main loop section. Here is our main loop section to blink ALL leds.

void loop() {
  ledOnAll()
  delay(500);
  ledOffAll();    
  delay(500);
}

CODE #3 BLINK

In our last exercise, we blinked all LEDs in the main loop. Why not create a function to blink all LEDs as well as individual LEDs? As you can see, we started from low level functions and now we are moving to higher functions that either combine functions and/or calls other low level functions.

Function: blinkAll

You specify the blinkTime in msec when you call this function.

void blinkAll(int blinkTime) {
   ledOnAll();
   delay(blinkTime);
   ledOffAll();
delay(blinkTime);
}

Function: blink

You specify the color and the blinkTime in msec when you call this function.

void blink(int color, int blinkTime) {
ledOn(color);
delay(blinkTime);
ledOff(color);
delay(blinkTime); }

Main Loop

Here is an an example of how we consume these functions.

void loop() {
blink(redLED, 500); blinkAll(500); }

Code #3 Spin & Boomerang

Once we have functions for blinks, we can create more higher functions to create couple light effects - spin, boomerang

Function: Spin (clockwise)

void spin(int speed) {
blink(redLED,speed); blink(blueLED,speed); blink(yellowLED,speed); blink(greenLED,speed); }

Function: Boomerang

void boomerang(int speed) {
blink(redLED,speed); blink(blueLED,speed); blink(yellowLED,speed); blink(greenLED,speed); blink(yellowLED,speed); blink(blueLED,speed); blink(redLED,speed); }

Main Loop:


void loop() {
spin(500);
boomerang(500); }

Code #4: Random Blink

In both Whack-a-Mole and Simon, we need to generate a random color. In this exercise, we'll use the Random function to pick a color and blink that LED.

Before we create a function, we first need to UPDATE (not replace) our setup() by ADDING the following line. This statement insures that our random numbers are truly random.

void setup() {
//insert below
randomSeed(analogRead(0));
... }

Next, let's create a new function that randomly pick a color. For this function, we will be using starting with "int" instead of "void" since we want this function to return an integer between 2 to 5. (Why 2 to 5? Our LEDs are numbered from 2 to 5 based on their pin assignment.) When we call this function, we're expected to get an integer between 2 to 5.

int pickNewColor () {
  //random(min, max)
  //Parameters
  //min - lower bound of the random value, inclusive (optional)
  //max - upper bound of the random value, exclusive
  
  //generate random # from 2 to 5 that matches led Pins
  //2 = red, 3 = blue, 4 = yellow, 5=green
  
  int randomColor = random(2,6);
  return randomColor;
}

Our main loop would simply call this function and blink random LEDs that are connected to pins 2 to 5.

void loop() {
blink(pickNewColor(), 200); }

Now this is getting interesting. This is calling blink where the input parameter for color is obtained by calling another function pickNewColor that simply returns with an integer from 2 to 5.

Whack-A-Mole and Simon

As you can see, in each exercise, we're simply adding more code in the form of high level functions that call our low level functions and our main loop is consuming those high level functions. Attached are working version of Whack-a-Mole and Simon. Consider them as version 1 as there's room for improvement but I will leave that up to you. Enjoy!