Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIDI over BLE support for ESP32, ArduinoBLE and Raspberry Pi Pico W #993

Merged
merged 42 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ba202f6
[Docs] fix Hairless link
tttapa Jan 18, 2024
103d6ab
ESP32 NimBLE support (WIP)
tttapa Jan 18, 2024
f56bc78
Use std::nothrow new for MIDI SysEx queue element
tttapa Jan 18, 2024
266388f
Improve ESP32 NimBLE support (WIP)
tttapa Jan 18, 2024
b2e7c8d
Refactor ESP32 NimBLE backend
tttapa Jan 19, 2024
610c4fe
Add BLERingBuf
tttapa Jan 20, 2024
215cd83
Add set_advertise_connection_interval, log connection info
tttapa Jan 20, 2024
f0d9c16
ArduinoBLE support
tttapa Jan 20, 2024
4b9c2d2
Make ESP32-NimBLE backend header-only
tttapa Jan 20, 2024
33953ee
Make ESP32-NimBLE backend inline
tttapa Jan 20, 2024
733b8c2
NimBLE disable encryption
tttapa Jan 20, 2024
b313467
Update Bluedroid BLE MIDI backend
tttapa Jan 20, 2024
052a3d2
Add BluetoothMIDI_Interface with sensible defaults
tttapa Jan 20, 2024
c71bc79
ArduinoBLE backend add maybe_unused
tttapa Jan 20, 2024
d653670
AHEncoder support on Arduino Giga
tttapa Jan 20, 2024
09f0911
ArduinoBLE GIGA and MKR 1010 WiFi support
tttapa Jan 20, 2024
052b9c4
[Docs] update MIDI-over-USB table with BLE support
tttapa Jan 20, 2024
2004838
Improve FreeRTOSBLEMIDISender
tttapa Jan 21, 2024
cb0fc10
Make BLERingBuf thread-safe
tttapa Jan 21, 2024
c4039a2
Extract BufferedBLEParser, remove ThreadSafeMIDIBLEParser
tttapa Jan 21, 2024
4ae1e78
Update BluetoothMIDI_Interface tests
tttapa Jan 21, 2024
944a804
BLE MIDI naming consistency
tttapa Jan 21, 2024
43a2296
Fix ESP32 NimBLE backend
tttapa Jan 21, 2024
7922b1f
Improve BLEMIDI docstrings
tttapa Jan 21, 2024
9109f75
[Docs] add MIDI-over-BLE page
tttapa Jan 21, 2024
c96cfd9
[Docs] improve BLE and USB MIDI interface docstrings
tttapa Jan 21, 2024
3ae5194
BLE and USB adapter examples
tttapa Jan 21, 2024
880b663
[CI] enable ESP32-S3
tttapa Jan 21, 2024
45d8351
Restore AHEncoder Due support
tttapa Jan 21, 2024
fb60e5d
[Docs] Update README and MIDI tutorial
tttapa Jan 21, 2024
5fe9637
[CI] install ArduinoBLE library
tttapa Jan 21, 2024
d25a63c
Include BluetoothMIDI_Interface.hpp in BLEMIDI-Adapter.ino
tttapa Jan 21, 2024
0f242db
[Docs] update MIDI-over-BLE page
tttapa Jan 21, 2024
5ce4664
Pico W BLE support (WIP)
tttapa Jan 22, 2024
79b8e22
Improve Pico W BLE (WIP)
tttapa Jan 22, 2024
bc06134
Further improve Pico W BLE backend
tttapa Jan 22, 2024
34531b5
Finish Pico W BLE backend
tttapa Jan 23, 2024
463c0f0
Limit maximum BLE MTU to 512+3 bytes
tttapa Jan 23, 2024
084d838
[CI] Test Pi Pico W
tttapa Jan 23, 2024
4309ae7
Pi Pico W MIDI over BLE support
tttapa Jan 23, 2024
9ec4373
Document Pi Pico W BLE support
tttapa Jan 23, 2024
9612cae
Update Pi Pico W MIDI-over-BLE GATT file
tttapa Jan 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/examples.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
board: [AVR, Nano 33 BLE, Pi Pico, Nano 33 IoT, UNO R4, ESP32, ESP8266, AVR USB, Mega, Leonardo, Due, Nano Every, Teensy 3.x, Teensy 4.1]
board: [AVR, Nano 33 BLE, Pi Pico, Pi Pico W, Nano 33 IoT, UNO R4, ESP32, ESP32-S3, ESP8266, AVR USB, Mega, Leonardo, Due, Nano Every, Teensy 3.x, Teensy 4.1]

