Introduction: Use an Arduino With an N64 Controller

Picture of Use an Arduino With an N64 Controller

There are tutorials out there for using an NES controller with an Arduino, but using the more complicated N64 controller and its analog joystick has a definite appeal. If you have an Arduino around and don't want to buy an Adaptoid, this instructable will make it possible to play emulated games in Project 64 with your Ardunio and an N64 controller.

Is this hard? / Will it damage my stuff?
This will not modify your controller in any way, and the wiring is extremely simple, so if you do everything carefully there should be no risk to your controller, and you can unhook it at any time to use with a N64 console.

What you will need:
Arduino - $30
Processing 1.0 - free
Arduino Software - free
3 pieces of wire - free (I hope)
USB cable

Step 1: Wiring the Controller

Picture of Wiring the Controller

The first thing you need to do is connect your Arduino to the controller
The controller only uses three leads: +3.3V, signal, and ground.
Looking directly at the plug, ground is farthest left, signal is in the middle, and +3.3V is on the right. Using the wire, connect ground and +3.3V to the respective pins on the Arduino, and connect the signal lead to the Digital 2 pin on the Ardunio.

NOTE: If you have other code on your Arduino, you should disconnect the controller and upload the new code from the next page to the Arduino before powering it up with the controller attached.

Connect the Arduino
Connect the USB cable and the Arduino will have power.

Step 2: Unpack and Run the Code

This code was written by me, with parts of the N64_Arduino file based on assembly code written by Andrew Brown.

ZIP Archives:
The two Zip files below contain the code needed to run the Arduino and then to interpret the data it sends to the computer. The N64_Arduino file needs to be compiled in the Arduino IDE, and the N64_Controller runs in Processing 1.0.

This PDE file should upload to your Arduino and run without a hitch if you have everything connected properly. It simply queries the N64 controller for data on the buttons and Analog stick and sends it back to the computer over the serial port. It is easy enough to modify, for example, you could use the methods from this file to query a controller and use the data to run an Arduino robot instead of transmitting it back to the computer.

This is a Processing 1.0 project that takes the data transmitted by the Arduino and converts it into keyboard presses that you can map to an emulator like Project 64. You might need to change the line String portName = Serial.list()[1];to match the your Arduino, it should be either Serial.list()[0]; Serial.list()[1]; or Serial.list()[2];

"import java.awt.Robot;"
"import java.awt.AWTException;"
"import java.awt.event.InputEvent;"
to the code if you are using Processing 1.1

This is the same as N64_Controller, except that the analog stick controls your mouse, not the arrow keys. A and B are right and left click, respectively. To activate the mouse, press the start button on your controller.

Step 3: Set Up Project 64

Picture of Set Up Project 64

Before you can use the controller, the Arduino needs to be connected and running the code you downloaded in the last step, and Processing 1.0 needs to be open with the N64_Controller program running.

Test it out in Notepad, pressing the A button should type an A, B should type a B, etc.

So now you have a working controller (hopefully) and you want to play some games.

Downl0ad PJ 64

Set Key Mappings
Start PJ 64 and open the settings menu first (Ctrl+T). Change the input controller to N-Rage's direct input. Open the "Configure Controller Plugin" menu and set the mappings using the controller.

Start Playing!
You should be all set to go now! Download some ROMs and start enjoying your homebrew N64 adapter.

Step 4: Arduino Code in Depth

Picture of Arduino Code in Depth

The N64 Protocol
The bits sent to and from the N64 controller on the one wire interface are encoded in 4 µs wide pulses. A '0' is 3 µs low and 1 µs high. A '1' is 1 µs low and 3 µs high.

The Arduino code in the methods N64_send or N64_receive use very carefully timed assembly code written by Andrew Brown to bit-bang the data line to communicate with the controller. nop blocks are used to wait the appropriate amounts of µs before polling the line of sending data.

On startup, 0x00 is sent to the controller, and then after that the only command used is 0x01 to query for the controller's status.

Data Encoding
When the data is received after a 0x01, it arrives as 16 bits of button information and 16 bits of analog joystick information. The data would look like 44000000000000400044440044000444.

The format of the bits is: A, B, Z, Start, Dup, Ddown, Dleft, Dright, 0, 0, L, R, Cup, Cdown, Cleft, Cright + 16 bits of analog stick position.

