Code:
//************LIBRARIES USED**************
// include the ResponsiveAnalogRead library for analog smoothing
#include <ResponsiveAnalogRead.h>
//usbMIDI.h library is added automatically when code is compiled as a MIDI device
// ******CONSTANT VALUES********
// customize code behaviour here!
const int muxTimeMin = 500; // minimum micro-seconds between MUX reads
const int channel = 1; // MIDI channel
const int MUX_PINS = 16; // number of MUX Channnels
// define the CC ID numbers on which to send them..
const int CCID[MUX_PINS] = {21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36};
//******VARIABLES***********
// a data array and a lagged copy to tell when MIDI changes are required
byte data[MUX_PINS];
byte dataLag[MUX_PINS]; // when lag and new are not the same then update MIDI CC value
byte i=0; // global index for MUX channel reads
//mapping of mux to teensy digital pins
int pin_Out_S0 = 0;
int pin_Out_S1 = 1;
int pin_Out_S2 = 2;
int pin_Out_S3 = 3;
int pin_In_Mux1 = A1;
//****** TIMER VARIABLE *** change scale here!
elapsedMicros mux1Updated; // switch to micros to run at speed and tune with muxTimeMin setting above
//elapsedMillis mux1Updated; // switch to millis to troubleshoot
//************INITIALIZE LIBRARY OBJECTS**************
// initialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead analog[]{
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true}
};
//************SETUP**************
void setup() {
//! don't forget to set for output!
pinMode(pin_Out_S0, OUTPUT);
pinMode(pin_Out_S1, OUTPUT);
pinMode(pin_Out_S2, OUTPUT);
pinMode(pin_Out_S3, OUTPUT);
}
//************LOOP**************
void loop() {
nextMUXpin();
while (usbMIDI.read()) {
// controllers must call .read() to keep the queue clear even if they are not responding to MIDI
}
}
//************MUX SECTION**************
void nextMUXpin(){
if (mux1Updated>muxTimeMin) {
// update the ResponsiveAnalogRead object every loop
analog[i].update();
// if the repsonsive value has change, print out 'changed'
if(analog[i].hasChanged()) {
data[i] = analog[i].getValue()>>3;
if (data[i] != dataLag[i]){
dataLag[i] = data[i];
usbMIDI.sendControlChange(CCID[i], data[i], channel);
serialPringMIDIdata(); // use to troublshoot
}
}
//reset timer
mux1Updated = 0;
//increment index
i++;
if (i>15) {i=0;}
// set mux control pins for next pass
digitalWrite(pin_Out_S0, HIGH && (i & B00000001));
digitalWrite(pin_Out_S1, HIGH && (i & B00000010));
digitalWrite(pin_Out_S2, HIGH && (i & B00000100));
digitalWrite(pin_Out_S3, HIGH && (i & B00001000));
}
}
// **useful for debugging, comment out function call to run full speed
void serialPringMIDIdata(){
Serial.print(i,DEC);
Serial.print(" :");
Serial.print(HIGH && (i & B00000001),BIN);
Serial.print(HIGH && (i & B00000010),BIN);
Serial.print(HIGH && (i & B00000100),BIN);
Serial.print(HIGH && (i & B00001000),BIN);
Serial.print(" MUX_PIN: ");
Serial.print(i,DEC);
Serial.print(" CC: ");
Serial.print(CCID[i],DEC);
Serial.print(" DATA HEX: ");
Serial.println(data[i],HEX);
}