ESP32 BLE HID to Bluetooth Classic Bridge —

Bridges a BLE HID gamepad to a Classic Bluetooth host such as a car head unit, PC, or gaming console. — GitHub

[ BLE HID gamepad ] <--BLE--> [ ESP32 ] <--Classic BT--> [ Host ]

Features

Requirements

Status LED

Connect an LED with a series resistor between the LED GPIO pin and GND. The default firmware uses GPIO 13 (WROOM/WROVER); the D1 mini build uses the built-in blue LED on GPIO 2.

PatternMeaning
Fast blink (100 ms)Waiting for BLE controller
Slow blink (500 ms)BLE connected, paging cached Classic BT host
Short-long blink (100 ms / 500 ms)BLE connected, discoverable — waiting for Classic BT host to pair
Steady onBoth connected, battery > 75%
3 blinks every 5 sBoth connected, battery 51–75%
2 blinks every 5 sBoth connected, battery 26–50%
1 blink every 5 sBoth connected, battery 0–25%

First pairing

  1. Flash the firmware using the installer below.
  2. Put your BLE controller into pairing mode.
  3. The ESP32 scans and connects automatically (status LED blinks fast while searching).
  4. Once the BLE controller is connected, the ESP32 appears over Classic BT as <controller name> Classic.
  5. On your host, scan for Bluetooth devices and pair as you would with any HID peripheral.

Both connections are cached in flash — on subsequent boots the ESP32 reconnects to the known controller and host without re-pairing.

Pairing a new host

Reset the ESP32 with the old host off or out of range. After 3 unanswered page attempts the bridge becomes discoverable automatically. Removing the bridge from the old host’s device list causes an immediate refusal and reaches discoverable mode faster.

Latency

Measured with a Stadia controller using controllertest.io:

SetupAverage latency
Stadia controller → Mac (direct BLE)~10 ms
Stadia controller → Bridge → Mac (Classic BT)~25 ms

The bridge forces the BLE connection interval to 15 ms (min = max = 12 × 1.25 ms) and forwards reports via a 5 ms periodic poll. Additional latency may come from Classic BT sniff mode negotiated by the host, which the bridge cannot control.

Web Installer

Before flashing, put the ESP32 into boot mode: hold BOOT, press and release RESET, then release BOOT.

Select your board, then click Install:

Requires Chrome or Edge on desktop. Does not work on Firefox or mobile browsers.
Full documentation and source code on GitHub.