Embedded radio options, firmware ecosystems, and engineering tradeoffs for converting a custom USB HID gamepad to wireless on PC.
Every commercial adapter — Brook Wingman, 8BitDo Wireless Adapter 2, Mayflash Magic-NS, COOV — relies on VID/PID lookup tables to identify known controllers. A generic controller with an unknown vendor/product ID is silently rejected.
The 8BitDo adapter operates in the wrong direction: it receives wireless Bluetooth controllers and outputs wired USB. Brook's Wingman line converts between console ecosystems — they accept known controllers and re-present them for a target platform. The FGC 2 supports 150+ controllers, but every one is a named product with a known VID/PID.
USB HID gamepads have no standardized report layout — button count, axis count, axis resolution, hat switches, and report IDs all vary per device. Parsing an arbitrary HID report descriptor is complex, and no commercial adapter attempts it. The only marginal exception is Mayflash Magic-NS, which may recognize common DirectInput report formats, but a truly custom HID descriptor will almost certainly fail.
Two fundamentally different architectures. Option A bypasses the existing controller MCU — wire buttons/sticks directly to a BLE-capable microcontroller. Option B preserves the original controller electronics and adds a USB-host-to-BLE bridge.
After power-cycling the ESP32, Windows shows the device as "connected" but no HID input works — you must unpair and re-pair every time. Root cause: Windows' BLE HID stack caches stale GATT handles after the peripheral reboots. Reported across ESP32-BLE-Gamepad issues #65, #79, #287 and NimBLE-Arduino #850. The library's ForcePairingMode and NimBLE patches help but don't fully resolve it. iOS and Android work fine. This issue alone may push you toward proprietary 2.4 GHz.
This is how every serious commercial wireless controller works. A proprietary radio protocol (not Bluetooth) between controller and a small USB dongle. The dongle presents as standard USB HID — no Bluetooth stack, no pairing quirks, no Windows driver issues.
Nordic provides a complete, production-ready wireless mouse/keyboard/dongle system in the nRF Connect SDK. Includes USB HID on the dongle via native USB, triple-mode operation (wired, BLE, proprietary 2.4 GHz), and extensive documentation. Adapting to gamepad requires changing HID report descriptors from mouse/keyboard to gamepad format.
OpenSplitDeck (945 GitHub stars, v0.3 March 2026) is a modular wireless controller using nRF52840 + ESB. It implements gamepad + mouse + keyboard HID reports, haptics/rumble, and trackpad input — directly applicable reference architecture.
Raw averages don't capture the most important metric for gaming: consistency. BLE's high jitter is its real weakness, not just average latency.
| Connection | Avg Latency | Variance | Poll Rate |
|---|---|---|---|
| Wired USB (GP2040-CE, RP2040) | 0.76 ms | ±0.5 ms | 1000 Hz |
| Proprietary 2.4 GHz (Nordic LLPM) | ~1 ms | ±0.5 ms | 1000 Hz |
| nRF24L01+ custom link | 1–3 ms | ±1 ms | 1000 Hz |
| 8BitDo M30 2.4G (dongle) | 3.6 ms | 1.9–6.0 ms | ~250 Hz |
| DualSense Bluetooth | 3.0 ms | narrow | ~250 Hz |
| Xbox Series via BT | ~15 ms | moderate | ~125 Hz |
| Generic BLE HID gamepad | 8–25 ms | 5.9–38+ ms | 67–133 Hz |
The 8BitDo M30 comparison is telling: its 2.4G dongle mode averages 3.6 ms with 6 ms worst-case, while its Bluetooth mode averages 21 ms with 38 ms worst-case — nearly 10× worse peak latency. For competitive gaming, proprietary 2.4 GHz is the only wireless option that approaches wired feel.
BT Core 6.2 introduces Shorter Connection Intervals down to 0.375 ms, demonstrated on nRF54L15 hardware. But it requires BT 6.2 support on both ends — not yet available in consumer Windows PCs.
Both USB HID and Bluetooth HOGP use the same HID Report Descriptor format — the descriptor bytes are transport-agnostic. You could forward the original descriptor as-is, but in practice you must parse it to understand report sizes/IDs, adapt between USB interrupt-endpoint polling and BLE GATT notifications, and handle output reports (rumble, LEDs) in reverse. Re-implementing a clean, well-known gamepad descriptor is simpler and more reliable.
Xbox controllers use proprietary protocols (XUSB for 360, GIP for One/Series) with dedicated kernel drivers. A generic BLE HID gamepad cannot present as XInput on Windows. It appears as DirectInput, which most modern games support but some XInput-only titles do not.
Workarounds: Steam Input remaps any DirectInput gamepad to XInput within Steam. ViGEmBus (open-source) creates a virtual Xbox 360 controller — the gamepad connects via BLE as DirectInput, ViGEmBus presents virtual XInput to games.
ESP32 WROOM/WROVER modules need a 15 mm keep-out zone around the PCB antenna — no copper on any layer. The antenna must extend beyond the main ground plane. Metal within 20 mm causes -15 dB signal loss. Human hands detune the antenna (skin ε ≈ 50), so tune slightly high (2.50–2.55 GHz). For tight enclosures, a 31 mm quarter-wave wire antenna beats PCB trace antennas.
The TP4056 is a linear CC/CV charger not designed for simultaneous charge and use. Without a load-sharing circuit (P-MOSFET + Schottky diode), the charger micro-cycles and terminates prematurely. Use MCP73871 (built-in power-path) or BQ24075 for proper charge-and-play.
ESP32 draws 100–130 mA active → 7–10 hours on 1000 mAh. nRF52840 draws 5–15 mA → 65–200 hours. Both support deep sleep at ~5–10 µA. For ESP32, use esp_bt_sleep_enable(). For nRF52840, Zephyr handles it automatically.
Buck/boost converters inject EMI into the 2.4 GHz band. Route power traces away from antenna and RF matching network. An LDO like AP2112K-3.3 (600 mA, 55 µA quiescent, SOT-23-5) avoids this entirely and is efficient enough for single-cell LiPo.
No commercial adapter handles arbitrary USB HID, so this is inherently a custom engineering project. The decision reduces to a single axis.
Build with nRF52840 on both controller and a PCA10059 USB dongle. Use nRF Desktop reference design and OpenSplitDeck as firmware starting points. 1000 Hz polling, rock-solid Windows compatibility (standard USB HID to PC), battery life measured in days.
Embed an ESP32 with direct GPIO/ADC wiring (Option A). Accept 8–15 ms BLE latency, test Windows reconnection extensively with ForcePairingMode, use Steam Input or ViGEmBus for XInput translation. Or use Slimbox BT on nRF52840 for a more polished BLE experience with sleep/wake and dual-mode.