# Built a MIDI CC Controller that Includes a Foot Pedal for CC1 (or other CC)



## ReelToLogic (Mar 5, 2021)

I was inspired by some of the postings here on VI-Control and some other forums to try building my own MIDI CC Controller. In addition to five 100mm Sliders I wanted to add a foot pedal that I could assign to CC1 or CC11 so that I could play string or other VI parts with both hands while still controlling Modulation or Expression.

So I bought a Nectar NX-P Foot Pedal (only $20; https://www.musiciansfriend.com/keyboards-midi/nektar-nx-p-universal-expression-pedal) hoping I could make that work with the Teensy 3.2 controller. It turns out it contains a variable resistor (potentiometer) similar to the other slide potentiometers I used in the main module, so it was very easy to incorporate. The 1/4" Stereo (TRS) connector plugs into my main box. On my unit I set the polarity to the #1 setting (there's a switch on the bottom) and I found that the "Tip" was the wiper so I connected that to an analog input, the "Ring" got 3.3 volts and the "Sleave" went to ground. I turned the "sensitivity" knob on the side fully CCW and I got smooth output of CC's from 0 to 127 over the full travel of the pedal.

I also included a 5-position selector switch so that I can pre-program 5 different sets of CC's and select them on the fly. I've wired that in, but haven't finished debugging the code to do that yet so right now I just have one set of CC's. I also wanted a device that was very compact so I purchased a plastic box that was just a little over 5" x 7" in size. It was so small that I had to do some minor machining just to make the 100mm travel slide pots fit inside it!

I was very excited at how easy and inexpensive it was to incorporate a foot controller into my project so I wanted to share this. I should note that I also have one of the 100mm sliders assigned to CC1, since my hands can do a more precise job of control than my foot. Depending on how skilled I get with my foot, it may be that I use the pedal more for "playing" than for recording - we'll see. It certainly is nice to have when playing! There are lots of other threads that discuss building these simple MIDI CC controllers but if anyone wants more info on this project just let me know.


----------



## fakemaxwell (Mar 5, 2021)

I keep waffling back and forth on building one. Did you use one of the MIDI CC libraries out there or code your own?


----------



## ReelToLogic (Mar 5, 2021)

I used the code from this thread;https://www.gearslutz.com/board/music-computers/1240121-diy-midi-cc-controller-w-100mm-sliders-under-100-2018-edition.html

As shown at the bottom of that thread (the 24th response), I added a couple of lines of code to prevent an issue I had with my DAW, but other than that, the code worked as is.

As I said above, I'm currently building on the code so that I can have multiple banks or sets of CC's to select from, and that's proving to be a bit more complicated than I had anticipated. But for a simple control system, it doesn't take much code and is simple cut-and-paste.


----------



## ReelToLogic (Mar 6, 2021)

Quick update: I got the 5 banks/sets of MIDI CC's working with the help of some great folks over on pjrc.com. You have to set up CCID as a two-dimensional array. A simpler version of the code (with just one set of user-defined CC's) is given in the thread linked in the 3rd posting above, but in case anyone is interested in using multiple banks of CCs I've copied the final code I used (on a Teensy 3.2 controller) below:


#include <Bounce.h>

///////////////////////////////////////////////////////////////////////////
// define how many pots are active up to number of available analog inputs
#define analogInputs 6
//////////////////////////////////////////////////////////////////////////

// define arrays for input values and lagged input values
int inputAnalog[analogInputs];
int iAlag[analogInputs];
// define array of cc values
int ccValue[analogInputs];
// include the ResponsiveAnalogRead library
#include <ResponsiveAnalogRead.h>

// Define variables for Rotary Switch function (used to define one of 5 CC sets)
int RotNewState;
int Pin1State;
int Pin3State;
int Pin4State;
int Pin7State;

///////////////////////////////////////////////////////////////////////////
// define pins and cc codes
const int A_PINS = 6;
const int ANALOG_PINS[A_PINS] = {A0, A1, A2, A3, A4, A5};
const int CC_SETS = 5;
const int CCID[CC_SETS][A_PINS] = {{11, 11, 11, 1, 1, 11}, {11, 11, 1, 11, 1, 11}, {11, 1, 11, 11, 1 , 11}, {1, 11, 11, 11, 1, 11}, {11, 11, 11, 11, 1, 1}};
/// 1's and 11's are for testing the controller only. Update to desired CC's in final version
///////////////////////////////////////////////////////////////////////////

// //////// REFERENCE INFO /////////////////////////////////////////////
// Five sliders left-to-right are A3, A2, A1, A0, A5. Footpedal is A4
//0=bank, 1=mod, 2=Breath, 7=Vol, 8=Bal, 10=pan, 4=foot, 11=Expr, 21=Vib 64=pedal
/////////////////////////////////////////////////////////////////////////

// a data array and a lagged copy to tell when MIDI changes are required
byte data[A_PINS];
byte dataLag[A_PINS];

// ititialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead analog[] {
///////////////////////////////////////////////////////////////////////////
{ANALOG_PINS[1], true},
{ANALOG_PINS[2], true},
{ANALOG_PINS[3], true},
{ANALOG_PINS[4], true},
{ANALOG_PINS[5], true},
{ANALOG_PINS[0], true},
///////////////////////////////////////////////////////////////////////////
};

// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);

// Define Input pins (from 5-position Rotary Switch)
pinMode (1, INPUT);
pinMode (3, INPUT);
pinMode (4, INPUT);
pinMode (7, INPUT);
}

void loop() {

// MIDI Controllers should discard incoming MIDI messages.
while (usbMIDI.read()) {
// read & ignore incoming messages
}

// Determine the state of the 4 pins coming from the rotary switch
Pin1State = digitalRead(1);
Pin3State = digitalRead(3);
Pin4State = digitalRead(4);
Pin7State = digitalRead(7);

// Deduce the "CC Set" selected on the Rotary Switch and store in variable "RotNewState";
if (Pin3State == HIGH && Pin7State == HIGH) {
RotNewState = 0;
}
if (Pin4State == HIGH && Pin7State == HIGH) {
RotNewState = 1;
}
if (Pin4State == HIGH && Pin7State == LOW) {
RotNewState = 2;
}
if (Pin1State == HIGH && Pin4State == HIGH) {
RotNewState = 3;
}
if (Pin1State == HIGH && Pin4State == LOW) {
RotNewState = 4;
}

// Serial.println(RotNewState); //was used to check function of determining rotary switch position -> worked fine.

// update the ResponsiveAnalogRead object every loop
for (int i = 0; i < A_PINS; i++) {
analog_.update();
// if the repsonsive value has change, print out 'changed'
if (analog.hasChanged()) {
data = analog.getValue() >> 3;
if (data != dataLag) {
dataLag = data;
usbMIDI.sendControlChange(CCID[RotNewState], data, 1);
}
}
}
}_


----------

