Introduction: 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

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.

N64_Arduino
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.

N64_Controller
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];

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

N64_Controller_mouse
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

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
http://www.pj64-emu.com/downloads/

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

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

Andrew Brown's project to create a gamecube to N64 adapter with the Arduino was invaluable while coding for this project: http://www.cs.duke.edu/~brownan/n642gc.html

Helpful schematics can be found here: http://www.raphnet.net/electronique/gc_n64_usb/index_en.php

Information on the N64 controllers proprietary protocol can be found here: http://www.mixdown.ca/n64dev/