Go Down

Topic: Simple MIDI programming on Leonardo (Read 179 times) previous topic - next topic


Greetings all.

I greatly appreciate everyone who reads this and responds.

I am building a midi controller for a close friend of mine who loves making music.

The controller has 8 buttons and 4 potentiometers/knobs.

The buttons and pots/knobs are already wired and working but I need help with the code for the Leonardo.

Please teach me how to edit the code to add the following functionality:

1. I would like the knobs to be mapped to certain CC parameters by default. So for instance, once the MIDI controller is plugged in, one of the potentiometers will automatically be set to control modulation. Another will control volume. So on and so forth.

2. How can I program some of the buttons to feature basic transport controls. (play, stop, and record)

3. How can I program buttons to bank up and down. In other words, add a button that moves all the input buttons up or down one octave.

Here is the code that I have so far. I have attached it. Please send any feedback or questions. I will be so happy to receive your assistance. Thanks in advance.



Please teach me how to edit the code to add the following functionality:

Download Arduino IDE, open your code and start editing. You have the code, you have the hardware...???

The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"


That code is way too complicated.

I would recommend something like this. It uses the Control Surface library.

#include <Control_Surface.h> // https://github.com/tttapa/Control-Surface
using namespace MIDI_Notes;

// Add a MIDI interface to use:
USBMIDI_Interface midi;

// Add potentiometer controls:
CCPotentiometer modulation = {A0, {MIDI_CC::Modulation_Wheel, CHANNEL_1}};  
CCPotentiometer volume     = {A1, {MIDI_CC::Channel_Volume,   CHANNEL_1}};
CCPotentiometer pan        = {A2, {MIDI_CC::Pan,              CHANNEL_1}};
PBPotentiometer pitch      = {A3, CHANNEL_1};

// Add transposer with three states:
// one octave down (-1), not transposed (0), and one octave up (+1)  
Transposer<-1, +1> octaveTransp(12); // 12 semitones = one octave

// Add buttons to control the transposer
IncrementDecrementSelector<octaveTransp.N> selector = {
  octaveTransp, {10, 11}, Wrap::Clamp, // pin 10 transposes up, pin 11 down  

// Add note buttons that can be transposed:
Bankable::NoteButton buttons[] = {
  {octaveTransp, 2, note(C, 4)}, // pin 2, middle C
  {octaveTransp, 3, note(D, 4)}, // pin 3, middle D
  {octaveTransp, 4, note(E, 4)},
  {octaveTransp, 5, note(F, 4)},
  {octaveTransp, 6, note(G, 4)},

// Add transport control buttons:
NoteButton transportButtons[] = {
  {7, MCU::PLAY},   // pin 7, Mackie Control Universal "play" command
  {8, MCU::STOP},   // pin 8, Mackie Control Universal "stop" command
  {9, MCU::RECORD},

void setup() {

void loop() {

It handles debouncing, potentiometer filtering, transposing, etc. internally so you don't have to worry about any of that.
Everything you add (MIDI interfaces, potentiometers, buttons, transposers, selectors) is automatically picked up by the library, and it will initialize and update everything for you.


Go Up