Control Surface has different MIDI over BLE backends for different Arduino-compatible boards.
To use MIDI over Bluetooth Low Energy in your code, you usually don't have to worry about these backends, and you can simply instantiate a BluetoothMIDI_Interface. For an example, see BLEMIDI-Adapter.ino.
A MIDI over BLE backend handles the low-level BLE communication, from setting up the BLE stack and configuring the GATT characteristics to sending and receiving MIDI messages over BLE. The backend is used by the GenericBLEMIDI_Interface class which provides the actual high-level MIDI_Interface API. The BluetoothMIDI_Interface class uses the default backend for the particular board.
Board | Default backend | Other supported backends |
---|---|---|
Arduino Nano 33 IoT | ArduinoBLEBackend | |
Arduino Nano RP2040 | ArduinoBLEBackend | |
Arduino Nano ESP32 | ESP32BluedroidBackend | ESP32NimBLEBackend |
Arduino Nano 33 BLE | ArduinoBLEBackend | |
Arduino MKR 1010 WiFi | ArduinoBLEBackend | |
Arduino UNO R4 WiFi | ArduinoBLEBackend | |
Arduino GIGA R1 WiFi | ArduinoBLEBackend | |
Raspberry Pi Pico W (RP2040) | BTstackBackgroundBackend | |
ESP32 | ESP32BluedroidBackend | ESP32NimBLEBackend |
ESP32-S3 | ESP32BluedroidBackend | ESP32NimBLEBackend |
ESP32-C3, ESP32-C6, ESP32-H2 | ESP32BluedroidBackend | ESP32NimBLEBackend |
Uses the ArduinoBLE library, and should support any boards supported by that library.
This is a polling backend: you should call GenericBLEMIDI_Interface::update regularly to ensure proper operation.
Because of limitations in the ArduinoBLE library, sending large packets is not possible. The default MTU is set to 23, with no way to negotiate a larger MTU, or even query the current MTU. This leaves only 20 bytes of MIDI data per packet, so the throughput is quite poor.
This is the default backend for ESP32 boards. It uses the ESP-IDF Bluedroid stack.
The Bluetooth stack runs in its own task, and events are delivered asynchronously. The sending of messages also happens asynchronously. Calling GenericBLEMIDI_Interface::update is therefore less critical compared to the ArduinoBLEBackend, but should still be done regularly to avoid the receiving buffer from filling up, since there is no BLE flow control.
This backend uses the newer Apache MyNewt NimBLE stack.
Like the ESP32BluedroidBackend, the NimBLE backend uses its own threads and does not require polling.
The NimBLE ESP-IDF component is disabled by default in the arduino-esp32 core, so you'll need to install the h2zero/NimBLE-Arduino library in order to use this backend.
Defining CS_USE_NIMBLE before including Control Surface changes the default backend for ESP32 to the ESP32NimBLEBackend.
This backend uses the BTstack stack that ships with the pico-sdk.
All Bluetooth events are handled asynchronously (using the background async_context
). Currently, buffering outgoing MIDI messages still requires polling, although this could be replaced by a BTstack timer in the future.
To use the BluetoothMIDI_Interface on the Pico W, you have to enable the Bluetooth stack in the Tools > IP/Bluetooth Stack menu in the IDE: https://arduino-pico.readthedocs.io/en/latest/bluetooth.html#enabling-bluetooth