Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
MIDI over BLE

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.

BLE Backends

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

ArduinoBLEBackend

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.

ESP32BluedroidBackend

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.

ESP32NimBLEBackend

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.

BTstackBackgroundBackend

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