steps:
- name: Checkout
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:

- name: Install Arduino Boards
run: |
arduino-cli core install arduino:avr arduino:mbed_nano arduino:mbed_rp2040 arduino:samd esp32:esp32 esp8266:esp8266 arduino:sam arduino:megaavr arduino:renesas_uno teensy:avr
arduino-cli core install arduino:avr arduino:mbed_nano arduino:mbed_rp2040 arduino:samd esp32:esp32 esp8266:esp8266 arduino:sam arduino:megaavr arduino:renesas_uno teensy:avr rp2040:rp2040
arduino-cli core upgrade
arduino-cli cache clean
version=$(arduino-cli core list | grep 'teensy:avr' | awk '{print $2}') && { sed -i 's/^recipe.hooks.postbuild/# recipe.hooks.postbuild/g' $HOME/.arduino15/packages/teensy/hardware/avr/$version/platform.txt ||:; }
Expand All @@ -70,6 +70,7 @@ jobs:
[ -d FastLED ] || git clone https://github.com/FastLED/FastLED.git --depth=1 &
[ -d MIDIUSB ] || git clone https://github.com/arduino-libraries/MIDIUSB.git --depth=1 &
[ -d Audio ] || git clone https://github.com/PaulStoffregen/Audio.git --depth=1 &
[ -d ArduinoBLE ] || git clone https://github.com/arduino-libraries/ArduinoBLE.git --depth=1 &
[ -d Arduino-AppleMIDI-Library ] || git clone https://github.com/lathoub/Arduino-AppleMIDI-Library.git --depth=1 --branch v3.2.0 &
[ -d arduino_midi_library ] || git clone https://github.com/FortySevenEffects/arduino_midi_library.git --depth=1 &
ln -snf "$GITHUB_WORKSPACE" "$HOME/Arduino/libraries/"
Expand Down
282 changes: 149 additions & 133 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,124 +8,40 @@

Control Surface is an Arduino library for building MIDI controllers and control
surfaces.
At its core is a
[general-purpose MIDI abstraction layer](https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/df7/midi-tutorial.html)
with support for serial MIDI, MIDI over USB, MIDI over BLE, etc., which can be
useful for any MIDI-related project.
Besides MIDI input/output, Control Surface also includes easy-to-use utilities
specifically for building MIDI controllers, supporting controls that send MIDI

At its core, the library features a flexible [**MIDI abstraction layer**](https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/df7/midi-tutorial.html)
with support for serial **5-pin DIN** MIDI, MIDI over **USB**, MIDI over **BLE**, etc.
These MIDI interfaces are compatible with a wide range of Arduino boards
(a full table can be found [here](https://tttapa.github.io/Control-Surface-doc/Doxygen/d8/d4a/md_pages_MIDI-over-USB.html))
and are useful in any Arduino MIDI project.

In addition to MIDI input/output, Control Surface also provides easy-to-use utilities
intended for building MIDI controllers, supporting controls that send MIDI messages
─ like potentiometers, push buttons, rotary encoders, etc. ─
and controls that react to incoming MIDI ─ LEDs, displays, and so on.
They can also be combined into controls that use both MIDI input and output,
such as motorized faders.
and controls that react to incoming MIDI messages ─ LEDs, displays, and so on.
More advanced controls that combine MIDI input and output ─
such as [motorized faders](https://github.com/tttapa/Control-Surface-Motor-Fader)
─ are supported as well.

In projects with large numbers of inputs and outputs, Control Surface allows you
to seamlessly add multiplexers, shift registers and other port expanders, and
treat them as if they were ordinary GPIO pins.

> Table of contents
> <span class="mono">¶</span>&emsp;[Overview](#overview)
> <span class="mono">¶</span>&emsp;[Example usage](#example-usage)
> <span class="mono">¶</span>&emsp;[Getting started](#getting-started)
> <span class="mono">¶</span>&emsp;[Documentation](#documentation)
> <span class="mono">¶</span>&emsp;[Feature overview](#feature-overview)
> <span class="mono">¶</span>&emsp;[Supported boards](#supported-boards)
> <span class="mono">¶</span>&emsp;[Information for developers](#information-for-developers)
> <span class="mono">¶</span>&emsp;[Change log and updating](#change-log-and-updating)

<a name="overview"></a>

## Overview

This library turns your Arduino-compatible board into a MIDI control surface.
Just connect some push buttons, potentiometers, LEDs ... and declare them in
your code.

The following sections give a brief overview of the features of the library.

### MIDI Interfaces

- **MIDI over USB**
- **Serial MIDI** (e.g. 5-pin DIN MIDI)
- **Debug MIDI** (prints out the messages in a readable format, and allows you
to input text based messages, like a MIDI monitor)
- **MIDI over Bluetooth LE**
- **AppleMIDI** over WiFi or Ethernet

<sub>→ [_MIDI Interfaces documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/dc/df0/group__MIDIInterfaces.html)</sub>

### MIDI Control Output

- **Push buttons** and **toggle switches**
- **Potentiometers**, **faders** and other analog sensors
- **Rotary encoders**
- **Scanning keyboard matrices**

Digital inputs are **debounced**, and analog inputs are filtered using
**digital filters and hysteresis**. This results in high accuracy without noise,
without introducing latency.

These MIDI control outputs can be used to send MIDI notes, Control Change,
Pitch Bend, Program/Patch change, etc.

<sub>→ [_MIDI Output Elements documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/d7/dcd/group__MIDIOutputElements.html)</sub>

### MIDI Control Input

- **LEDs** (e.g. to indicate whether a track is muted/armed/soloed)
- **LED rings** (e.g. to indicate the position of a pan knob)
- **LED strips** (using the [FastLED](https://github.com/FastLED/FastLED)
library)
- **VU meters**
- **OLED displays**
- **7-segment displays**

A large portion of the **Mackie Control Universal** (MCU) protocol is
implemented.

<sub>→ [_MIDI Input Elements documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/df/d8b/group__MIDIInputElements.html)</sub>

### Motorized faders

- **Motorized faders** are supported through the [tttapa/Control-Surface-Motor-Fader](https://github.com/tttapa/Control-Surface-Motor-Fader) repository.

<sub>→ [_Control Surface Motor Fader documentation_](https://tttapa.github.io/Pages/Arduino/Control-Theory/Motor-Fader/)</sub>

### Bank support

All controls can be arranged in **banks**: for example, if you have only 4
physical faders, you can make them bankable, so they can be used to control
the volume of many more different tracks. Changing banks can be done using push
buttons, rotary encoders, etc.
Apart from banks and bank selectors, you can also add **transposers** to change
the key of your notes, for example.

### Extended input/output

In order to save some IO pins, the library natively supports **multiplexers**
(e.g. 74HC4051 or 74HC4067) to read many switches or potentiometers,
**Shift Registers** (e.g. 74HC595) to drive many LEDs, **MAX7219 LED drivers**,
etc.

<sub>→ [_Extended IO documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/db/dd3/group__AH__ExtIO.html)</sub>

### Audio

If you are using a Teensy 3.x or 4.x, you can use it as a
**USB audio interface**. Just add an I²S DAC (e.g. PCM5102) and 5 lines of code,
and you can start playing audio through your Teensy, by combining Control
Surface with the Teensy Audio library.
You can also add volume controls and VU meters for these audio connections.

<sub>→ [_Teensy Audio documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/d5c/group__Audio.html)</sub>

### Modular and extensible

Thanks to the structure of the library, you can easily add your own MIDI or
display elements, using some minimal, high level code. All low level stuff is
completely **reusable** (e.g. all MIDI operations, debouncing switches,
filtering analog inputs, and so on).

<a name="example-usage"></a>

## Example usage

A complete sketch for a MIDI controller with a potentiometer that sends out MIDI
An extensive list of examples can be found [in the documentation](https://tttapa.github.io/Control-Surface-doc/Doxygen/examples.html).
Below are a handful of simple examples that give an idea of how the Control
Surface library can be used.

**Example 1**: A complete sketch for a MIDI controller with a potentiometer that sends out MIDI
Control Change message can be written in just five lines of code:

```cpp
Expand All @@ -138,10 +54,11 @@ void setup() { Control_Surface.begin(); }
void loop() { Control_Surface.loop(); }
```

Larger MIDI controllers can implemented very easily as well, with clean and easy
to modify code.
**Example 2**: Larger MIDI controllers can be implemented very easily as well, with clean and
easy to modify code.
The following sketch is for 8 potentiometers (connected using an analog
multiplexer) that send out MIDI Control Change messages over USB.
multiplexer) that send out MIDI Control Change messages over USB. A detailed
walkthrough of this example can be found on the [Getting Started](https://tttapa.github.io/Control-Surface-doc/Doxygen/d5/d7d/md_pages_Getting-Started.html) page.

```cpp
#include <Control_Surface.h> // Include the library
Expand Down Expand Up @@ -176,7 +93,7 @@ void loop() {
}
```

Control Surface supports many types of MIDI inputs.
**Example 3**: Control Surface also supports many types of MIDI inputs.
For example, an LED that turns on when a MIDI Note On message for middle C is
received:
```cpp
Expand All @@ -189,7 +106,30 @@ void setup() { Control_Surface.begin(); }
void loop() { Control_Surface.loop(); }
```

<a name="getting-started"></a>
**Example 4**: Control Surface's MIDI interfaces can also be used directly, for example, to
implement a MIDI-over-USB to MIDI-over-BLE adapter:
```cpp
#include <Control_Surface.h>

// Instantiate MIDI over BLE and MIDI over USB interfaces
BluetoothMIDI_Interface midi_ble;
USBMIDI_Interface midi_usb;
// Pipes allow routing between MIDI interfaces
BidirectionalMIDI_Pipe pipes;

void setup() {
// Route the MIDI input from the USB interface to the BLE interface,
// and the MIDI input from the BLE interface to the USB interface
midi_usb | pipes | midi_ble;
// Initialize the MIDI interfaces
MIDI_Interface::beginAll();
}

void loop() {
// Continuously poll all interfaces and route the traffic between them
MIDI_Interface::updateAll();
}
```

## Getting started

Expand All @@ -201,8 +141,6 @@ The [**MIDI tutorial**](https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/
might be useful if you want to use Control Surface as a regular MIDI library,
for sending and receiving MIDI messages.

<a name="documentation"></a>

## Documentation

The automatically generated Doxygen documentation for this library can be found
Expand All @@ -221,7 +159,96 @@ You can find an answer to some frequently asked questions on the
[**FAQ**](https://tttapa.github.io/Control-Surface-doc/Doxygen/da/dc1/FAQ.html)
page.

<a name="supported-boards"></a>
## Feature overview

This library turns your Arduino-compatible board into a MIDI control surface.
Just connect some push buttons, potentiometers, LEDs ... and declare them in
your code.

The following sections give a brief overview of the features of the library.

### MIDI Interfaces

- **MIDI over USB**
- **Serial MIDI** (e.g. 5-pin DIN MIDI)
- **Debug MIDI** (prints out the messages in a readable format, and allows you
to input text based messages, like a MIDI monitor)
- **MIDI over Bluetooth LE**
- **AppleMIDI** over WiFi or Ethernet

<sub>→ [_MIDI Interfaces documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/dc/df0/group__MIDIInterfaces.html)</sub>

### MIDI Control Output

- **Push buttons** and **toggle switches**
- **Potentiometers**, **faders** and other analog sensors
- **Rotary encoders**
- **Scanning keyboard matrices**

Digital inputs are **debounced**, and analog inputs are filtered using
**digital filters and hysteresis**. This results in high accuracy without noise,
without introducing latency.

These MIDI control outputs can be used to send MIDI notes, Control Change,
Pitch Bend, Program/Patch change, etc.

<sub>→ [_MIDI Output Elements documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/d7/dcd/group__MIDIOutputElements.html)</sub>

### MIDI Control Input

- **LEDs** (e.g. to indicate whether a track is muted/armed/soloed)
- **LED rings** (e.g. to indicate the position of a pan knob)
- **LED strips** (using the [FastLED](https://github.com/FastLED/FastLED)
library)
- **VU meters**
- **OLED displays**
- **7-segment displays**

A large portion of the **Mackie Control Universal** (MCU) protocol is
implemented.

<sub>→ [_MIDI Input Elements documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/df/d8b/group__MIDIInputElements.html)</sub>

### Motorized faders

- **Motorized faders** are supported through the [tttapa/Control-Surface-Motor-Fader](https://github.com/tttapa/Control-Surface-Motor-Fader) repository.

<sub>→ [_Control Surface Motor Fader documentation_](https://tttapa.github.io/Pages/Arduino/Control-Theory/Motor-Fader/)</sub>

### Bank support

All controls can be arranged in **banks**: for example, if you have only 4
physical faders, you can make them bankable, so they can be used to control
the volume of many more different tracks. Changing banks can be done using push
buttons, rotary encoders, etc.
Apart from banks and bank selectors, you can also add **transposers** to change
the key of your notes, for example.

### Extended input/output

In order to save some IO pins, the library natively supports **multiplexers**
(e.g. 74HC4051 or 74HC4067) to read many switches or potentiometers,
**Shift Registers** (e.g. 74HC595) to drive many LEDs, **MAX7219 LED drivers**,
etc.

<sub>→ [_Extended IO documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/db/dd3/group__AH__ExtIO.html)</sub>

### Audio

If you are using a Teensy 3.x or 4.x, you can use it as a
**USB audio interface**. Just add an I²S DAC (e.g. PCM5102) and 5 lines of code,
and you can start playing audio through your Teensy, by combining Control
Surface with the Teensy Audio library.
You can also add volume controls and VU meters for these audio connections.

<sub>→ [_Teensy Audio documentation_](https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/d5c/group__Audio.html)</sub>

### Modular and extensible

Thanks to the structure of the library, you can easily add your own MIDI or
display elements, using some minimal, high level code. All low level stuff is
completely **reusable** (e.g. all MIDI operations, debouncing switches,
filtering analog inputs, and so on).

## Supported boards

Expand All @@ -239,8 +266,10 @@ following boards:
- Arduino Nano 33 BLE
- Arduino Nano Every
- Arduino UNO R4 Minima
- Arduino UNO R4 WiFi
- ESP8266
- ESP32
- ESP32-S3
- Raspberry Pi Pico

This covers a very large part of the Arduino platform, and similar boards will
Expand All @@ -251,29 +280,16 @@ If you have a board that's not supported, please
[open an issue](https://github.com/tttapa/Control-Surface/issues/new)
and let me know!

Note that MIDI over USB and MIDI over Bluetooth are not supported on all boards.
For MIDI over USB support, check out the [**MIDI over USB**](https://tttapa.github.io/Control-Surface-doc/Doxygen/d8/d4a/md_pages_MIDI-over-USB.html)
documentation page. As a general rule of thumb, if your board is supported by
the [MIDIUSB library](https://github.com/arduino-libraries/MIDIUSB) or if it's
a Teensy, MIDI over USB should be supported.
MIDI over BLE is currently only supported on ESP32.

<a name="information-for-developers"></a>

## Information for developers

Information for people that would like to help improve the Control Surface
library can be found here:
<https://tttapa.github.io/Pages/Arduino/Control-Surface/Developers/index.html>
It covers installation instructions for developers, instructions for running the
tests and generating documentation, a style guide, etc.

<a name="change-log-and-updating"></a>
Note that MIDI over USB and MIDI over Bluetooth are not supported on all boards.
See the [**MIDI over USB**](https://tttapa.github.io/Control-Surface-doc/Doxygen/d8/d4a/md_pages_MIDI-over-USB.html)
documentation page for a table with supported features per board.

## Change log and updating

### 2.x

- ([fae1933](https://github.com/tttapa/Control-Surface/commit/3ae51946d57e27f0e37d001bb8e0ce418fae1933))
Completely refactored `BluetoothMIDI_Interface`, with support for the NimBLE and ArduinoBLE backends.
- ([ba7f42e](https://github.com/tttapa/Control-Surface/commit/9c4cdd452990c470ee429b3121bdeb178ba7f42e))
More upper case constants and enumerators have been deprecated. For example,
`ControlChange` should be used instead of `CONTROL_CHANGE`. If you continue
Expand Down
Loading