Bluetooth Nintendo 64 Controller

Hi everyone,

I have successfully got an Arduino Uno talking to a Nintendo 64 controller, and then translating the response into bluetooth HID packets. This allows you to use an N64 controller wirelessly with most operating systems.

https://www.youtube.com/watch?v=5XgjOnGEn5E

https://github.com/LogicalUnit/N64_Bluetooth

I would like to continue with this project, to make it easier and cheaper for others to make their own.

First, a few basics:

  1. The N64 controller is a 3-wire device: 3.3V, GND, and Data (which is bidirectional).

  2. We do not use digitalWrite to make the Data pin HIGH or LOW. Doing this on a 5V Arduino Uno would fry the controller. Instead we pull it LOW, and use a macro to switch it from output to input. When the Data pin is set to input (while LOW), it becomes floating, and there is a pull-up resistor inside the N64 controller. This simulates a high output.

  3. To send a logical 0 to the N64 controller, put the data pin low for 3us and high for 1us. To send a logical 1, put the data low for 1us and high for 3us.

  4. After sending n bytes to the controller, send a logical 1 as a stop bit. After receiving n bytes from the controller, wait for a logical 1 as a stop bit.

The Arduino Uno works great for 3 reasons:

  1. It provides a regulated 3.3 volts, which is exactly what our controller needs.

  2. It has a clock speed of 16MHz, which means it can do 16 operations in a microsecond. This is great for our logic.

  3. It mates with the SparkFun ProtoShield, which has a BlueSMiRF port for a Bluetooth HID module. Easy!

What I would like to do is get the code working on an Arduino Pro Mini, because it is smaller and cheaper. This has the following issues:

  1. The 16MHz 5V Arduino Pro Mini does not provide a regulated 3V3 for our controller.

  2. If we were to use the 8MHz 3.3V Arduino Pro Mini, we would still need to provide 3V3 and GND pins for the controller. Could we do this by pulling digital pins HIGH and LOW?

  3. Could we stop using the input/output macro and use digitalWrite instead? Could we fit the required logic into only 8 instructions per microsecond instead of 16?

Any advice would be greatly appreciated :slight_smile: