Skip to content

Repository files navigation

JR BLE Gamepad v2.0

2026 - Fabrizio Sitzia, Sven Busser

Introduction

This ESP32 sketch turns your RC transmitter into a generic Bluetooth LE Gamepad. Run your favorite RC simulator wirelessly!

Introduction image

The goal was to get rid of any USB-C hubs, dongles, cables, etc. when running an RC sim on the above laptop, all while preserving the low latency and high resolution of a wired USB connection.

A gamepad emulation was chosen because most operating systems and RC sims support them out of the box, without having to install additional drivers.

The yellow transmitter you see on the above photo (a Jumper T8SG v2 plus) features a "JR Module" bay on the back. In the RC world this is some kind of de-facto standard for extending a transmitter's functionality.

It was a natural choice to try and make this project fit into such a module. But on transmitters that lack a JR module bay it is still possible to build the circuit directly into the transmitter's housing if a usable PPM signal is available. An example is given at the end of this document.

By the time of this writing the module has been tested successfully under Mac OS, Linux, various Android devices and Windows 10.

Features

  • variable PPM frame size, up to 8 channels
  • 100 nanoseconds, or 13 bit, pulse-width sampling resolution
  • 30mA average current draw @ 8V using a step-down regulator, 70mA with a linear regulator
  • wide range of PPM input signal voltages (1V to 15V)
  • compatible in theory with any operating system that supports BLE gamepads ...but in practice you will have to contend with improper or incomplete gamepad driver implementations and work around application bugs
  • Wifi access point & web interface running on the ESP32 module for tuning PPM and BLE settings

Building the module

What you will need

Required components

  1. ESP32 board (such as the ESP32 D1 Mini) that will fit into a JR module enclosure
  2. 3.3V regulator
  3. electrolytic capacitor (6.3V / 47uF)
  4. 3 resistors (44kΩ, 14kΩ and 330Ω) and a NPN transistor (BC547, BC337 or similar)
  5. a small piece of stripboard
  6. a few wires
  7. pin headers for soldering the ESP32 board onto the stripboard
  8. 5-pin female header for interfacing with the module bay pins
  9. 3D-printed module case (or a Jumper-style "DIY box") - STL files are included in this project
  10. an on/off switch
  11. soldering iron, dremel tool and a hot glue gun

On the software-side you will need the Arduino IDE (https://www.arduino.cc/en/software) with the libraries & extensions listed below:

  • esp32 Boards Manager extension by Espressif Systems (3.3.10)
  • NimBLE-Arduino Library by h2zero (2.5.0)
  • ESP32-BLE-Gamepad Library by lemmingDev (0.7.3)
  • Async TCP Library by ESP32Async (3.4.10)
  • ESP Async WebServer Library by ESP32Async (3.11.2)

Testing the ESP32 board

It is a good idea to first test your ESP32 board before building the circuit.

Launch the Arduino IDE and edit the JR_BLE_Gamepad.h header file: Check if the LED_PIN and PPM_PIN parameters fit your board, and #define DEBUG to have verbose information appear in the Serial Monitor. Connect the ESP board to the computer's USB port, then compile & upload the sketch.

If all goes well, the following output should appear in the Serial Monitor:

==================================================================
   JR BLE Gamepad v2.0 - 2021-2026 Fabrizio Sitzia, Sven Busser   
==================================================================

1. Initializing settings
   using defaults

2. Starting local Wifi access point:
   ssid = 'JR BLE Gamepad', password = 'OneWirelessRCTransmitter'
   local IP address: 192.168.4.1
   mDNS: announcing as 'gamepad.local'

3. Initializing webserver
   HTTP server started

4. Starting channelExtractorTask
   waiting for PPM signal...

5. Starting gamepadRefreshTask

You will also notice that the blue onboard LED is now blinking fast, indicating that there is no PPM signal.

IMPORTANT: The next steps assume that your transmitter outputs a 3.3 volt PPM signal on pin 5 in the JR module bay. It is vital to check that the PPM signal voltage does not exceed 3.3V, as higher voltages might damage the ESP32 or even your transmitter. Skip this section if you're not sure!

Use two patch wires to connect the GND (2) and PPM signal (5) pins from your transmitter's module bay to the ESP32 board's GND and PPM_PIN (IO22 by default):

WESP32 board test

Configure your transmitter to output a PPM signal.

As soon as a PPM signal is detected the sketch will start advertising the BLE gamepad:

5. Starting gamepadRefreshTask
   advertising BLE gamepad...

You will notice that the blue LED is now blinking more slowly, indicating that the module is not yet bound to a host.

Open the Bluetooth settings on your computer. You should see a device called JR BLE Gamepad. Pair the device, and if all goes well the onboard LED will turn a steady blue, and a stream of axis values will appear in the serial monitor:

-268 / -463 / -268 / -268 / -32768 / -32768 / -32768 / -32768
-268 / -463 / -268 / -333 / -32768 / -32768 / -32768 / -32768
-268 / -463 / -268 / -268 / -32768 / -32768 / -32768 / -32768
-268 / -463 / -268 / -268 / -32768 / -32768 / -32768 / -32768

Those values appear at a slow rate when you are not touching the transmitter's sticks, but increases as soon as you wiggle the sticks.

Go ahead and try your RC simulator now ;-)

Configuration - Web UI

This version of the JR BLE Gamepad sketch starts a local Wifi access point and provides a web-based user interface for configuring & fine-tuning most of its settings.

Tweaking those settings may be necessary to work around gamepad driver limitations (Hello Android) or game engine bugs (Hello Unity) or you may simply want to get the best performance out of your equipment.

Open the Wifi settings on your smartphone. Under the Available networks list you should see one named JR BLE Gamepad:

Wifi access point

Connect to it using the password OneWirelessRCTransmitter then open the url http://gamepad.local in your favorite web-browser:

Web UI

The settings are grouped into 3 sections: PPM signal, Gamepad features and Update frequency

Tapping a title or label will show an explanatory text for that particular section or parameter:

Web UI - explanations

Do not forget to click on the Save settings button on the bottom of the page after making changes:

Web UI - save settings

You will get a reminder that if you changed any settings under the Gamepad features section you should restart the module and freshly re-bind it to the host.

Testing the circuit on a breadboard

Now build up the following circuit on a breadboard:

Schematic of the JR BLE Gamepad module circuit The real thing should look a bit like the photo below.

IMPORTANT: Never plug in the USB connector when the ESP32 board is being powered by another power source (such as the transmitter on the photo), as this could damage your board or your computer's USB port!

breadboard

The purpose of the transistor circuit is to shift a wide range of input PPM signal voltages down or up to 3.3V.

If you had to skip the PPM signal test in the previous section, you may perform it safely now.

Building the module

Those instructions assume that the stripboard circuit is intended to be fit into a Jumper-style "DIY box". You may order such a box online, or 3D-print a custom one using the STL files included in this project.

Prepare a piece of stripboard of 33mm x 55mm size (12 x 21 holes), then cut away a 1x5 hole stripe on the bottom right corner to make place for the module bay's 5-pin header, and a 2x4 hole stripe on the top right corner to make place for the on/off switch:

stripboard cut to size

On the photo you also see a female 8-pin header that has been shortened to 5 pins using a dremel. It will be used to interface with the JR module's pin header.

For cutting / joining the traces and for drilling the holes for the screws, refer to the included Fritzing files and to the following picture, which shows a bottom view of the stripboard:

stripboard bottom view

The two black discs are the locations for the screws. They line up exactly with the third hole on the top and bottom rows of the stripboard.

To achieve a perfect fit with the module bay pin header, start by bending the pins 180 degrees and fit them to the stripboard like so:

5-pin header stripboard fit

Drill the holes for the screws and screw the stripboard into the module case.

