Control Surface master
MIDI Control Surface library for Arduino

This is an example of the CCPotentiometer class of the Control_Surface library, and specifically, how to use the map function to account for non-linearities of the potentiometer.


The map function in this example corrects for potentiometers that don't go all the way to the extreme values. Some potentiometers still read a value that's greater than 0 when turned all the way to the left. To fix that, tweak the minimumValue constant. If the potentiometer doesn't read the maximum value when turned all the way to the right, tweak the maximumValue constant.

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


Connect the left terminal of the potentiometer to ground, and the right one to VCC.



Select the Arduino as a custom MIDI controller in your DAW, and use the MIDI learn option to assign the potentiometer to a function.
It will send the MIDI Control Change Channel Volume parameter for channel 1.

Written by Pieter P, 16-06-2019

// Include the Control Surface library
// Instantiate a MIDI over USB interface.
// Create a new instance of the class `CCPotentiometer`, called `potentiometer`,
// on pin A0, that sends MIDI messages with controller 7 (channel volume)
// on channel 1.
CCPotentiometer potentiometer {
// The filtered value read when potentiometer is at the 0% position
constexpr analog_t minimumValue = 255;
// The filtered value read when potentiometer is at the 100% position
constexpr analog_t maximumValue = 16383 - 255;
// A mapping function to eliminate the dead zones of the potentiometer:
// Some potentiometers don't output a perfect zero signal when you move them to
// the zero position, they will still output a value of 1 or 2, and the same
// goes for the maximum position.
analog_t mappingFunction(analog_t raw) {
// make sure that the analog value is between the minimum and maximum
raw = constrain(raw, minimumValue, maximumValue);
// map the value from [minimumValue, maximumValue] to [0, 16383]
return map(raw, minimumValue, maximumValue, 0, 16383);
// Note: 16383 = 2¹⁴ - 1 (the maximum value that can be represented by
// a 14-bit unsigned number
void setup() {
// Add the mapping function to the potentiometer;
// Initialize everything
void loop() {
// Update the Control Surface (check whether the potentiometer's
// input has changed since last time, if so, send the new value over MIDI).
// Use this to find minimumValue and maximumValue: it prints the raw value
// of the potentiometer, without the mapping function
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 of MIDIOutputElements that read the analog input from a potentiometer or fader,...
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.
uint16_t analog_t
The type returned from analogRead and similar functions.
constexpr uint8_t Channel_Volume