https://github.com/finger563/esp-usb-ble-hid
USB BLE HID adapter using ESP32S3 to have a BLE central which supports receiving HID input from a remote device and outputting over USB.
https://github.com/finger563/esp-usb-ble-hid
ble ble-hid esp32 nintendo-hacking nintendo-switch switch-pro-controller usb usb-hid xbox xbox-controller
Last synced: 7 days ago
JSON representation
USB BLE HID adapter using ESP32S3 to have a BLE central which supports receiving HID input from a remote device and outputting over USB.
- Host: GitHub
- URL: https://github.com/finger563/esp-usb-ble-hid
- Owner: finger563
- License: mit
- Created: 2025-02-07T17:01:32.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-10-31T14:46:58.000Z (8 months ago)
- Last Synced: 2026-06-02T18:03:59.339Z (18 days ago)
- Topics: ble, ble-hid, esp32, nintendo-hacking, nintendo-switch, switch-pro-controller, usb, usb-hid, xbox, xbox-controller
- Language: C
- Homepage:
- Size: 168 KB
- Stars: 19
- Watchers: 1
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ESP USB BLE HID
Example code for using BLE gamepad (such as Xbox wireless controller) with the
Nintendo Switch via a USB dongle.
This repository contains example code for using an ESP32s3 to act as a USB-BLE
HID bridge. You would run this code for instance on a QtPy ESP32s3 or a LilyGo
T-Dongle S3, connected to a computer or other device which is a USB HID host.
The main HID host that this targets is the Nintendo Switch. The QtPy / this code
would then start a BLE GATT Client to connect to a BLE HID device (this example
targets a gamepad), and will allow the wireless HID device (gamepad) to talk to
the HID Host.

**Table of Contents**
- [ESP USB BLE HID](#esp-usb-ble-hid)
- [Plug and Play](#plug-and-play)
- [Purchase Dongle](#purchase-dongle)
- [Program It](#program-it)
- [Plug it into your Switch](#plug-it-into-your-switch)
- [Cloning](#cloning)
- [Configuration](#configuration)
- [Build and Flash](#build-and-flash)
- [How To Use](#how-to-use)
- [Pairing Mode](#pairing-mode)
- [Reconnection Mode](#reconnection-mode)
- [Connected](#connected)
- [Note about system power](#note-about-system-power)
- [Output](#output)
- [Helpful Links](#helpful-links)
## Plug and Play
If you just want to get a dongle and use your BLE controller with the switch,
simply get the dongle, plug it into your computer, and run the programmer
executable from the release.
### Purchase Dongle
Sources:
- [LilyGo](https://lilygo.cc/products/t-dongle-s3?srsltid=AfmBOopsToYDfOeA4GJiUlQNNcefgA_lMLmWoF99lzdWc_j5Ysd9FUeW)
- [Amazon](https://www.amazon.com/LILYGO-T-Dongle-S3-ESP32-S3-Development-Display/dp/B0BK9162QY)
### Program It
The dongle will require one-time programming to function as a BLE HID USB
dongle.
Download the release `programmer` executable from the latest [releases
page](https://github.com/finger563/esp-usb-ble-hid/releases) for `windows`,
`macos`, or `linux` - depending on which computer you want to use to perform the
one-time programming.
1. Download the programmer
2. Unzip it
3. Double click the `exe` (if windows), or open a terminal and execute it from
the command line `./esp-usb-ble-hid_programmer_v2.0.2_macos.bin`.
### Plug it into your Switch
Now that the dongle is programmed, simply plug it into your Switch and turn your
switch on.
See the [How To Use](#how-to-use) section for information about how to pair /
reconnect your controller to the dongle.
https://github.com/user-attachments/assets/a0789d38-bd0e-4215-bf2c-ebedd9958495
https://github.com/user-attachments/assets/c81b947a-24a1-4a44-b5d0-5d4c274beb93
## Cloning
Since this repo contains a submodule, you need to make sure you clone it
recursively, e.g. with:
``` sh
git clone --recurse-submodules https://github.com/finger563/esp-usb-ble-hid
```
Alternatively, you can always ensure the submodules are up to date after cloning
(or if you forgot to clone recursively) by running:
``` sh
git submodule update --init --recursive
```
## Configuration
You can run `idf.py menuconfig` to configure the project to run on either the
`T-Dongle-S3` or the `QtPy (ESP32 or ESP32S3)`. The configuration is under the
`Hardware Configuration` menu from the main menu and is the `Target Hardware`
option.

## Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## How To Use
> NOTE: you must turn on the `support wired controllers` setting on your switch
> for the dongle (or any wired controllers for that matter) to work.
The dongle can store up to 5 paired devices at a time. When it turns on / is
plugged in it will attempt to reconnect to one of those devices. If there are no
paired devices, then it will enter pairing mode.
If at any time you want to pair a new controller, simply press and hold the
button on the dongle until the LED starts pulsing blue.
### Pairing Mode
While in pairing mode, the device will scan for any BLE devices which expose a
HID service. It will connect and attempt to bond to the first device it finds.
### Reconnection Mode
When in this mode, the device will scan for the devices in its pairing list and
connect to the first one it finds.
### Connected
While connected, the device will translate xbox controller inputs received via
BLE into Nintendo Switch Pro controller inputs which will then be transmitted
over USB.
If the controller disconnects, then the dongle will re-enter reconnection mode.
### Note about system power
The switch turns off its USB-C port when it enters sleep mode. This means that
while the Switch Dock's USB-A port still has power, the dongle will not properly
mount as a usb device until the Switch comes out of sleep.
For this reason, you cannot use this dongle or the associated BLE controller to
power on your switch unfortunately. The only way (currently) to remotely wake
your switch is via Bluetooth Classic.
That being said, I have read online that if you plug a usb-to-ethernet adapter
into your Switch Dock, then the Switch may keep its USB-C port awake during
sleep.
## Output
https://github.com/user-attachments/assets/a0789d38-bd0e-4215-bf2c-ebedd9958495



## Helpful Links
The links below were invaluable in developing the switch pro implemenation
within this repo such that it would work on MacOS, Android, iOS, and (most
importantly) the Nintendo Switch.
* https://github.com/Brikwerk/nxbt/blob/master/nxbt/controller/protocol.py
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/bluetooth_hid_subcommands_notes.md
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/USB-HID-Notes.md
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/spi_flash_notes.md
* https://github.com/EasyConNS/BlueCon-esp32/tree/master/components/joycon
* https://github.com/mzyy94/nscon/blob/master/nscon.go
* https://www.mzyy94.com/blog/2020/03/20/nintendo-switch-pro-controller-usb-gadget/