Control Surface master
MIDI Control Surface library for Arduino


This example demonstrates how to use custom callbacks to display the value of a selector.

AVR, AVR USB, Nano 33 IoT, Nano 33 BLE, Due, Teensy 3.x, ESP8266, ESP32


Connect the common cathode of the RGB LED to ground.


The LEDs display the current setting of the bank. Red is the first bank (0), yellow is the second bank (1), green is the third bank (2), cyan is the fourth bank (3), blue is the fifth bank (4), and purple is the sixth bank (5).

Use the two push buttons to change the setting. The one on on pin 2 increments the setting, the one on pin 3 decrements the setting.
Keeping one of the buttons pressed will keep on cycling through the settings until you let go of it.
Pressing both buttons simultaneously resets the setting to its initial value.

Note: this example doesn't send any MIDI, but you could use it as a template for a MIDI controller with banks.



Written by PieterP, 2020-02-03

// Custom callback to handle output for a selector.
class MySelectorCallback {
// Constructor
MySelectorCallback(pin_t redLED, pin_t greenLED, pin_t blueLED)
: redLED(redLED), greenLED(greenLED), blueLED(blueLED) {}
// Begin function is called once by Control Surface.
// Use it to initialize everything.
void begin() {
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
// Update function is called continuously by Control Surface.
// Use it to implement things like fading, blinking ...
void update() {}
// Update function with arguments is called when the setting
// changes.
// Use it to update the LEDs.
void update(setting_t oldSetting, setting_t newSetting) {
(void) oldSetting; // unused in this example
// Show the color of the given setting.
void show(setting_t setting) {
uint8_t color = getColor(setting);
digitalWrite(redLED, color & 0b001 ? HIGH : LOW);
digitalWrite(greenLED, color & 0b010 ? HIGH : LOW);
digitalWrite(blueLED, color & 0b100 ? HIGH : LOW);
// Convert the given setting to a 3-bit RGB color value.
static uint8_t getColor(setting_t setting) {
switch (setting) {
case 0: return 0b001;
case 1: return 0b011;
case 2: return 0b010;
case 3: return 0b110;
case 4: return 0b100;
case 5: return 0b101;
default: return 0b000;
// Member variables to remember the pin numbers of the LEDs.
pin_t redLED, greenLED, blueLED;
// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
// Create 6 banks with one track per bank.
Bank<6> bank = 1;
// Create a selector that uses our custom callback, to control the bank.
bank, // bank to manage
{10, 11, 12}, // red, green, blue LED pins
// (this is the MySelectorCallback constructor defined above)
{2, 3}, // incr/decr button pins
Wrap::Wrap, // wrap around when reaching setting 6
void setup() {
Control_Surface.begin(); // initialize
void loop() {
Control_Surface.loop(); // update
constexpr PinStatus_t LOW
constexpr PinStatus_t HIGH
constexpr PinMode_t OUTPUT
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.
uint8_t setting_t
The type used for Selectors.
Definition: Def.hpp:51
@ Wrap
When the maximum (minimum) setting is reached, wrap around to the minimum (maximum) setting.
A class that groups Bankable MIDI Output Elements and Bankable MIDI Input Elements,...
Definition: Bank.hpp:91
void begin()
Initialize the Control_Surface.
void loop()
Update all MIDI elements, send MIDI events and read MIDI input.
A class for MIDI interfaces sending MIDI messages over a USB MIDI connection.
void pinMode(pin_t pin, PinMode_t mode)
An ExtIO version of the Arduino function.
void digitalWrite(pin_t pin, PinStatus_t val)
An ExtIO version of the Arduino function.
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).