Skip to content

Repository files navigation

Bluetooth LE ➡️ USB HID Bridge (ESP32-S3)

ESP-IDF firmware for an ESP32-S3 that turns BLE controller input into USB HID keyboard/media output, managed through a built-in web UI.

Put simply, this project allows you to use a Bluetooth controller (like a gamepad or remote) as a keyboard or media controller for hardware that only supports USB input.

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#262626',
    'primaryTextColor': '#dbdbdb',
    'primaryBorderColor': '#00ff99',
    'lineColor': '#8d81ff',
    'secondaryColor': '#1f1f1f',
    'tertiaryColor': '#333'
  }
}}%%
flowchart LR
    C[🎮 Bluetooth LE Controller<br/>Gamepad / Remote]
    E[ESP32-S3<br/>BLE ➜ USB HID Bridge]
    R[💻 Receiver System<br/>PC / Console / Media Center]

    C -- Bluetooth LE --> E
    E -- USB HID Keyboard / Media Keys --> R
Loading

Flashing the firmware

Assuming ESP-IDF is installed and the ESP32-S3 is connected to your computer, simply run the following from the root of the repo:

source "~/.espressif/tools/activate_idf_v6.0.2.sh"
idf.py set-target esp32s3 && idf.py build && idf.py flash

Usage

  1. Power on the device and connect to its broadcasted access point (SSID: ControllerMapper-XXXX, password: mapper1234).
  2. Open the web UI hosted at http://192.168.4.1
  3. Press Start Scan to find BLE devices and Pair on your desired one.
    • These Paired devices are persisted across reboots and automatically reconnected to at startup.
  4. Press Edit Keys for your paired device and press some keys on your controller.
    • The keymap is autopopulated as new buttons are discovered.
  5. Remap your desired keys to USB keyboard/media combos (ex. Controller A Button -> CTRL+ALT+X over USB).
    • Pressing Save to Flash will persist your keymap to NVS so it is remembered across reboots.

Example Use Case

  • Controlling game consoles or media center PCs that lack Bluetooth LE support, with a cheap universal remote like the Sofabaton U1 or U2.

Testing and Debugging

The web UI and API are always available during runtime and allows for test firing key combinations, viewing the serial log, and viewing other useful status/runtime information.

API Endpoints

  • /api/status - Returns current status of the app, including connected devices and last key pressed.
  • /api/logs - Returns the last 180 lines of the log ring buffer.
  • /api/ble/* - Endpoints for scanning, pairing, connecting, and disconnecting BLE devices.
  • /api/keymap/* - Endpoints for viewing, adding, removing, and saving key mappings.
  • /api/hid/test - Endpoint for test firing a key combination over USB.
  • /api/last_button - Returns the last button pressed on the connected BLE device.

Repo Architecture

  • main/ble-to-hid-controller-mapper.c: startup orchestration
  • main/wifi_ap.c: SoftAP initialization and AP event logs
  • main/web_ui.c: embedded single-page HTML/JS UI + REST-like JSON endpoints
  • main/ble_scanner.c: NimBLE host lifecycle, scanning, pairing, connection, input decoding, reconnect loop
  • main/hid_bridge.c: combo parser + TinyUSB HID send pipeline
  • main/app_state.c: mutex-protected in-memory app state
  • main/keymap_store.c: keymap NVS load/save/clear
  • main/paired_store.c: paired-address NVS load/save
  • main/log_sink.c: in-memory log ring buffer for /api/logs
  • main/include/*.h: module interfaces

Future Plans / Bugs

  • Allow for connecting to a home Wi-Fi network for easier management (currently only SoftAP mode is supported).
  • Some simpler remotes may not properly "zero out" their key state on release, causing an inability to detect repeated key presses.
  • Fix double keypresses

About

ESP-IDF firmware for an ESP32-S3 that turns BLE controller input into USB HID keyboard/media output, managed through a built-in web UI.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages