Control Surface main
MIDI Control Surface library for Arduino
No Matches


This is an example that demonstrates how to extend the library using your own MIDI Output Elements. The example declares a MIDI Output Element that sends MIDI Note events when a push button is pressed or released. It's a simplified version of the NoteButton class.

Boards: 🛈
AVR, AVR USB, Due, Nano 33 IoT, Nano 33 BLE, UNO R4, Pi Pico, Teensy 3.x, ESP32


The internal pull-up resistor for the button will be enabled automatically.



Select the Arduino as a custom MIDI controller in your DAW, and use the MIDI learn option to assign the button to a function.

Written by PieterP, 2020-02-04

* @brief A class for momentary buttons and switches that send MIDI events.
* The button is debounced, and the internal pull-up resistor is enabled.
* @see NoteButton
* @see Button
class MyNoteButton : public MIDIOutputElement {
* @brief Create a new MyNoteButton object on the given pin, with the
* given address and velocity.
* @param pin
* The digital input pin to read from.
* The internal pull-up resistor will be enabled.
* @param address
* The MIDI address to send to.
* @param velocity
* The MIDI note velocity [0, 127].
MyNoteButton(pin_t pin, MIDIAddress address, uint8_t velocity)
: button(pin), address(address), velocity(velocity) {}
// Initialize: enable the pull-up resistor for the button
// This method is called once by `Control_Surface.begin()`.
void begin() final override { button.begin(); }
// Update: read the button and send MIDI messages when appropriate.
// This method is called continuously by `Control_Surface.loop()`.
void update() final override {
AH::Button::State state = button.update(); // Read the button
if (state == AH::Button::Falling) { // if pressed
Control_Surface.sendNoteOn(address, velocity); // → note on
} else if (state == AH::Button::Rising) { // if released
Control_Surface.sendNoteOff(address, velocity); // → note off
AH::Button button;
const MIDIAddress address;
uint8_t velocity;
// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
// Instantiate a MIDI over USB interface.
// Instantiate a MyNoteButton object
MyNoteButton button {
5, // Push button on pin 5
{MIDI_Notes::C[4], Channel_1}, // Note C4 on MIDI channel 1
0x7F, // Maximum velocity
void setup() {
Control_Surface.begin(); // Initialize Control Surface (calls button.begin())
void loop() {
Control_Surface.loop(); // Update the Control Surface (calls button.update())
constexpr Channel Channel_1
Definition Channel.hpp:118
The main header file that includes all Control-Surface header files.
Control_Surface_ & Control_Surface
A predefined instance of the Control Surface to use in the Arduino sketches.
A class for reading and debouncing buttons and switches.
Definition Button.hpp:15
An enumeration of the different states a button can be in.
Definition Button.hpp:45
@ Rising
Input went from low to high (0,1)
Definition Button.hpp:49
@ Falling
Input went from high to low (1,0)
Definition Button.hpp:48
A super class for object that have to be updated regularly.
virtual void update()=0
Update this updatable.
virtual void begin()=0
Initialize this updatable.
void begin()
Initialize the Control_Surface.
void loop()
Update all MIDI elements, send MIDI events and read MIDI input.
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
void sendNoteOn(MIDIAddress address, uint8_t velocity)
Send a MIDI Note On event.
void sendNoteOff(MIDIAddress address, uint8_t velocity)
Send a MIDI Note Off event.
A class for MIDI interfaces sending MIDI messages over a USB MIDI connection.
constexpr Note C
C (Do)
Definition Notes.hpp:56
T * begin()
Get a pointer to the first element.
Definition Array.hpp:74