Vector Rocket Pro

buildscc | 17 May 2012 | | projects

Rusty did cool stuff here

Older · View Archive (146)

NES Controller as USB Game Controller


Chris Woodall wanted to play video games with an NES controller (the motivating games being Cave Story and Jamestown, the former was successfully beat with the controller). To do this he decided to use an Arduino UNO (definitely overkill). The best method for doing this is to announce your microcontroller as an HID Keyboard so that it can write to the keyboard buffer like any other USB peripheral keyboard. This adds the convenience of portability and flexibility; however, it requires flashing the ATMega8u2 on the Arduino UNO, which normally only handles serial communication via USB with a firmware that handles HID communication via USB. To do this you need to do some sketchy (explained below), but there is little risk of bricking your Arduino because you should always be able to flash the original atmega8u2 firmware.


Parts List

  • An Arduino Uno
  • A NES Controller from Amazon
  • Lots of wires (solid core preferably)

Future Upgrade for SNES Controller version

Future No Arduino Version

  • PICS actually sell DIP package chips that can be programmed to do USB :) [1]
  • However, I can do a PCB for an ATMega8u2 or similar.


NES Version

Basic Schematic for the NES Controller to Arduino interface

SNES Version

Coming Soon…


Getting Data from the NES Controller

NES Controller Data Protocol

Getting the data off of the NES controller is really straight forward and I read up on it here. The basic idea is that the NES controller contains a shift register (parallel in, serial out). To start off, the latch should be low as should the clock (pulse) pin. To start a read you pull latch high for approximately 2us to load the data into the shift register. Then you read the data on the serial line, and pulse the clock high (for ~2us) then do another read. in total you should pulse 8 times and read each bit in the shift register. I think the clock rate can be changed a little bit, but 2us is the fastest the Arduino can reliably clock at (unless you use nop’s). The SNES controllers function the same way, but the Shift Registers have 16 bits instead of 8.

To tackle the NES Controller easily I created a NESController class. The class documentation is in the code.

Example Pseudo-Code

uint8_t data = 0;
digitalWrite(latch, LOW);
digitalWrite(clk, LOW);

// Pull Latch high for 2us to load new data
digitalWrite(latch, HIGH);
digitalWrite(latch, LOW);

// Read off the first bit
data = digitalRead(din);

// Read off the next seven bits 
for (int i = 1; i <= 7; i++) {
    // Pull clock high 
    digitalWrite(clk, HIGH);
    // Read new data into the "front" of data
    data |= digitalRead(din) << i;

   // Push clock low for 2us
    digitalWrite(clk, LOW);


Making Your Arduino an HID device with LUFA

Sketchy method to put your Arduino into DFU mode to program the ATMega8u2

In order to make your Uno look like an HID device you need to flash your ATMega8u2 with an appropriate firmware. The problem is that to do this you need to do some sketchy by grounding some leads. This is discussed in full in the following link: Putting arduino in DFU mode. In order to actually program the DFU you will need to install dfu-programmer. Instructions can be found here along with some Keyboard HID code. The actually Keyboard HID code I used is found here. Thanks to darran for his contributions for the Keyboard LUFA code.

Basically once you load up the Arduino code and then flash the Keyboard firmware you should be able to unplug your device, plug it back in and have it detected as a keyboard. All your code needs to do is send, via a serial connection the data that the HID Keyboard firmware is expecting to receive in this case it is 8 bytes.

Byte	Contents
0	0 - Left CTRL | 1 - L SHIFT | 2 - L ALT | 3 - L GUI | 4 - R CTRL | 5 - R SHIFT | 6 - R ALT | 7 - R GUI
1	Not Used
2 - 7	HID Active Key Usage Codes (outlined below)

NOTICE: In order to reprogram your Arduino you will need to flash the default Arduino Serial hex unto your arduino. This can be found on your computer (on OSX that will be in your /Applications/ directory. On other OSes I am not 100% sure where it will be located)

The basic flow for programming is as follows:

  $ sudo dfu-programmer at90usb82 erase
  $ sudo dfu-programmer at90usb82 flash Arduino-usbserial-uno.hex 
  $ sudo dfu-programmer at90usb82 reset


Sending the Keyboard Commands

This is pretty simple. To communicate with the keyboard all you need to do is start a serial connection with: Serial.begin(9600). Once a serial connection is created you check the controller, load up a key into an appropriate byte of the buffer. Then write that 8 byte buffer to the Serial port.

Example Code

byte buf[8] = { 0 };	/* Keyboard report buffer */

void setup()
  Serial.begin(9600); // initialize serial connection
  delay(200); // Allow computer to recognize HID device

void loop() 
    j = 2; // Reset buttons count
    buf[2] = 0;
    buf[3] = 0;
    buf[4] = 0;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = 0;

    if (( | 0b11111110) != 0xFF) {
        buf[j] = KEY_Z;
        j += 1;
    if (( | 0b11111101) != 0xFF) {
        buf[j] = KEY_X;
        j += 1;
    if (( | 0b11111011) != 0xFF) {
        buf[j] = KEY_A;
        j += 1;
    if (( | 0b11110111) != 0xFF) {
        buf[j] = KEY_S;
        j += 1;
    if (( | 0b11101111) != 0xFF) {
        buf[j] = KEY_UARROW;
        j += 1;
    if (( | 0b11011111) != 0xFF) {
        buf[j] = KEY_DARROW;
        j += 1;
    if (( | 0b10111111) != 0xFF) {
        buf[j] = KEY_LARROW;
        j += 1;
   if (( | 0b01111111) != 0xFF) {
        buf[j] = KEY_RARROW;
        j += 1;
    Serial.write(buf, 8);	// Send keypress

HID Keycodes

Here are some modifiers and some alpha numeric keys as define statements.

// List of standard HID Keycodes
#define KEY_LEFT_CTRL 0x01
#define KEY_LEFT_SHIFT 0x02
#define KEY_RIGHT_CTRL 0x10
#define KEY_RIGHT_SHIFT 0x20
#define KEY_NULL 0
#define KEY_A 4
#define KEY_B 5 
#define KEY_C 6
#define KEY_D 7
#define KEY_E 8
#define KEY_F 9
#define KEY_G 10
#define KEY_H 11
#define KEY_I 12
#define KEY_J 13
#define KEY_K 14
#define KEY_L 15
#define KEY_M 16
#define KEY_N 17
#define KEY_O 18
#define KEY_P 19
#define KEY_Q 20
#define KEY_R 21
#define KEY_S 22
#define KEY_T 23
#define KEY_U 24
#define KEY_V 25
#define KEY_W 26
#define KEY_X 27
#define KEY_Y 28
#define KEY_Z 29
#define KEY_RARROW 79
#define KEY_LARROW 80
#define KEY_DARROW 81
#define KEY_UARROW 82




4x4x4 LED Cube


Coming soon…


Bill of Materials

R1;R2;R4;R7 2.2K 2.2K RESISTORS 1/4 WATT N/A N/A N/A
R5;R6;R8;R3 100 100 OHM RESISTORS 1/4 WATT N/A N/A N/A
IC1-IC4 74LS164 74LS164 DIP Serial In-Parallel Out Shift Register N/A N/A link
U1 Arduino Uno ARDUINO N/A N/A N/A


Schematic for the 4x4x4 LED Cube (made with EAGLE)

The actual EAGLE files can be found on the github in the hardware folder.

How does it work?

LED Cube Electronics


Github Repo