It is now possible to use Bluetooth gamepads both in Arduino and CircuitPython projects.
This means that you can use your PlayStation (PS3, PS4, PS5), Nintendo (Wii, Wii U, Switch) and Xbox One S gamepads in your electronics project: control a robot, home-automation, video games, etc… everything controlled from your favorite gamepad.
The catch is that not every Arduino or CircuitPython boards are supported. In fact, only a few of them are supported.
For Arduino, the boards that have the NINA-W10x (ESP32) co-processor are supported, like:
- Arduino Nano RP2040 Connect (great board, get one if you haven’t already)
- Arduino Nano 33 IoT
- Arduino MKR WiFi 1010
- Arduino MKR VIDOR 4000 WiFi
- Arduino Uno WiFi Rev 2
- …and probably a few more. If it has the NINA-W10x co-processor, it is supported.
And similar for CircuitPython, the boards that have the AirLift (ESP32) co-processor are supported, like:
- Adafruit MatrixPortal M4 (great to create a video-game console)
- Adafruit Metro M4 Express AirLift
- Adafruit PyPortal
- Adafruit PyBadge
With the additional benefit that you can use any CircuitPython board by attaching the stand-alone AirLift module:
How does the co-processor work
Before describing how Bluepad32 works, it is better to first describe how WiFi works on NINA and AirLift co-processors (ESP32).
Both Arduino and CircuitPython use the co-processor mostly as WiFi modules. In order to use WiFi, you would use:
These two libraries (WiFiNINA and ESP32SPI) have the same functionality. In fact they are compatible. The only difference is that WiFININA is written in C++ , and ESP32SPI in Python.
The co-processor (ESP32) comes pre-flashed with the Arduino NINA firmware.
The ESP32 (A) connects to the internet using WiFi. And then sends the data back to the main processor (B). It uses a protocol that has some predefined messages like:
- Open HTTP connection and get data
- Enumerate SSID networks
- Connect to SSID network
How does Bluepad32 work
Now that we know how WiFi works, it is easier to explain how Bluepad32 works. Similar to WiFi, Bluepad32 has two main parts:
- Bluepad32 firmware
- Bluepad32 library
The gamepad connects to the ESP32 (A) using Bluetooth. And the ESP32 (A) sends the gamepad data to the main processor (B). It uses the same protocol used by the NINA firmware, but with some extended messages like:
- Get gamepad data
- Set rumble on gamepad
- Set player LEDs on gamepad
Bluepad32 firmware has the following features:
- Has Bluetooth gamepad support
- Runs on the co-processor (ESP32)
- Replaces the Arduino NINA firmware
- Uses the same NINA firmware protocol
- There are two variants of the firmware:
Bluepad32 library has the following features:
- Runs on the main processor
- Fetches that gamepad data from the co-processor
- There are two version of the library:
How to use it in Arduino
Bluepad32 library is part of the official Arduino library registry, so, you can install like any other Arduino library:
Arduino IDE -> Tools -> Manage Libraries -> Search for “bluepad32” and install.
And it comes already with an example that shows how to use it:
Arduino IDE -> File -> Examples -> Bluepad32 -> Gamepad
To flash the Bluepad32 firmware in your Arduino board, please follow these instructions:
How to use it in CircuitPython
$ circup install bluepad32
This example shows how to use Bluepad32 library for CircuitPython:
And to flash the Bluepad32 firmware in your CircuitPython board, please follow these instructions:
NINA vs AirLift vs ESP32
NINA-W10x are ESP32 modules. They are similar in functionality to the ESP32-WROOM-32 modules. Although the NINA modules are built by u-blox, and not by Espressif (do not confuse a ESP32 module with the ESP32 chip).
u-blox, in addition to the NINA-W10x modules, makes other modules that are not ESP32-based. But for the sake of simplicity, in this article, when we mention “NINA”, we talk about the NINA ESP32-based modules.
Makes sense, it is consistent:
AirLift modules, on the other hand, are ESP32-WROOM-32 modules. I guess “AirLift” was created as a marketing name. But what is confusing is that they come pre-flashed with a fork of the Arduino NINA firmware, and the library name is called ESP32SPI.
It is confusing:
- Module name: AirLift
- Firmware name: Adafruit NINA-W10x firmware (fork of Arduino’s).
- Library name: ESP32SPI
(Adafruit, if you are reading, I’d rename them to “AirLift firmware”, and “AirLift library”).
Whether it is a NINA-W10x, an AirLift module or an ESP32-WROOM32, all of them have the ESP32 chip inside. And all of them can run the NINA firmware, or the Bluepad32 firmware, or mostly any other ESP32 firmware that are out there.
So, if all of them are ESP32-based, and if WiFiNINA and ESP32SPI library are compatible, why did Adafruit fork Arduino’s NINA firmware? So far, the only incompatibility that I found, is that the MOSI pin (from SPI) is different.
GPIO 12 is strapping pin, and at boot time it is used internally by the ESP32. It seems that it was causing some interference with some modules.
And just because of that change (different MOSI pins) I needed to create a “Bluepad32 firmware for NINA” and a “Bluepad32 firmware for AirLift”.