Multiplayer Bluetooth controllers adapter for retro video game consoles

Similar projects worth following
BlueRetro is a multiplayer Bluetooth controllers adapter for various retro game consoles. Lost or broken controllers? Need those rare and obscure accessories? Just use the Bluetooth devices you already got! The project is open source hardware & software. It's built for the popular ESP32 chip. All processing for Bluetooth and HID input decoding is done on a single core which makes it easy for other projects to use the Bluetooth stack within their own project as long the application is running on the other core. It's a spiritual successor in some way to my project fork. This is my wildcard entry to the #2020HACKADAYPRIZE


BlueRetro primary target is to be a Bluetooth controllers adapter for retro video game consoles. However the software is built so that any Bluetooth HID (BR/EDR/BLE) device can be connected and used including gamepad, mouse, keyboard, trackball, etc.

7 controllers can be connected simultaneously on a single adapter for multiplayer games. This means the adapter also emulate the multitap accessory for most systems. Rumble accessories/function is supported. Keyboard, trackball & mice console accessories are supported.

The adapter is highly configurable via a Web Bluetooth (BLE) interface for mobile & desktop. Buttons and axes can be mapped to any buttons or axis direction (ex. mapping axis direction to a button, buttons on an axis direction, inverting an axis direction, trigger to axis, buttons to trigger, etc.). Various scaling and response curve options is available for axes and trigger. Presets configuration for various games are available.

A secondary objective is for the code to be easily used on other ESP32 project to add Bluetooth HID device input. To help this the Bluetooth and HID decoding is all done within one core. The retro console interface on the second core can be easily removed and replaced by another application that need input. (ex. RC cars, robots, game consoles, emulators, etc.). While the project in itself is more toward gaming, the code could be used as a component of an adaptive tool. 


A hardware goal is to be as simple as possible. A unique module with a ESP32 and one connector (DB-25 so far) should be the core of the solution. Most system will only need a straight cable adapter or an adapter only including level shifter. More complex adapter will exist for systems with full parallel input, direct potentiometer interface, RS485 (JVS), RS232 or USB.