The method translate_raw_data() goes through the 32 bits, inserting them into the struct N64_status. The first 16 bits are simple 1 or 0, but the last 16 are translated into an integer approximately in the range (-80, 80) by

    for (i=0; i<8; i++) {
        N64_status.stick_x |= N64_raw_dump[16+i] ? (0x80 >> i) : 0;

After the data is in this simple form, it is easy to do whatever you want with it. In this case, it is simply sent over the serial port in the loop() method as a string of binary data with two integers for the x and y values.

The data sent over the serial port might look like: 0400000000000400 63 -67 which would mean that two buttons were pressed and the control stick was at 63,-67.

Step 5: References

Picture of References

Andrew Brown's project to create a gamecube to N64 adapter with the Arduino was invaluable while coding for this project:

Helpful schematics can be found here:

Information on the N64 controllers proprietary protocol can be found here:


xenoinc (author)2012-04-12

Great post!

With the new version of Arduion-1.0 i did have to include the "import" stuff & as well take care of RXTX-2.2pre1 / RXTX-2.2pre2 (see below)

Minor Issue:
Has anyone made a patch yet for the controller's sensitivity? With a lot of games this is a HUGE problem.

Overall, great job throwing together the documentation

Fix the RXTX errors:

POSSESSEDFERRET (author)xenoinc2012-05-11

Hey xenoic, which version do I need to download? And do I need the source or binary?

xenoinc (author)POSSESSEDFERRET2012-05-14

Currently they are only offering "RxTx-2.2 pre2". So this should help you out.

just pull back the latest RxTx 2.2 preview version & you should be good

cobrajet302gt (author)2017-09-26

I can't get this working, im using an arduino mega 2560 with uploaded , pin 2, 3.3v and gnd. I added import java.awt.Robot;

import java.awt.AWTException;

import java.awt.event.InputEvent;

import java.awt.event.KeyEvent;

I had to change my serial.list()[1] to 0 for coms port 3

i am not getting any output from the program from ether controller

SilasC3 (author)2017-02-05

I know this is an old project, but it is still awesome. Tried it out with processing 2.2.1 which seems to work fine. Just include the import already listed in the description and this import java.awt.event.KeyEvent; --- So total additional import is

import java.awt.Robot;

import java.awt.AWTException;

import java.awt.event.InputEvent;

import java.awt.event.KeyEvent;

kokolasticot (author)2016-08-31

Thank you for this instructable, I'm finally able to play again majora's mask as it should! (after some adjustment now that it is version 3 of processing :) )

Tgizzo (author)2015-09-02

hello, and Great instructable! very easy to follow. however, i have one question. i get an error that says

Error, disabling serialEvent() for COM3


any help? it is greatly appreciated, and keep up the good work!

LBC_Bulletproof (author)Tgizzo2016-03-26

I also have this problem :/

MrattS (author)2016-02-24

Hi, I'm trying to get this to run on Ubuntu 14.04.

I seem to only be able to get processing 3 to run natively and I'm running processing 1.5.1 out of WINE.

When I try to run the processing code I get this error message and I have no idea how to make heads or tails of it, any help with getting this up and running would be really appreciated! I mean to link it up to pure data and play some music with my controller! (also just Jet Force Gemini)

MrattS (author)MrattS2016-02-24

woops, forgot to include the error message- here's some info

Error inside Serial.<init>0

(with the line N64 Connection = new Serial(this, portName, 115200) highlighted)

the whole error message is much longer and I'll type it up soon- can't seem to copy paste...

MrattS (author)MrattS2016-02-24

i suppose I'll type the whole thing up if you let me know if you can help.

The first line is:; Unkonwn Application

DiamondDrake (author)2016-01-11

I have actually built on of the v-usb based adapters from I part of the way though porting his implementation into something more arduino friendly. I saw this link and spent a little time today to see how well it works. The code isn't very pretty but it does work. I modified it to read 2 n64 controllers at the same time and created a HID usb descriptor for v-usb for it to show up as 2 gamepads. No host software needed. Just a note, 2 of your links from above are dead.

Hopefully I can find the time to spin off a continuing instructable that shows how much more power you can get out of this set up.

Thanks for sharing

nfarrow (author)2015-08-29

Has anyone got this to work with a RetroPie?

WilliamW24 (author)2015-06-22

Im trying to use custom pads that send keypresses like the makey makey to control it.
how do i do it plz help been stuck on this for weeks

Maxaxle (author)2013-07-03

