Close
0%
0%

Bluetooth Low Energy Receiver for NES Controller

Hardware that adds a BLE interface to the NES controller port

Similar projects worth following
This is a proof-of-concept system designed to interface the Nintendo Entertainment System controller port with a wireless controller over a Bluetooth Low Energy (BLE) interface. The primary board implements all logic needed to translate BLE communications to the 4021 shift-register logic used by the NES to read in controller inputs. Other logic, such as hardwired LEDs and a DIP switch set, is used to allow for prototyping use.

I decided to use as many packaged devices as possible to reduce the complexity for hand-assembling this board, making use of a fully-enclosed 10-LED package (LTA-1000G) and several Bourns resistor networks.

This device uses leftover parts from previous projects, including the PIC18LF2420 MCU and HM-10 BLE module.

PCB is a 2-layer design with HASL finish, fabricated by JLCPCB. Firmware was developed with MPLAB X, compiled with XC8 (C), and programmed/debugged with a PICkit 3.

The main board was designed with the controller interface in mind. A real NES controller uses a 4021 shift register with some pull-up resistors to relay its button presses to the 6502 CPU running inside the NES. The 6502 uses three of its data bus bits to interact with the 4021: a latch output that latches the parallel inputs in place, a clock output that clocks the shift register out, and a data input that reads out the data starting at bit 8. This board implements that interface, along with some additional circuitry.

Driving this interface is a PIC18LF2420 microcontroller. I use these a lot because I bought a few of them for my graduate school project and have been looking for uses for the spares. They're very capable and work well for this effort. I connected the 8-bit controller bus to the PIC18 to simulate the button presses inputs to the 4021. I placed a pair of ULN2003A load drivers in parallel with the data bus to drive a 10-LED display module for debugging purposes. As the ULN2003A IC has pull-down circuitry, I placed a 1K ohm resistor array in the circuit to pull up the bus so that it emulates the NES controller interface - the NES will invert all inputs on its side. Therefore, a '0' indicates a press and a '1' is idle behavior. The result is a ~4V voltage on the 8-bit bus, which is enough to register as high with a 4021 (3.5V is the threshold for high). This, however, is simply a fail-safe circuit as the PIC18 will be using its push-pull outputs to drive the 4021 at close to Vdd/Vss.

Bluetooth Low Energy is handled by an HM-10 module. I had one left over from my graduate school project and decided to put it to use here. This is a module based on the CC2540 MCU that allows designers to interface a lower-end microcontroller with a Bluetooth Low Energy interface - all that is required is a UART interface, which virtually any microcontroller in existence has. The HM-10 is intended to receive a single byte representing the 8 button states of an NES controller and relay it to the PIC18 through serial.

The PIC18 is clocked at 4 MHz with an external crystal and programmed to read the 19200 baud output of the HM-10 through its USART interface and uses an interrupt-driven 8-entry ring buffer (interrupt on serial receipt) to store data prior to pushing it out onto the 4021 in the main program loop. The PIC18 looks for a "high" state pin on the HM-10 to read data from it; if this pin is low, there is no BLE connection and the PIC18 sets the 4021 to an idle state. A system tick of 1.024 ms is used for timekeeping; if 100 ticks pass between receipt of a byte over BLE, the system resets the 4021 interface back to a high / idle state.

For debugging, a switch is present to allow the MCU to enter test states in which the data bus is set to different states on startup to test the functionality of the PIC18. The user must select a mode and press reset for this state to be set.

A custom cable was fabricated for this effort. I simply snipped the controller side off of a broken third-party NES controller and matched the colored wires up with the port pinout with an ohmmeter. I consulted the Internet for an NES controller pinout and soldered them up to a DE-9 connector. I used some heat shrink and a plastic hood for protection of the contacts and to provide strain relief on the cable and it works very well so far.

A Python script was created with pygame and Bleak to relay the inputs of a Logitech F310 gamepad to the main board over BLE. This script simply reads the button states with Pygame, places them into an array, collapses this array into a byte, and transmits it with BLE. This script runs on my M2 MacBook Air and seems to work pretty well.

I put a 1A fuse on the board to protect my top-loader NES from harm as this board draws power right from the NES.  I'll probably...

Read more »

main-12-8-2024.c

Updated C source file with fixed ring buffer code and timer interrupt logic

x-csrc - 8.15 kB - 12/08/2024 at 23:34

Download

main-11-3-2024.c

PIC18LF2420 C source file with new features

x-csrc - 8.47 kB - 11/04/2024 at 01:35

Download

NES BLE CABLE.pdf

Cable drawing interfacing an NES controller plug to a DE-9 connector

Adobe Portable Document Format - 38.11 kB - 10/30/2024 at 22:49

Preview

controllerBLE.py

Python 3.10.7 test script using pygame and Bleak to transmit Logitech F310 button presses to the main board. Confirmed to run on an M2 MacBook Air running Sonoma.

x-python-script - 2.92 kB - 10/30/2024 at 22:42

Download

Manufacturing-10-19-2024.zip

Gerber and drill file for PCB manufacturing

Zip Archive - 38.44 kB - 10/28/2024 at 01:18

Download

View all 6 files

  • 1 × 4609X-101-472LF RES ARRAY 8 RES 4.7K OHM 9SIP
  • 1 × CD4021BE Logic ICs / Flip-Flops, Latches, Registers
  • 1 × L777TSEG09POL2RM8 CONN D-SUB PLUG 9POS VERT SLDR
  • 1 × ECS-40-20-5PX-TR CRYSTAL 4.0000MHZ 20PF SMD
  • 1 × DS01C-254-S-05BE SWITCH SLIDE DIP SPST 0.025A 24V

View all 20 components

  • Potential update: PCB revision to replace HM-10 / PIC18 with Raspberry Pi Pico W

    Zachary Murtishi12/23/2024 at 13:12 0 comments

    I've been thinking about revising the PCB design to use a Pi Pico W - I've had one on my desk for a while and have been thinking about ways to incorporate it into this design. I figure I can change the design of the PCB to incorporate the Pi Pico W and port the PIC routine to MicroPython code.

    I haven't actually started any work on this, it was just an idea I had.

  • Updated ring buffer code

    Zachary Murtishi12/08/2024 at 22:00 0 comments

    I was attempting to lift my ring buffer code from this project for a different, AVR-based project, only to find that the ring buffer did not work as intended in that application. I discovered a bug in the pop() function in which the head variable is not properly updated prior to retrieving information from the ring buffer i.e. head should be decremented prior to retrieving data. This has been fixed and the source file in the files section has been updated to reflect this change.

    I also corrected some faulty timer interrupt logic, which resulted in the timeout always kicking in and resetting the 4021 bus. The tick count is now cleared every time a serial receive nterrupt fires.

View all 2 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates