FAQ¶
Why can't I connect my DualShock or Switch controller to my ESP32-S3 or ESP32-C3 ?¶
TL;DR
Answer: ESP32-S3 and ESP32-C3 don't support "Bluetooth Classic" protocol.
The only ESP32 chip that supports "Bluetooth Classic" (AKA BR/EDR) is the original ESP32. ESP32-S3, ESP32-C3, ESP32-C6 and ESP32-H2 don't support it.
Controllers like Switch, Wii, DualSense, DualShock, etc. only talk "BR/EDR" (as opposed to BLE). You will need a chip that talks BR/EDR, like the original ESP32 or Pico-W to use DualShock, Switch, etc.
Matrix of supported controllers / chips (might be outdated, see here for up-to-date list)
Chip | BR/EDR | BLE |
---|---|---|
ESP32 | ||
ESP32-S3 | ||
ESP32-C3 | ||
ESP32-C6 | ||
ESP32-H2 | ||
Pico W | ||
Pico 2 W |
Non-comprehensive list of supported Bluetooth gamepads their protocols:
Gamepad | BR/EDR | BLE |
---|---|---|
DualSense (PS5) | ||
DualShock 4 (PS4) | ||
DualShock 3 (PS3) | ||
Nintendo Switch Pro | ||
Nintendo Switch JoyCons | ||
Nintendo Wii U Pro | ||
Nintendo Wii Remote | ||
Nintendo Balance Board | ||
Xbox Wireless | * | * |
Xbox Adaptive | * | |
Steam | ** | |
Stadia | *** | |
Android | **** | **** |
8BitDo | ||
Atari | ||
iCade | ||
Nimbus | ||
OUYA 1st gen |
*: Xbox Controller Firmware v3.x and v4.x use BR/EDR. Firmware v5.x and later use BLE.
**: Requires Steam Controller Bluetooth firmware update
***: Requires Stadia Bluetooth firmware update
****: Some Android controllers use BR/EDR, some use BLE.
What are the supported boards?¶
TL;DR
Answer: Pico W and ESP32-family
The Pico W and ESP32 family of processors. But only the ones that support Bluetooth.
For ESP32, Bluepad32 can run in:
- the main processor, like in the Espressif ESP32-DevKitC
- or in coprocessor modules, like Adafruit AirLift modules, or Arduino NINA-W102 based boards.
If you want to know whether a certain ESP32-based board is supported, it is safe to assume that if the board is supported by regular Arduino, then it is supported by Bluepad32.
How to pair just one controller to one particular board?¶
TL;DR
Answer: Use BT allowlist.
Scenario: You want to control eight robots, each with one controller. Controller A should only control robot A, controller B should only control robot B, and so on.
There are two ways to do it:
- Programmatically using the
uni_bt_allowlist
API - Manually from the USB console
Using uni_bt_allowlist
API¶
One way to do it is by using the uni_bt_allowlist
API.
The most important APIs are:
bool uni_bt_allowlist_add_addr(bd_addr_t addr);
: add BT address to the allowlistvoid uni_bt_allowlist_set_enabled(bool enabled);
: enables the allowlist.
To see the rest of the APIs see: uni_bt_allowlist.h
Complete example:
// Arduino sketch
// Include Uni API.
#include <uni.h>
// The address of the gamepad that is allowed to connect.
// You can add up to four entries.
static const char * controller_addr_string = "00:11:22:33:44:55";
void setup() {
// Somewhere in your "setup" add the following lines:
bd_addr_t controller_addr;
// Parse human-readable Bluetooth address.
sscanf_bd_addr(controller_addr_string, controller_addr);
// Notice that this address will be added in the Non-volatile-storage (NVS).
// If the device reboots, the address will still be stored.
// Adding a duplicate value will do nothing.
// You can add up to four entries in the allowlist.
uni_bt_allowlist_add_addr(controller_addr);
// Finally, enable the allowlist.
// Similar to the "add_addr", its value gets stored in the NVS.
uni_bt_allowlist_set_enabled(true);
}
Using allowlist commands from the USB console¶
Note
The USB console is ONLY avaialble in the Arduino ESP-IDF Template project, in the ESP-IDF raw API, and in Unijoysticle.
To access the USB Console, use your favorite serial terminal a do:
# Port might change
# If you prefer minicom, just do 'minicom -D /dev/ttyUSB0'
tio /dev/ttyUSB0
And once you are in the console type help
bp32> help
The allowlist commands are:
allowlist_list
: List allowlist addressesallowlist_add <bt addr
: Add address to the allowlistallowlist_remove <bt addr
: Remove address from the allowlistallowlist_enable <0 | 1 >
: Whether allowlist should be enforced
See video for further details:
Values are stored in Non-Volatile-Storage (NVS). This means that if you reset the ESP32, the allowlist entries, and whether it is enabled will persist the reset.
How to detect when a gamepad is out of range?¶
TL;DR
Answer: Add a "if don't receive data in 5 seconds, disconnect"
Let's assume that you are controlling a car with the gamepad. If the car goes too far away, it won't receive gamepad data because Bluetooth was not designed a long-range protocol."
BR/EDR | BLE |
---|---|
up to 100 meters | up to 50 meters |
So when the car is outside the range, it won't even receive a "disconnect" event. Eventually, the Bluetooth stack will figure out that the connection was disconnected and will close it But it might take up to 20 seconds or more.
So, in your code you should do something like the following:
// Arduino Sketch
void processControllers() {
for (auto myController : myControllers) {
if (myController && myController->isConnected()) {
if (myController->hasData()) {
// process controller
processGamepad(myController);
lastUpdate = millis();
} else {
// No data received from the controller.
if ((millis() - lastUpdate) > 5000) {
// If no data received in more than 5000 milliseconds, do something.
stopCar();
myController->disconnect();
}
}
}
}
}
void loop() {
bool dataUpdated = BP32.update();
if (dataUpdated) {
processControllers();
}
vTaskDelay(1);
}
Check GitHub Issue #42 for more details.
Could you add support for my unsupported controller?¶
TL;DR
Answer: We'll do our best.
First of all, double-check that the controller is not already supported:
If it is not there, and you want us to support it, contact us (Send us a Private Message in Discord , or file a feature request ).
The way it works is:
- You send us a link to the controller that is not supported, like the Amazon or AliExpress link.
- You send us via PayPal , Ko-fi , Venmo , or even an Amazon gift card, the cost of the gamepad + shipping to the US.
- We purchase it, and we will do our best to support it. But we don't guarantee anything. So many things can go wrong, especially with low-cost clones where many features are not implemented.
Why does the internal Bluepad32 API use uni
as prefix?¶
TL;DR
Answer: Legacy
The Unijoysticle2 project included both the hardware and the firmware. In November 2020 I decided to port the Unijoysticle firmware to Adafruit AirLift module.
During the port and I had the decouple the firmware from the Unijoysticle2 hardware: I had re-design the architecture,
but to avoid too many changes I decided to keep using the old uni
prefix.
The Bluepad32 Arduino API does NOT use the uni
prefix since I created it from scratch, without the need to maintain
backward compatibility.
Why is BTstack being used as the Bluetooth stack?¶
TL;DR
Answer: There were no alternatives back in 2019
When I started Bluepad32 back in January 2019, there was no Bluetooth Classic (BR/EDR) implementation available for ESP32.
I had two options:
- use Bluekitchen BTstack
- or implement my own
I decided to use BTstack. It turned out to be a good decision:
- Pico W uses BTstack, so porting Bluepad32 to Pico W was fairly straight-forward.
- It supports Posix systems: Beneficial when adding support for a new controller.
Which IDE should I use?¶
TL;DR
Answer: The one that makes you more productive.
Use the one that makes you more productive. Sometimes it is the one that you are more familiar with.
Some options are:
- Arduino IDE: good if you are already familiar with Arduino ecosystem.
- Visual Studio Code: good as a generic code editor. Requires to install different plugins to have a good C / C++ experience.
- CLion: good for advanced C / C++ users.
For me, the best one by far is CLion. But your mileage may vary.
When was Bluepad32 created?¶
TL;DR
Answer: 2019, although the original project started in 2016, and it was renamed to Bluepad32 in 2020.
- Started Unijoysticle project (WiFi gamepad for Commodore 64): 2016-03-28
- Decided to support Bluetooth in late 2018, the first commit was: 2019-01-02
- Created Unijoysticle2 repo: 2019-02-06 (copied files from Unijoysticle repo)
- First public release of the firmware v0.1.0: 2019-04-27
- Renamed firmware to Bluepad32: November 2020 (hardware was still called Unijoysticle2)
timeline
2016-03-28: First Unijoysticle commit, ESP8266 + WiFi only
2019-01-02: Initial Unijoysticle ESP32 port, with Bluetooth support
2019-02-06: Created Unijoysticle2 repo
2019-04-27: Released v0.1.0, first public release
2020-11-20: Released v2.0.0-beta0: Renamed to Bluepad32