Introduction: Turn an N64 Controller Into a USB Gamepad Using an Arduino Leonardo

The easiest way to turn an N64 Controller into a USB Gamepad is to buy an N64 Controller Adapter for around £15. However it can also be done if you have an Arduino Leonardo or any other Arduino board with built-in USB communication.

What you will need:

  • An Arduino Leonardo (Also possible with other boards but the config will need to be changed)
  • An N64 Controller
  • 3 Leads
  • USB Micro Cable

Background:

This project is an evolution of the excellent instructable by quasse. That project used a standard Arduino Uno to communicate with an N64 Controller and send the state via Serial port to the computer. A processing sketch was then required to be running on the computer to convert the Serial input into keystrokes or mouse movements that could be used to play N64 games on an emulator.

This project varies in a number of crucial steps:

  • The Arduino Leonardo can act as a USB Gamepad directly without requiring any drivers or processing sketches to interpret the USB connection.
  • Being a gamepad and not a mouse/keyboard it means that the mouse isn't moving across the screen when playing games.
  • Now that the gamepad interprets the analog stick rather than a keyboard the controls are analog and not digital - before it didn't matter if the analog stick was left a little bit or a lot the game response was the same, now it is different.

Step 1: Setting Up the Arduino Environment

Unfortunately the Arduino doesn't support USB Gamepads, it only supports mouses and keyboards. So we have to edit the Arduino core files to support Gamepads. Rather than start messing with the files we can define a new board type that uses a different set of core files.

Start by navigating to C:\Program Files (x86)\Arduino\hardware\arduino\avr and open up the boards.txt file. Find the definitions for the Leonardo board and copy all of them. Then at the bottom of the file paste them. Then rename leonardo on every line to leonardon64. Then change the lines:

leonardon64.name=Arduino Leonard
leonardon64.build.core=arduino

to:

leonardon64.name=Leonardo N64
leonardon64.build.core=leonardon64

The final product should be:

##############################################################
leonardon64.name=Leonardo N64 leonardon64.vid.0=0x2341 leonardon64.pid.0=0x0036 leonardon64.vid.1=0x2341 leonardon64.pid.1=0x8036 leonardon64.vid.2=0x2A03 leonardon64.pid.2=0x0036 leonardon64.vid.3=0x2A03 leonardon64.pid.3=0x8036 leonardon64.upload.tool=avrdude leonardon64.upload.protocol=avr109 leonardon64.upload.maximum_size=28672 leonardon64.upload.maximum_data_size=2560 leonardon64.upload.speed=57600 leonardon64.upload.disable_flushing=true leonardon64.upload.use_1200bps_touch=true leonardon64.upload.wait_for_upload_port=true leonardon64.bootloader.tool=avrdude leonardon64.bootloader.low_fuses=0xff leonardon64.bootloader.high_fuses=0xd8 leonardon64.bootloader.extended_fuses=0xcb leonardon64.bootloader.file=caterina/Caterina-Leonardo.hex leonardon64.bootloader.unlock_bits=0x3F leonardon64.bootloader.lock_bits=0x2F leonardon64.build.mcu=atmega32u4 leonardon64.build.f_cpu=16000000L leonardon64.build.vid=0x2341 leonardon64.build.pid=0x8036 leonardon64.build.usb_product="Arduino Leonardo" leonardon64.build.board=AVR_LEONARDO leonardon64.build.core=leonardon64 leonardon64.build.variant=leonardo leonardon64.build.extra_flags={build.usb_flags}

Finally enter the folder 'cores' and copy the folder 'arduino' and paste it there renaming it to 'leonardon64'. Then within this folder delete the files 'HID.cpp' and 'USBAPI.h' and replace them with the files of the same name below.

These files effectively define the way that the leonardo creates the gamepad. Further information on creating these two files can be found in a freetronics forum by drake250.

Step 2: Uploading the Program to the Leonardo

Plug the Leonardo into the computer and start up the Arduino IDE. The under the tools menu select the board we have just created 'Leonardo N64'. Then using the attached code upload the project to the Leonardo. The majority of the code here has been lifted from the instructable by quasse and details of how the state of the N64 controller is retrieved can be found there.

Step 3: Connect the N64 Controller

Connect the N64 controller using three leads to the three Arduino pins (Ground, Pin2 and 3.3V) in my picture black, yellow and blue respectively. You will need to reset the board to get it working as there is an initialization that occurs at the start of the code.

If done correctly you should be able to go to set up USB Game Controllers in windows and the leonardo should display as a gamepad with 14 buttons and a joystick.

If that works then you're good to go and start using it with an N64 emulator or any other gaming platform that accepts gamepads.

A small note with Project64: I found that N-Rage's input plugin didn't connect to all 14 of the buttons, however Shunyuan's plugin worked perfectly (with a bit of an adjustment for the sensitivity).

Step 4: Notes for Using Other Arduino Types or Pins for the Signal

The project should in theory be possible to port to other Arduino types that feature direct-USB communication like the Micro or the Due but the following will need to be done:

  • Update Boards.txt to create a new type that mimics the board you want to use just like leonardon64 mimics the leonardo
  • In N64_Controller.h change the following section so that N64_PIN refers to the pin you are using and also change 0x02 so that it refers to the correct pin in the port register for that board (more info on port registers available here):
#define N64_PIN 2
#define N64_PIN_REGISTER 0x02

Good Luck!