Having inserted the three import lines, I'm having an issue running the the two Processing files, both coming up with this issue:
"Cannot find anything named "KeyEvent.VK_UP"
on this line:
"VKey.keyPress(KeyEvent.VK_UP);// DUp"
Any ideas?

DONPATCH (author)Maxaxle2015-04-07

You need to add this"import java.awt.event.KeyEvent;"

Jdbye (author)2013-05-15

I've been trying to get Controller Pak support working, but it seems the timing of the sending/polling isn't accurate enough as getting the controller status and button state works fine (verified this by logging the data) but the mempak refuses to work. I don't know assembly so I can't convert the entire code to it, does anyone have any suggestions for optimizing my code and making timing more accurate?

Arduino code can be found here:
Project64 plugin source:

lolpaper21 (author)Jdbye2014-04-04

Hey I recently got ahold of your code (I don't know if you're even still on that project, its been about 10 months.) What COM port is your program searching for? Because My UNO is on COM3 and it says Failed to open com port

Jdbye (author)lolpaper212015-03-11

Just saw your reply, in that code it uses COM4 but you can change it in Controller.cpp near the top at #define comPort. I never added a config window to allow changing the COM port since having it hardcoded worked fine for my own personal use and I was more interested in getting controller paks working. Still not sure why the Memory Pak doesn't work, it seems to transfer data fine but struggles with the 32-byte data packets and the data gets corrupted. Might be a timing issue. It's a pity since the only adapter that works with paks to my knowledge is the Adaptoid and those are not easy to get anymore. Would be nice to have full pak support, add USB HID and maybe do a production run of some boards if people are interested.

double_g made it! (author)2015-02-12

Great instructable! In well under an hour I now have my old n64 controller hooked up to my pc all with stuff I had lying around :).

Also for those using the latest processing 2.2.1 make sure to look at @BrookBigford's comment for the additional import line that is needed.

BrookBigford (author)2014-11-19

Solution :

cannot find anything named "KeyEvent.VK_UP"

I just downloaded processing 2.2.1 and received this error trying to run the N64_Controller_mouse.pde file. I fixed it by including this line to the list of files to import.

import java.awt.event.KeyEvent; //<----SOLUTION

clynch7 (author)2012-12-26

I don't know if this instructable is still alive, but in the Processing window, it says that it "cannot find anything named "KeyEvent.VK_UP". " I feel like I'm so close to being able to play!

quasse (author)clynch72012-12-26

I think that over time the processing people have changed the way KeyEvents work, but I remember someone commenting with the changes that needed to be made to the code...

If that doesn't work, you could try and find the old version of processing that I used to write this tutorial. I think it was 1.0

magicman1648 (author)quasse2013-12-03

Have you had any luck in finding 1.0, or have you found a way to allow it to work on 1.5.1? - Thanks

Jeebiss (author)2013-07-04

I think I found the old version of processing for anyone interested.

Jeebiss (author)Jeebiss2013-07-04

Quick addon, I managed to get this working flawlessly with Zelda with the link I posted for Processing 1.0.9.Work the sake of being a clean project, I soldered on some jumper wires that came with my arduino, onto the wires for the controller. Now I can very easily add/remove the controller when I am not using it. Thanks for the GREAT instructable.

StudioAfterlife (author)2013-02-18

Anyone have any luck either getting this to work with Processing 1.5.1 or newer or find a place to download 1.0/1.1?

ozatomic (author)2013-01-28

Having some problems getting the Processing application to work. I've tried Version 2.0b6 and version 1.2.1 becasue I can find ! and i keep geting the following error about disabling serialEvent. Doesn't have anything about a RXTX missmatch Stable Library ========================================= Native lib Version = RXTX-2.1-7 Java lib Version = RXTX-2.1-7 error, disabling serialEvent() for //./COM2 java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke( at sun.reflect.DelegatingMethodAccessorImpl.invoke( at java.lang.reflect.Method.invoke( at processing.serial.Serial.serialEvent(Unknown Source) at at Method) at$ Caused by: java.lang.NumberFormatException: For input string: "" at java.lang.NumberFormatException.forInputString( at java.lang.Integer.parseInt( at java.lang.Integer.valueOf( at N64_Controller.serialEvent( ... 8 more

ozatomic (author)ozatomic2013-01-28

Ignore this i had enabled debugging in the ardunio file and forgot to turn it off .

clynch7 (author)2013-01-17

I've tried searching high and low looking for Processing 1.0, but with no success. Do you have any ideas where I could find it?