Plug the case into the transmitter, then plug the female header on top of the module bay's 5-pin header. Bend / adjust the female header pins until they line up exactly with the stripboard holes:

module bay fit

Add a small dab of hot glue to temporarily hold the connector in place until it is soldered to the stripboard. Let the hot glue set, remove the stripboard from the module case and solder the connector's five pins.

That was the most fiddly part. Soldering the remaining components to the board is easier. The finished top and bottom sides will look like this:

module top and bottom view

Notes:

  • Only the required 3 pins (and an additional one for increased mechanical stability) have been soldered to the above ESP32 board instead of entire pin-headers. That makes it easier to de-solder the board if necessary.
  • Unused stripes are grounded so they act as a ground plane
  • The author forgot to join two traces which is why there is one additional wire (...you should not solder stuff after 23 o'clock!)

The final result after fitting the board & on/off switch into the 3D-printed module case:

finished module build

The module lid clicks onto the base and features a thin translucent plastic layer over the board's LEDs:

module bay fit

(...picture taken while being distracted by the cat ;-)

Transmitters lacking a module bay

Transmitters that lack a JR module bay can still be turned into a Bluetooth gamepad. The only condition is that they have to provide a usable PPM signal!

The XK X6 is an unexpensive transmitter that is bundled with the micro-heli that you see on the photo:

X6 front view

It lacks a module bay, but it does feature a trainer port on the back. Trainer ports typically carry a standard PPM8 signal:

X6 rear view

The best way to find out is to actually measure the trainer port signal with an oscilloscope:

X6 PPM signal

And yes, it turns out to be a standard 8-channel PPM signal with 3.3V amplitude. That signal can be fed directly to an ESP32 IO pin. No voltage-level shifting is required!

The ESP32 needs a 3.3V power source which you could of course provide using a separate voltage regulator that you feed from the transmitter's battery. But in this case it turns out that we can syphoon power from the transmitter's onboard regulator: It is an AMS1117 3.3V linear voltage regulator with a 1A max current rating.

As the transmitter only draws 150mA, it should have no problem in providing an extra 30mA for our ESP32 board.

The X6 main board also features measuring pads which are convenient for soldering the GND, 3.3V and PPM wires to the ESP32 board. The wires have not been soldered directly to the ESP board but to a 3-pin header instead. The 3.3V wire is routed to a toggle switch (the blue one on the top right of the photo) before going to the 3-pin header.

The pin-header is secured with a screw at the location indicated by the arrow:

X6 measuring pads

A servo cable, which mates with the 3-pin header above, is soldered to the ESP32 board.

The board stands upright on the left bottom side of the transmitter's back case. This was deemed the best location to avoid obstructing the Bluetooth antenna, while allowing access to the ESP board's USB port from the bottom of the transmitter:

X6 voltage regulator

The ESP board has been secured with some hot glue (...you could go fancy and create a custom 3D-printed bracket instead, but hot glue does the trick for a "proof-of-concept" build like this one ;-)

A hole has been drilled into the front of the transmitter's case for viewing the board's LEDs, and another hole on the bottom for accessing the USB port:

X6 LEDs and USB port

X6 transmitter video with the BLE mod in action:

XK X6 BLE demo

Note:

The X6 transmitter has a quirk which may cause the module to fail to properly detect a PPM signal.

When powering on the transmitter the TX goes BEEP BEEP BEEP if the throttle stick is not at its bottom position... until you move the stick down. That beeping disrupts the PPM signal. The X6 designers apparently deemed a proper-sounding BEEP to be more important than a timely PPM signal!

Therefore, make sure the throttle stick is at the bottom before switching on the transmitter.

Credits

To For
Sven Busser - the design of the 3D-printed JR module case
- beta-testing on Windows 10
lemmingdev for the excellent ESP32-BLE-Gamepad library
chegewara tons of ESP32 code examples, not only related to BLE

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages