Hello!
In this instructable, I will show you how to hook up a Nintendo Entertainment System control pad to an arduino, the arduino is in turn running a special sketch that allows it to show up to a PC as a USB HID joystick!
And if that is not cool enough, I will show you how to shove it all inside the NES controller shell for a simple controller + wire, "plug n play" device!
Notice!!
If you hook this up wrong you can fry your arduino, and or your usb ports, if you choose to biuld this project you assume responsibility for its proper construction
Sofar I have tested this on ... Windows XP pro, Windows 7 64 bit, and Ubuntu 9 32 bit
So far its not tested on Mac, I don't see why it should not work on Mac, but its untested, the only Mac I have in the house is a SE from 1986, I will test it as soon as possible, just gotta sweet talk a co worker into bringing his macbook pro into work :)
Tools: your usual electronics tools... on this project I used
Soldering Iron
Solder wick
Solder
Small phillips (+ shape) screwdriver
razor knife
small needle nose pliers
electrical tape (or proper sized heat shrink, I just happen to be out)
multimeter
Tweezers
Parts:
Arduino (with atmega 168 or 328, other chips not tested)
and a EXTRA atmega chip, you dont HAVE to but I installed this inside the controller, so you may want to have an extra chip on hand with a boot loader installed on it to replace the one we will be using (especially for me since I use my arduino AS a avr programmer, I would be kinda stuck)
16mhz crystal (ceramic resonator works fine, but I had the crystal and caps already)
2 * 22pf for the crystal (if your using a resonator then its packaged in for you)
0.1uf cap (code 104)
2 * 68ohm 1/8 watt resistors (or smaller if you want, just not larger, its tight in there)
1k5 ohm resistor
2 * 3.6v zeiner diodes 500mw or smaller
USB cable you dont mind cutting one end off of
NES game pad
thin insulated jumper wire
I am not smart enough to figure half of this usb stuff out, so were using a library, In researching this on good old google, I found http://www.arduino.nl/?p=36
Now there is a couple things to note on this page
1) its based off of the usb keyboard library found on rancid bacon
http://code.rancidbacon.com/ProjectLogArduinoUSB, which REQUIRES arduino 0016! I have messed around with this for a few days trying to get it to compile on arduino 18 software, and though it wants to work the computer never can communicate with the device, leaving a ugly balloon next to my clock, the joystick library flat out does nothing on 18
arduino 16 started to be a pain in the butt, and not start up for me, what I figured out is I needed to remove the preferences.txt file that 18 had placed in my user folder, and then start arduino 16, it should work, and 18 continues to work off of 16's file
see http://www.arduino.cc/en/Hacking/Preferences so see where you can find yours if you need too
2) The comments of the joystick library page state that it doesn't compile, and it doesn't, its not that hard to fix, and I already have in the software download. But if anyone else wants to know ...
in UsbJoystick.h you need to include interrupt.h
void sendJoystick(byte val0, byte val1, byte val2, byte val3, byte val4 , byte val5 , byte val6, byte val7) {
to
void sendJoystick(uchar val0, uchar val1, uchar val2, uchar val3, uchar val4 , uchar val5 , uchar val6, uchar val7) {
Finally, after fiddling with this library for nearly 2 solid days, I gave up on changing its configuration, so the computer sees a 6 axis 4 button joystick, even though it only responds to 2 axis and 4 buttons
Moving on, down below you will see 2 files, the zip file contains the fixed usbjoystick lib, place that in the /hardware/libraries folder of arduino 16, and my project files, open the pde file in arduino 16, compile and upload
otherwise if you have a avr programmer handy and dont mind dealing with avrdude there is also a hex available
Ok, once you have the software uploaded to the chip you can put the arduino on the side for a little while, and get rid of that pesky computer keyboard
We will test the controller connected to the arduino In a little bit, but first we need to make some changes to the controller itself
Flip your controller face down on the table, using your small + screwdriver remove the 6 screws, the back and the controller board
... Apparently I am missing a picture, but place the controller shell / screws / buttons / pads in a safe place, and desolder the controller cable and its shift register IC
Once you have those 2 items out of the way (keep the shift register, its fun) clean and (re)tin all the pads
Most designs use the shift register to talk to the controller, as its a simple 3 wire device, but I had a rather large chip with (still) a lot of I/O pins, and a rather hard time finding a place for it AND another 16 pin dip chip, So I said ok and we are going to wire each button directly to a pin of the microcontroller
In order for this to work we need to know which pads go to what parts of the controller
I highly recommend that you spend the extra time and hassle to hook up 10 wires to the nes pad and plug them into your arduino board and make up the usb ciruit
A note about usb cables, or any other cable, don't trust the colours, use a meter to find out which wire goes to each point on the plug, in my case the wires are not even the correct colours so it does not matter, but I have also had a keyboard that had wrong colours and wrong printing on the pcb!
Connecting the controller is tedious, the usb hardware is easy, either way its good to know it functions, cause after this its pretty much the point of no return
SO TEST IT
Take note that the cathode of the diode (the end with a stripe) needs to face into oncoming current, and the anode needs to be connected to ground
this is backwards from most diodes, what is happening here is the zener diode has a very low reverse breakdown point, so it "leaks" a controlled amount of current backwards through the diode to ground, which also drops our voltage down to the 3 ish volt signals expected by usb
So we have hooked up the circuit plugged it in, verified it working by checking the control panel or maybe playing Mario for 20 min , but its time to move this fragile bundle of wires into its new home.
Doing so requires some pain in the butt soldering, but really its not hard (fiddly yes). The trick is to tin both parts, then using your tweezers hold them together and melt the solder to form a solid joint
for practice try soldering components leads together, as we will be doing that too
Start off by cleaning the game pad's pcb of all wires(again) and carefully remove the atmega from the arduino.
Using your needle nose pliers you need to very carefully bend the following pins of the microcontroller out at a 90 degree angle, right at the base where the pin gets fat.
Pin
1 28
2 27
3 26
4 25
5 24
6 23
7 22
8 -
9 20
10 -
- -
- -
- 16
- 15
the pins marked with a - leave pointing down, these will fit into the original shift register "socket"
The pcb has a silk screen of which way the sr went in, line up the atmega where pin one is on the same side as indicated on the silk screen (facing the cable connection), and where the lasts pins are in the next to last set of holes
First flip the board over and solder only where the atmega pins are poking through the pcb, we just connected 6 out of the 8 buttons yay, we still need to connect buttons A and B
Get a segment of jumper wire, tin the end, get a (not excessive) ball of solder on the nes pad 15, do not push the wire through the hole, just solder it flat on the pad
Now loop it around so it meets up with pad #12, Pin # 17 of the atmega is already in this hole, and the pad is not connected to anything else in the controller, so B button is good to go, A was not as graceful
For button A solder a wire flat onto pad #1, loop this around to the top of the board and solder to pin # 23 of the atmega
Also solder blob pins 20 and 21 together (dont overheat) this is aref and analog power supply, aref is soldered to the pcb's +5v bus
Every Nintendo controller I have seen was kind enough to have a couple extra pad's and holes made connecting to power and ground, its a great place for a decoupling cap, so lets add one
Insert your 0.1uf cap into the top of the pcb, fold it over so it lays flat, and away from the screw hole in the corner, flip the board over and solder its leads to the pads, but do not clip the leads short yet
Now solder 2 jumper wires to those pads (I could have done this differently but hindsight is 20/20) for ground and + 5v, now you can clip the leads of the capacitor
Wrap the power and ground jumpers to the top of the board, connect +5v to pin 7 of the mega, and connect ground to pin22 of the atmega
The crystal is going to be sitting sideways, to make life a little easier you may want to "smoosh" the leads down so they line up with the atmega's pins easier, Also I put the board back in its front shell, there is a post right where the crystal goes, so you have a choice, you can work around it, or cut the post off
I choose to work around it (thinking its more protection for the crystal if this gets stepped on)
Solder 1 leg of the crystal to pin 9 of the atmega, bend the other leg to pin 10 of the mega, now we can add the 22pf caps, they are necessary for operation
The first capacitor is pretty, easy, stick one lead into that leftover ic hole (pad# 8) and solder to the pcb, solder the other lead to the closest lead of the crystal
The other capacitor is a little bit of a pain in the butt, because of a second plastic post, you can cut this post off too if you wish, but I worked around it, One lead of that capacitor needs to be soldered to the second lead of the crystal, and the second lead of the capacitor needs to be soldered to pin #8 of the atmega (this is a ground pin)
With the basics needed for the microcontroller to run we can hook up the resistors that are the first step in our level conversion from 5v to ~3v
First resistor to hook up is the 1k5 resistor, insert it into the top hole of where the cord used to plug into, solder it in place from under and just kinda bend its lead out of the way for now
Side note, I say 1.5k and picture a 1.0k, reason for this is I already have 100 3.3v diodes, and with the currents involved its only pulling the line up to ~2.7v instead of 3.3, this may be fine for my mutt open architecture computers but not all computers will "play ball", use 3.6v diodes and a 1.5k ohm resistor and when you do the math its around 3.2+ and will not cause issues with computers that dare things to be within spec
Now Take your 2 68 ohm resistor and solder a end to pins 4 and 6, trim their leads so they stagger a little at the opposite end and bend those leads to the right
Finally for this step add some jumper wires to the 3 resistors and clip them so they all end at the same place (I used red for the pull up resistor, and blue for the 2 data lines
Take the wires that lead from the pull up resistor (1k5) and one of the 68 ohm resistors that ultimately ends up on the mega's pin 6, and pigtail them together.
Also take the wire lead from mega pin 4 then strip and twist its end
Next take your diodes, and pigtail their cathodes (end with the stripe on it) to the other wires
Find the D- line in your usb cable, Mine was brown ... anyway do a inline splice with the pigtail that contains 2 wires and the diode, then solder together and wrap in tape, take the D+ line and splice it with the other wire that is coming off of the mega's pin 4 and the diode, solder them all together and wrap with tape
You should have the other leads of the diodes still sticking out, choose whichever one looks longer and solder it to the lead of the capacitor that is connected to ground (the other side would be connected to the crystal), then solder the other diode lead to the first diode lead so they are both connected to ground
Then solder the ground lead from the usb cable to one of the leads connected to ground
The final connection is for the usb to provide everything with power, I was running a little tight on space, and really did not want to run another jumper wire... what to do?
Easy, cheat, plug the USB's +5 line into the last IC socket hole on the top of the board, this only goes 1 place, and it ends up right next to where we connected the pull up resistor, to power the rest of the board, we need to jump the first 2 pads where the cable used to attach
Wrapping up:
Plug it in and test it one more time, I added some glue on spots that I thought could bend easy or vibrate and you should too, although I am impressed with the NES controller strain control, I started bending plastic and the cable did not budge
Take this chance to really clean your controllers case, so you don't have old goo stuck between the buttons and the shell
As you put the controller back together there are supports in the back half of the shell, if you followed the pictures there should be little issue, just kind of peek inside as your closing up and do not force pinch anything, it might take a little poking to get everything happy
And most importantly enjoy!