Klaudiuszm (author)2013-01-04

Great instructable! I've used it and it works great. I have found one troubling issue though, the analog stick is behaving like digital(being either on or off).

Klaudiuszm (author)2013-01-04

Great instructable! I've used it and it works great. I have found one troubling issue though, the analog stick is behaving like digital(being either on or off).

cubbydebry (author)2012-11-21

Okay so Im having a little bit of trouble working this out on my mac. I hooked up the controller correctly and check out the serial monitor, that seems to be working okay, I get a "4" for pressed, a "0" for unpressed and then the joy stick input, so I think the error is in the processing file. I am using processing version 2.0b6, I added the "import" lines and the only errors I get are:

WARNING: RXTX Version mismatch
Jar version = RXTX-2.2pre1
native lib Version = RXTX-2.1-7
and something about a stale lock file, if anyone has any ideas, your help would be greatly appreciated :)

Potentiometer13 (author)2012-11-01

How do you change the controller pin?
I tried changing #define N64_PIN 2 to #define N64_PIN 13, but this seems to do nothing; the controller does not work on pin 13 but it still works on pin 2.

The reason I ask is because I wan't to connect 4 controllers at the same time, allowing 4 people to control 4 controllers.

Well I found out how to change the pin number by changing the 0x04s in these values:
#define N64_HIGH DDRD &= ~0x04
#define N64_LOW DDRD |= 0x04
#define N64_QUERY (PIND & 0x04)

to 2 raised to the power of the pin that you want (so if I wanted pin 4, I would put 2^4 which is 16. Make sure the 16 is in decimal, not hex though.)

However, I want to add multiple controllers. I tried a few ways of doing this by changing numbers around values and stuff around, but what I have tried is unstable (player one always works, two sometimes, but can never go down, three is good 3/4s the time, and I have yet to have a problem with 4.)

Does anyone know how to make the code stably support at least 4 players?

Finally got 4 controllers to stably work, if anyone wants the code and/or help making it work, feel free to contact me... in some way, pming me is probably the best. Thanks so much quasse for the code by the way!

Can you post your code?

Hi, im very interested in what yoou said, which arduino did you use?

Sadly, I used the controllers for a little bit, and they started acting up again... I will have to do some more tests and try more stuff out. I am using a Uno by the way. It is really odd since I can see no reason why one controller should affect another and why the code only likes certain controllers in certain slots...

Jdbye (author)2012-05-23

I followed this guide and it worked well.
However, I wanted analog stick support, so I wrote a plugin for Project64 and other emulators.
The only thing that's missing is Memory Pak, Rumble Pak and Transfer Pak support (like the Adaptoid has)
I have no idea how to implement either of them and there doesn't seem to be much of help on google, nor can I find the source code of the Adaptoid plugin/driver, so if anyone could point me in the right direction that would be great.

relima (author)Jdbye2012-11-02

Please, can you make it available as a compiled file?

The source is very helpful, but I am running into problems when compiling it.


quasse (author)Jdbye2012-05-24

That sounds awesome, is your plugin posted online anywhere?

Jdbye (author)quasse2012-05-25

Oh, also, Rumble Pak support would be pretty easy to add. I would add it if I knew where my Rumble Pak was.

Jdbye (author)quasse2012-05-25

Only one controller is supported at the moment, but adding support for more would be easy. Mempaks work however by letting the emulator handle them (but that means you can't use physical mempaks)
You will probably have to change the COM port in Controller.cpp to match your Arduino's COM port (it's hardcoded for COM4 at the moment, I would add a configuration dialog to choose COM port, but I'm not sure how to make dialogs in C/C++)

natman3400 (author)2010-06-20

This is so fun to use with my atomic purple controller. The connector broke about a year back, and I haven't been able to use it with my real 64, and have been wanting to use it on the computer.

cdanger (author)natman34002012-10-15

Just a hint :] ...
If it's an easy 3 wires to hook the controller up to an arduino, it's an easy 3 wires to plug it into your console.

woodmaster (author)2012-07-01

Hey it´s a verry helpfull instructable, but can you tell me the colours of the cables ( because on my old controller is`nt a plug)????

Thanks woodmaster

abadfart (author)2012-03-14

im not really familiar with Arduino could you give me an idea of how to hook 4 controllers so i can play 4 player super smash brothers works for two controllers

About This Instructable




More by quasse:Use an Arduino with an N64 controller
Add instructable to: