Arduino-Based Handheld Simon Game - Arduino-Based-Handheld-Simon-Game
Arduino-Based Handheld Simon Game - Arduino-Based-Handheld-Simon-Game
by christophersfactory
https://www.youtube.com/embed/5Stxm-SGq5w?
enablejsapi=1&origin=https://www.instructables.com&enablejsapi=1&origin=https://www.instructables.com&enablejsapi=1&origin=https://www.instructables.co
m&enablejsapi=1&origin=https://www.instructables.com
About Me
This Instructable was written for the Instructables Game Design competition in Spring of 2023. I am Christopher. I run
Christopher's Factory, where I make a lot of videos, instructional material, and projects aimed to inspire others to learn
new skills, especially skills they might otherwise view as being out of their reach. I am a Senior at Texas State University,
where I study nance. This discrepancy between what my hobbies are and what I study in school is a big inspiration for
my channels' content. I am not trained in electronics, engineering, physics, or anything even related to STEM -- but I am a
rm believer that in the modern age, anyone can learn any skill, it's simply a function of dedication and willingness to
learn new things.
You can nd my tech, Arduino, 3D printing, and DIY wind turbine content on every major social media platform under my
handle Christopher's Factory (@christophersfactory), and you can contact me via email at
[email protected].
Simon is a short-term memory game. The beautiful simplicity of the game makes it an entertaining pastime for all ages,
as well as a commonly referenced example project in the elds of programming, electrical engineering, and product
design. This project will combine several broad skills concepts that are common to makers. If you're worried your skills
may not be up to par, fear not! I will break everything down as simply as possible while providing checkpoints along the
way, as well as nished les, schematics, and code for those who are more interested in just making the game than
learning the theory.
This Instructable is written such that anyone, even with no experience at all, can follow and understand every step. Those at a higher skill
level should skip through, taking the les and resources they need. Code, Fusion 360 models, and resources can be found at the end of each
step, and all resources from all steps are cumulated at the end of the project.
Supplies:
This guide will be designed to encompass as many skill levels as possible. Those who are adept in the skills necessary will
be able to breeze through this guide, cherry-picking the necessary les and resources. Those who are beginners -- fear
terms Part of what I think draws a lot of people to my channels is the fact that
not! I will explain everything in simple terms.
because I am not an engineer, I think I do better at explaining complex topics in a way that non-engineers can easily
grasp.
Please note that for this step, it is not necessary you do any coding on your own if you do not desire. I have provided my
code for you to use or adapt if you'd like.
The Arduino IDE is programmed by using a language that is technically distinct from, but very closely related to C++. For
the scope of this project, there are only a handful of functions you'll really need to use, and I'll go over them here.
The most barebones Arduino program is required to have, at the very least, these two functions: setup and loop. Most
hardware applications resemble this same basic structure, where there is a set of instructions to be performed once upon
"awakening," and another set of instructions to be performed on repeat continuously for as long as the device remains
powered. When you open a blank sketch in the Arduino IDE, the functions are already in the code for you, declared as
void setup() and void loop(). The void prex is to indicate that the functions aren't meant to report back with a certain
response or anything, they just need to perform the instructions contained therein.
An empty setup and loop aren't very useful -- it's putting commands inside the setup and loop, as well as making your
own functions and subroutines that give an Arduino its purpose. Since none of the functions I use in this project will need
to return any information, they will all be declared as "void functionname()"
Arduinos have many input and output (IO) pins, and these pins can be used to write and receive data. data They can also be
used to turn power on and o, by either raising or lowering the voltage on the pin. You may have heard people say that
computers work using zeros and ones. In application, what this means is that computers communicate by reading a
voltage, and determining whether or not the voltage is above a set threshold, which is called the logic level.
level The Arduino
Nano's logic level is 5 volts, so if you had a 5V battery and applied it to pin number nine, and told the Arduino to read
that pin, it would respond with 1, HIGH, or True, depending on the context. These three responses are all conceptually the
same thing, which response is used or given simply depends on the context.
Ones and zeros, binary, HIGH and LOW, True and False are all associated with digital logic. All IO pins can be used for
digital purposes, but there is a special set of pins that can be used for analog logic. Analog logic is beyond the scope of
this project -- all you need to know about it is that while nearly all the IO pins can be used for digital functions, only the
pins specied as analog pins can be used for analog logic.
Let's review the syntax and application of the basic functions that will comprise the majority of the code.
INPUT/OUTPUT) tells the Arduino what the pin will be used for. Arduinos can handle a
pinMode(pin, INPUT/OUTPUT):
lot, but will always work better when they know what to expect.
digitalRead(pin) returns an answer of either a 0 or a 1, based on the voltage currently applied to the pin.
digitalRead(pin):
LOW/HIGH) Applies either 0V or 5V to the pin. This can be used for communicating
digitalWrite(pin, LOW/HIGH):
with other components, or for powering low-current components like the LEDs we'll be using.
frequency) Used to play a note on a speaker or buzzer. Frequencies are input as integers,
tone(pin, frequency):
measured by hertz.
noTone(pin) Stops playing any notes on the pin.
noTone(pin):
delay(ms) The Arduino cracks a digital beer and does nothing for a time, measured in milliseconds.
delay(ms):
Loops
Loops have highly variable complexity. There are super simple loops, and very intricate loops. Rather than trying to
Arduino-Based Handheld Simon Game: Page 11
explain them conceptually, I think it'd be easier to show an example of one and elaborate on the syntax.
I'll describe what this loop does by describing the thought process that a human might use:
"For every integer,
int which we will call i, starting from i = 0 and incrementing by one (i++) as long as i is less than 100,
display the value of i."
You can probably imagine the output of this function. The program creates an integer variable called i, and sets the value
in that variable to zero. The function then prints the value of i (which is zero) to the serial monitor. Then, the function has
reached the end of the instructions for that iteration, and adds one to the variable i, as instructed by the loop declaration.
It then prints that value (now 1), and repeats this process so long as i < 100.
The full output of this function will therefore be every integer between 0 and 99 inclusive. The number 100 will never be
printed to the output. Why? After printing 99, the function will compute 99 + 1 = 100, and it will review the parameters of
the for function, and because 100 is not less than 100, it will not perform the commands within the loop, and will instead
move on.
Similarly, the while loop performs the commands in the function so long as the input conditions are true. Consider the
following code:
continue = 0;
while (continue == 0){
if(digitalRead(7) == 1){
continue = 1;
}
delay(50);
}
Now we're getting somewhere! You've just read your rst nested loop, simply: a loop inside of a loop. Here's how this
one might be read by a human:
"Continue is a variable with a value of zero in it. As long as continue is equal to zero, read digital pin 7, and if the voltage is
ever at 5 volts, change the variable continue to 1. Every time the digitalRead is completed (regardless of the reading),
wait 50 milliseconds before going on."
The program will continually check pin 7 and then delay 50ms. If pin 7 is ever high (at 5v), the program will set the
variable called continue to 1, and when that happens, the while loop will be broken and the program will move on upon
nishing the current iteration.
Alright! I genuinely think this is the most conceptually dicult part of this project, so if you're still on board at this point, I
have 2 things to tell you:
1. You're doing great
2. The worst part is over
Loop
1. Make a random list of 20 items
2. For each of the (i) items in the list
3. Run through (x) items up to i, and for each of those x items,
4. Light the corresponding LED and play the corresponding frequency on the speaker
5. For each of the x items,
6. Start a timer
7. Read all the buttons
8. If >1 buttons are pressed, fail
9. If the button is pressed that shouldn't be, fail
10. If the timer runs out, fail
11. If the right button is pressed, pass
After that, it's just a matter of setting up the loops according to your plan and testing everything out to ensure it runs
smoothly.
Step 2: Connections
I would recommend you put the project together on a breadboard rst so that you can get an idea of what connections
go where. It also helps to troubleshoot issues more eciently.
Here is a pinout list, based o my code, to remind you what connections go where:
Here's what the project looked like when I was prototyping it on a breadboard. Refer back to this in the rest of the
section when I'm describing how things should be hooked up to each other.
Wiring a Button
Arduino-Based Handheld Simon Game: Page 15
Most buttons do nothing more than close a connection, connecting the circuit. Remember that digitalRead will read the
voltage currently on the pin, so it's important to wire your button such that when the button is not pressed, the pin is
connected to ground, and when the button is pressed, a ood of 5 volts comes through the button to raise the voltage of
the pin. Additionally, we'll incorporate a resistor between the pin and ground to ensure that when the button is pressed,
we're not just shorting an unlimited amount of current down to ground.
Some of the most commonly used buttons for prototyping are these little breadboard tactile momentary switches. This
is a fancy way to say breadboard button. In the pictures for this step, I included some guides on how these buttons work.
The concept is the same for any switch -- 5V on one side, input pin on the other side, as well as a resistor to ground.
(I know someone is going to say, "Couldn't you have just done this in software?" to which I say yes, but I didn't want to. I
felt like using an IC would have been a good transition for beginners into more intermediate electronics, and it simplied
the coding, which many people nd to be daunting.)
What that means for the project is that the LEDs will be controlled by a small, 14-pin IC package. The IC has four sets of 3-
pin OR gates, and each of the 3-pin sets has two inputs and one output. If either input of a gate is raised to 5v, the chip
will raise the output of that gate to 5v and allow current to ow through.
In the picture below, you'll see what is called a truth table. This truth table describes the behavior of a two-input OR
gate, like the ones inside the IC. You can see that if either A or B is 1 (meaning raised to 5v), the output will be 1, meaning
raised to 5v).
The button manufacturer said to use 12v. Anything less than that will dim them, and anything more than that might burn
them out. After probing the LED assembly with my multimeter, I found that there was a 460 ohm resistor put in series
with one of the legs. There are two things one could do in this situation:
1. Gut the LED and replace the resistor with one of a lower value
2. Change the LED's power setup
I decided I didn't want those following along to have mess with the internals of the button, so rather than powering our
LEDs directly from the OR gate IC, I'm going to have the 5v output of the IC toggle a 12v circuit by implementing a
transistor. Transistors are awesome. They have tons of uses, but for the scope of this project, you can think of it like a
I nd the naming convention of transistors' pins a bit tough to conceptualize, so here's a sample circuit instead that I
made to illustrate how one would use a transistor in a typical application.
As you can see, the transmitter works by completing the 12v circuit, allowing the LED to connect to ground when the
middle pin is raised to 5v. We add a 4.7k resistor to ensure power from the 5v source isn't being wasted, since it only
requires a very small amount of current to toggle the transistor. An important note -- this is a usage schematic for a
2n2222 transistor. There is another common transistor, the BC547A, that has the emitter and collector pins swapped. One
can remember the transistor's confusing terminology by thinking of the collector as collecting electrons, and the emitter
emitting them out.
So now we have the power issue sorted out. We can have the Arduino write 5v to a pin, which will then toggle a
transistor, which then completes the 12v circuit, turning on the lights. This obviously raises the question, though -- what
will be the power source for our handheld Simon game?
Arduino-Based Handheld Simon Game: Page 20
Arduino-Based Handheld Simon Game: Page 21
Arduino-Based Handheld Simon Game: Page 22
Arduino-Based Handheld Simon Game: Page 23
Arduino-Based Handheld Simon Game: Page 24
Arduino-Based Handheld Simon Game: Page 25
Arduino-Based Handheld Simon Game: Page 26
Arduino-Based Handheld Simon Game: Page 27
Step 3: Power
Conveniently, Arduinos have voltage regulators on them, and all of the 5v logic level Arduinos (Nano, Uno, Mega) have a
maximum input voltage of 20v. This is great for us, because whatever 12v power source we use to light our LEDs can also
be fed into the Arduino, and the Arduino will regulate that down to the 5v that it needs to operate.
So where shall we get our 12v power source? There are a couple things we could do:
1. Connect 8 AA batteries together in series
2. Connect 3x 18650 LiPO batteries in series, which might be nice because they're rechargeable
3. Use less batteries, but implement a DC-DC voltage boost converter to raise the voltage up to what we
All of these options would work... A single 9v battery is the easiest option, but it will probably need to be replaced after a
few hours, but that's ne for me, as I don't think it's likely I'll be playing this constantly. We'll add a barrel jack to the
enclosure so that the game can be plugged in the wall if the batteries are dead and you can't be bothered to go to the
store. One thing I absolutely love about the barrel jacks I linked is that they have an internal switch that can be used to
disconnect a battery circuit when the barrel jack is plugged in. This ensures that no battery power is wasted as long as
the game is plugged in.
We're also going to add a toggle switch on the side of the box that disconnects the ground of all power sources (wall
and battery) when switched. When using precious battery power, every little trickle of power becomes crucial, so it's
important to erase any possibility that power will be used. Plus, I think that starving an Arduino of power is, by far, the
easiest way to turn it o. No latching ip-op circuits, no deep sleep and wake, just cut the power!
I decided while writing this section that in a future project, I want to use an 18650 cell and a boost converter so that it
can last longer and be rechargeable. I gured that alone is probably worth its own Instructable, so be sure to follow me
here and on other socials if you want to learn how to do that.
Here is the switch that I will be using to turn o the device when not in use:
So, in terms of hooking everything up, we want the power switch to overrule the switch that's in the barrel jack, so we'll
have pin 2 of the barrel jack go to the switch. Recall that pin 2 will either carry ground from pin 3 from the 9v battery if
nothing is plugged into the jack, or ground from the wall if the jack is plugged in. Either way, ground must come through
pin 2 of the barrel jack to complete the circuit, so I'll make that ground have to also go through two adjacent pins of the
switch. This will make it such that no matter if our game is running o battery or wall power, we can still cut o power
with this one switch.
Take a deep breath and crack yourself a cold sparkling water. Look how far you've come! We're on the home stretch now,
and you're close to impressing all of your friends with your Simon game.
As I mentioned in the beginning, this project is my entry for the "Game Design" themed Instructables competition,
presented by Autodesk Fusion 360. As such, one of the requirements for the project is that it uses Fusion 360 in the
design. For me, it'd be more challenging to have to make a project without Fusion 360! As a maker, Fusion 360 is
If you are a student, you can get free access to the full, enterprise-level version of Fusion 360 at this link.
If you are a maker or hobbyist, you can get free access to a slightly limited but still extremely powerful version of Fusion
360 at this link.
The rst thing I did is measured everything that would need to go in the enclosure. Then, I sketched a really rough design
of what I might want my game to look like. Some people like to plan out every detail of their project before starting, but
my preferred modus operandi is to just start running in the rst direction I feel like, and then make changes and
improvements as I go along.
To access user parameters, go to Modify < Change Parameters < + User Parameter. Then, you can create your variable,
dene what units it will use, and specify a length, angle, etc.
I added several parameters as I went along to allow myself to tweak the design. I was really glad I did this, because there
were several times that I needed to make walls bigger, expand holes, etc., and I was glad I didn't have to go through and
do it manually.
When those parts nish printing, here's your to-do list, roughly in order:
Remove all supports
Put the switch, jack, and buzzer in place. Don't tighten the nuts down yet.
Solder the knurled nuts in place (more info on this below)
Gently remove the button internals by twisting counter-clockwise on the red and black rectangle. It will
click out of place and can be easily removed. This step is necessary to t the buttons into the enclosure.
Put the buttons into their places, ensuring to follow the convention for Simon ( example)
Screw the nuts for the buttons on rst, then gently lock the lights back into place
Tighten everything nger-tight
https://www.youtube.com/embed/iHPajA0dpm8?enablejsapi=1&origin=https://www.instructables.com
You'll want to probe the LEDs to nd the positive and negative on each one. Out of the four I used, I had three where the
positive leg of the LED was connected to the pin on the black side of the switch, and one that was the opposite, so you'll
want to make a note of the polarities.
Now, we nd ourselves at a crossroads. If you trust yourself, you can put together a piece of protoboard and begin
hooking everything up. I will go over how to do that now, but if you want to save yourself some time and the
headache of debugging, you can skip to step #5, #5 where I will show how I made a custom printed circuit board to
make all the connections easier.
If you're bold and want to wire everything by hand, start by connecting all the 12V legs of the LEDs to each other, to the
VIN of the Arduino, and to the positive leg of the DC barrel jack.
For the purposes of this project, these tones may also sound better either shifted up an octave, or in the B♭ minor chord.
Totally up to preference. Here's a note chart if you want to play around with other notes and frequencies, here's a chart
that will help you connect notes to frequencies.
View in 3D Download
https://www.instructables.com/FOB/V6E4/LFB4G7BC/FOBV6E4LFB4G7BC.stl
I decided to lay out a circuit board to make all the connections easier. When making my protoboard, I found that I was
using tons of excess space in the name of keeping things organized, accidently bridging several connections in the
process, and I spent a long time debugging and probing the board for errors. Where custom PCBs were once an
expensive luxury of those with the skills and funds to make them, custom PCBs are now a reasonable alternative for
hobbyist prototypers. There are several rapid prototyping PCB companies that will make small-batch boards for cheap. I
got my rst 5 for $0.40 each (shipped), and they were even cheaper after I veried that my design worked properly and I
was able to order a larger amount.
Step 5 of this project does not include any new information, but instead is simply a translation of the circuits and
schematics from past steps into Fritzing, a program for hobbyists and enthusiasts to easily design simple circuits,
diagrams, and PCBs.
I have included the les for my circuit board for free on this project ( Link). Readers may use and edit these les for any
personal/non-commercial purposes. Since most PCB prototype manufacturing services have a minimum order quantity, I
also included headers for the pins unused in this project so that you can repurpose the boards for other projects.
You'll also notice that I try to socket everything when possible, but especially, especially Arduinos. Even if they're cheap,
it's still a few dollars that can be saved with minimal eort.
At this point, you're done! It's just a matter of testing all your connections. What I recommend you do from here is play
around with the code -- mine was admittedly somewhat hastily written and has many things that could be improved
upon. Also, with the same wiring, you could implement a screen, counters, you could make up a new game completely
from scratch!
Gerber les for the board are available to download for free on my Patreon (Link)
If you made it to the end of this project, I'm proud of you! I hope you learned something along the way and had fun
doing it.
Rather than trying to gatekeep project information and les behind paywalls, I try to keep my work accessible to
everyone. That being said, this project took me a surprising number of hours and many days' work, and if you'd like
to contribute to my eorts to educate and inspire, it would very much help to keep the lights on in Christopher's
Factory. (Paypal Link)
(Paypal Link)