In this instructable, I will show you how to take an SNES controller, hook it to an Arduino, and make a simple Simon Says game.
This could be used to create a more complex game, or maybe even to try and make an Arduino based mini-console. Eventually, I will get a video up of the game in action, but I dont know when.
Step 1: Materials Needed
The materials needed are as follows:
-1 small breadboard
-1 old SNES controller that you wouldn't mind tearing up
-10-15 Jumper wires(I use 11)
Step 2: Hook Up All the Wires for the Arduino
Plug jumper wires into pins 2-9 on the arduino. See below to see what each pin does, along with my recommended color scheme.
Pin 2: Strobe Pin. Connects to Orange wire from controller, so I would make the Jumper Pink or Orange.
Pin 3: Clock Pin. Connects to Yellow wire from controller, so I recommend a Yellow Jumper.
Pin 4: Data Pin. Red wire on controller, so a red jumper would be best.
Pin 5: Power for top led.
Pin 6: Power for right led.
Pin 7: Power for bottom led.
Pin 8: Power for left led.
Pins 5-8 should have same colored jumper wire. I choose Dark Green.
Pin 9: Power for game indicator led. I used Light green.
5V: Power pin, connects to white wire from controller, so i used a white jumper.
GND: Brown wire from controller, I used a black jumper.
GND: Used to connect all grounds from breadboard back to arduino, i use blue for all the ground wires.
Step 3: Setting Up LEDs and Breadboard
Place your LEDs on the breadboard in a diamond shape. Make sure no 2 LED pins share the same numbered row. Wire all the cathodes(short pins on leds) to the ground lines on your breadboard, then hook you ground line to one of the GNDs on the arduino. Connect the jumpers on Pins 5-8 to the Anodes of your LEDs, corresponding to their position, as given in the last step.
For the game indicator LED, just put it away from the others, hook up its anode to Pin 9, and its cathode to the ground rail.
Step 4: Hooking Up the Controller
Up to this point, you have not had to mess with the controller at all. Now, you have to cut the plastic casing off of the end of the wire, so that you can get to the wires inside. They should have some little metal ends on them(refer to pictures), so it should be fairly simple to hook up jumper wires, right?
First tape the controller cord to the desk by the arduino. If you let it move, you will have a hard time making good connections. My jumper wires slip right out of the little metal things, so i took a pocket knife, and pried the ends apart(see pictures)so that i could stick the jumper wire perpendicular into the socket thing. When hooking the 5 wires up to the controller, make sure they do not touch eachother, and that you are matching the colors correctly.
At this point, you should have everything properly wired and ready to go. Download the linked Arduino sketch, compile it, then upload it to your arduino. To play, wait for the game indicator LED to stop flashing, then use AXBY as the 4 cardinal directions. In the next couple of steps, I will attempt to explain the code, but if all you want is a working game, you can stop here.
Step 6: The Code, Part 1
First a little background on how the controller sends data. In order to recieve data from the controller, you set the strobe pin to high, then read your first bit of data(least significant bit). To get the second bit, you toggle the clock pin, then read from the data pin. You continue doing this 16 times. The state of the controller is a 2 byte number, with the 12 least significant bytes containing the buttons currently being pressed, and the 4 most significant bytes being useless.
So the first 7 lines are pretty simple, because they just assign names to the 3 controller pins and the game indicator pin.
Lines 8-20 declare the hex data used to detect which button is pressed on the controller. Each hex value turns on a separate bit in the data stream, so that way you can just use bit shifts to determine if a certain button is pressed, or just use a bitwise and.
The variable 'array' is just an array of integers that is 30 ints long. This stores the sequence of presses for the game.
'pos' is a position variable. More on that later.
'timeForPress' is how long you have to press the buttons.
Up next is the setup() method. We start by seeding the random number generator, and then setting the pin mode for each of the pins 2-9. Next we open up serial communication, for debugging purposes, and set the sequence of buttons to all '4's. I did this b/c the numbering system for the LEDs only goes up to 3, so the 4 is essentially just a placeholder. Now we set timeForPress to 1000, and call the genSequence() method, which fills our array with random integers between 0 and 3(inclusive). Next, it sets our position to 0, to show that it hasn't started the game yet, and then it flashes the game indicator to show that the game is about to begin.
Step 7: The Code, Part 2
In this step, I will quickly cover the methods used to obtain data from the controller. I told you the theory in the previous step, but now I will lay out the actual function calls.
I think I got a little bit of this code from this instructable. Not entirely sure though.
There are three methods used to check the controller input:
The buttons() method first sets up a return variable and a place counter. It then strobes (using strobe()), and enters a for() loop. In the for loop, it reads and stores the data one bit at a time using the shiftin() method and bitwise operators.
The method strobe() is pretty straightforward. Basically just sets the strobe pin to HIGH, then immediately back to LOW. Pretty simple stuff. This tells the controller to begin transmitting data.
The shiftin() method actually reads the data. It takes the data from the data pin, then toggles the clock pin, which tells the controller to send the next bit over.
Using just these three methods, you can read the state of the controller. You should never have to directly call strobe() or shiftin(). On a final note, when checking to see if a button is being pressed, you have to use 2 bitwise operators. The ~ (tilde) is a bitwise not, and inverts the data, then the & checks the state vs whatever button you want pressed.
Step 8: The Code, Part 3
This is the final step about the code. I am just going to quickly glaze over the operation of the game loop, since that should be pretty easy to follow for a novice programmer.
The loop() method starts out by serially printing the state of the controller. It then plays the sequence stored in the array, then checks the user input with the readAndCheckInput method, which essentially just a for loop with some if statements in it. If you get one wrong, it breaks out of the loop and does the blinking thing then ends.
I guess that means this tutorial is over! If y'all make any cool games, please comment and put a picture, as I would love to see them!