Adobe Portable Document Format - 79.16 kB - 05/21/2020 at 23:42


  • 1 × ESP-WROVER-KIT V4.1 or ESP32-DevKitC V4
  • 1 × DB-25 Female connector
  • 1 × DB-25 Male connector
  • 1 × Target system cable plugs
  • 1 × Digilent Pmod MicroSD Only if using ESP32-DevKitC V4

  • 2020-06-04 Progress update

    Jacques Gagnon8 hours ago 0 comments

    Finished log on Bluetooth tracing Saturday. That took more time to finish than I expected, took much of my available time last week. Been working since Sunday on the Generic HID pad support and it finally work! I use a 8bitdo NS30 to test this since it got a switch to toggle between 2 HID descriptor: xinput and dinput.

    BlueRetro detect controllers in 2 ways. Very early in the Bluetooth stack it will match the device name with a list of known supported controllers. This is not great but it's required for devices with weird connection process like the Wiimote. If the name string doesn't match anything then it's tag as a generic HID device. This will trigger the adapter to get the HID descriptor from SDP. At that point the adapter will try to match a known controller again by trying to fingerprint the HID report to one of the known controllers. As an example if the NS30 was set to xinput at that point the adapter would find that it's report match the one from the Xbox One controller and simply consider the device as a Xbox One controller from that point on.

    When the NS30 is set to dinput it will match nothing the adapter know. Adding explicit support for the main families of controller is fine but it's not viable to do so for every random controller. So when nothing matches the adapter will follow what the HID descriptor state. That should give good result for axes but the buttons mapping might be a bit weird. So default mapping setting will likely not do but once configured properly it should be fine.

    Next I will start working on HID Keyboard support!

  • Learning Bluetooth Classic (BR/EDR) with HCI traces

    Jacques Gagnon05/28/2020 at 00:46 0 comments

    I worked in WiFi for around 10 year, five first as a tester then as a Linux driver developer. So I got a base on RF but didn't know much about Bluetooth until I started this project. What I learned from those years is that you got to get wireless trace to fully understand issues. I learned more about WiFi doing trace than reading books. Book & spec tell you what the devices are supposed to do. Trace show you the reality!

    So my approach to learning Bluetooth was to get some traces first and then analyze them with the help of the Bluetooth core spec. I did try to look online but finding stuff about Classic Bluetooth (BR/EDR) is hard since pretty much everything you will find is about BLE.

    This is written from the point of view of writing a host Bluetooth Classic stack on a embedded system. What you will find online is mostly about making devices.

    Bluetooth tracing

    With Bluetooth you got basically two ways of tracing. Over the air using some costly hardware or a ubertooth or tracing the HCI communication interface between the Bluetooth stack and the Bluetooth controller. 

    The controller is a mix of software and hardware handling the very low level of a Bluetooth transmission. The Bluetooth stack implement the higher level of the Bluetooth spec. As an example for ESP32 the software part of the controller is located at it's a closed source library. You really don't want to face bugs in there because you are then at the mercy of the vendor support. The esp-idf provide BlueDroid as the software stack.

    For BlueRetro I decided to write my own "minimal" stack talking to the BT controller directly via the ESP32's VHCI interface. My reasoning for doing so was that I knew nothing about Bluetooth and duplicating what I was seeing in the HCI traces directly to the controller looked easier and faster than learning a particular stack API. I felt I would get a more generic knowledge this way. Also early game console controllers don't follow Bluetooth spec/good practice 100% and I felt that a generic stack could limit the project and I didn't want to start hacking into a giant Bluetooth stack code base. I just want reports from a HID device and it should be simple enough I thought back then.

    You can get most of the job done with only the HCI traces but in my case I do see a couple bugs already that would require a wireless trace to help figure out the issue.

    Read more »

  • 2020-05-27 Progress update

    Jacques Gagnon05/27/2020 at 12:53 0 comments

    Most of my spare time last week was on preparing the project page, github readme, github wiki and creating a basic schematic for the 2 ESP32 eval board I use. I also filmed a video to present the project. It's at bit boring but at least it shows what the adapter can do :) .

    This weekend I took some time to go for a few low-hanging fruit. I completed the Wiimote and extension support. The Bluetooth part was done for age but somehow I never added the glue code in the adapter. Now it's done and it work great!

    Next I will work on finishing the generic HID support base on HID descriptors. Again the hard part is already done (parsing the descriptor) just need to add the glue code.

    I'm also working on a log describing my process of learning Bluetooth Classic only using HCI trace.

  • Background and current status

    Jacques Gagnon05/22/2020 at 12:40 0 comments

    I started this project in early 2018 when I ordered Switch Pro, Xbox One S & PS4 Bluetooth controllers on amazon. I'm still not owning neither of those systems! I had resurrected my 6-year-old fork of the Cube64 project a few months back. While I absolutely loved hacking on that project, it was clear to me it was kind of pointless. Replacing old N64 controller with old GameCube controller was not ideal (even if Nintendo re-release GC pad every SSB release). What was really needed was a universal adapter that would take any current HID devices. Why bid war on eBay with collectors to get a console specific keyboard or mouse?

    I kept working on Cube64 as a test bench for the next project. It was simple enough that I could easily test various features I had in mind in the real world. At the same time that spring I took a look at what would be the chip to host that next project. I wanted a chip with a good community so I had in mind to either use a STM32 with an UART BT chip or one of the Nordic chips. After learning more about Bluetooth, I realized what I really needed was a Dual Mode Bluetooth chip (Classic BT + BLE). Most controllers are Bluetooth classic (BR/EDR) but many new devices are only BLE. This ruled out Nordic and while looking at an all-in-one Dual BT solution I came across the ESP32 which had a good community around it and a nice SDK. I still had in mind to use both Bluetooth and USB HID devices at that point. I was a bit annoy the ESP32 didn't have a USB OTG PHY since it was perfect otherwise. In the end after reflection I decided to drop the USB support and focus on Bluetooth. So ESP32 it was!

    The rest of 2018 was mostly trying out the various examples for the ESP32 to know the chip better while hacking a bit on Cube64 and learning more about BT Classic. It's hard to learn BT Classic in the age of BLE!! More on that in another log ;) .

    By May 2019 I had a N64/GC driver using the RMT hardware for talking to 4 controller simultaneously. Then by the end of June I had a very primitive Bluetooth stack that could talk to a WiiU Pro controller. In July I glued together both demos in what end up to be the first BlueRetro version. Then in August I decide to implement the Maple protocol for Dreamcast with GPIO Bitbang. This was really hard I almost gave up. I realized then that the ESP32 got that evil chip bug that prevents both core from reading from DPORT simultaneously. Their fix in the IDF is to stall the other CPU when access is required. This is fatal when you try to bitbang 2x 1 MHz signal simultaneously. Once I realized this, I simply staled the other core when I was about to go bitbang and this resolved the problem.

    With the hardest system supported I focus on my Bluetooth stack most of fall 2019 and added support for Wii, PS3, PS4, Xbox One S and Switch Bluetooth controllers. Then I added simultaneous BT device support. Then in November I added the BLE configuration interface through Web Bluetooth. My vision is that an end user should not need to install anything beside a browser. I knew nothing about JavaScript but I managed to hack something functional. Now I could configure the buttons mapping and various other features. At that point it started to feel like a real product!

    I planned to go into Hackaday prize 2020 with v1.0 ready but I'm still at v0.1. It's a lot of work and it's crazy at my real job these days so my pace reduced a lot in the last few months. After thinking a bit about waiting another year to get this out, I finally decided to go in with what I got now and continue development in the public.

    Read more »

View all 4 project logs

View all 7 instructions

Enjoy this project?



Similar Projects

Does this project spark your interest?

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