Hi I am new in the forum and new to coding. Bought a 6 button midi controller and was trying to code. Manage to add 2 different midi channel into the code.
The mid controller works in way that when I switch on button 1, I need to off button 1 in order not the mess up the PC number.
How can I switch on a random preset (e.g. button 3) without needing to off it.
For e.g. When I switch to button 4, button 3 will off it and button 4 preset will come right up.
Any help appreciated.
Thanks!
The mid controller works in way that when I switch on button 1, I need to off button 1 in order not the mess up the PC number.
How can I switch on a random preset (e.g. button 3) without needing to off it.
For e.g. When I switch to button 4, button 3 will off it and button 4 preset will come right up.
Any help appreciated.
Thanks!
Code:
//************LIBRARIES USED**************
// 'include the Bounce library for 'de-bouncing' switches -- removing electrical chatter as contacts settle'
#include <MIDI.h>
#include <Bounce.h>
//'usbMIDI.h library is added automatically when code is compiled as a MIDI device'
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
// ******CONSTANT VALUES********
//********** PIN DEFINITIONS
const int D_PINS = 5; // number of Digital PINS in main group (excl tap/bank)
const int DIGITAL_PINS[D_PINS] = {0,1,2,3,4}; // pins to switchs
const int RED_LED_PINS[D_PINS] = {6,22,10,17,19};
const int GREEN_LED_PINS[D_PINS] = {24,9,16,18,20};
const int MODE_TAP_PIN = 5; // momentary switch to set tempo and select bank
const int MODE_TAP_LED_PIN = 15; // pin to LED for tempo/bank indicator
//Alan
const int RED_LED_PINS1[D_PINS] = {6}; // pins to switchs RED
const int RED_LED_PINS2[D_PINS] = {22}; // pins to switchs RED
const int RED_LED_PINS3[D_PINS] = {10}; // pins to switchs RED
const int RED_LED_PINS4[D_PINS] = {17}; // pins to switchs RED
const int RED_LED_PINS5[D_PINS] = {19}; // pins to switchs RED
const int GREEN_LED_PINS6[D_PINS] = {24}; // pins to switchs GREEN
const int GREEN_LED_PINS7[D_PINS] = {9}; // pins to switchs GREEN
const int GREEN_LED_PINS8[D_PINS] = {16}; // pins to switchs GREEN
const int GREEN_LED_PINS9[D_PINS] = {18}; // pins to switchs GREEN
const int GREEN_LED_PINS10[D_PINS] = {20}; // pins to switchs GREEN
const int DIGITAL_PINS0[D_PINS] = {0}; // pins to switchs
const int DIGITAL_PINS1[D_PINS] = {1}; // pins to switchs
const int DIGITAL_PINS2[D_PINS] = {2}; // pins to switchs
const int DIGITAL_PINS3[D_PINS] = {3}; // pins to switchs
const int DIGITAL_PINS4[D_PINS] = {4}; // pins to switchs
//********** MIDI DEFINITIONS*************
// MODIFY THIS SECTION TO CUSTOMISE YOUR MIDISTOMP SIX
const int firstchannel = 1; // MIDI channel for USB MIDI
const int secondchannel = 2; // MIDI channel for TRS MIDI
const int thirdchannel = 3; // MIDI channel for TRS MIDI
const int MODE_COUNT = 2; // number of rows of banks
const int MODE_COUNT2 = 2; // number of rows of banks
//CC configuration matrix!! TIMELINE
const int MIDI_PC_NUMS[MODE_COUNT][D_PINS] = { //rows are banks up to MODE_COUNT
{60,61,62,63,64},
{65,66,67,68,69}
};
// BIGSKY
const int MIDI_PC_NUMS2[MODE_COUNT2][D_PINS] = { //rows are banks up to MODE_COUNT
{60,60,62,63,64},
{60,60,60,60,60}
};
const int TAP_CC = 93;
//const int TAP_CC_DOWN = 80+82;
//const int TAP_CC_UP = 82+81;
const int ON_Value = 127; // note-one velocity sent from buttons (should be 65 to 127)
//********** PHYSICAL DEFINITIONS
const int BOUNCE_TIME = 30; // 5 ms is usually sufficient
const int modeThreshold = 800; // how long to hold before mode changes
const int flashOnTime = 150; // how long flashed LED is on
const int flashOffTime = 250; // how long flashed LED is off
const bool LED_ON = LOW; // LOW for active LOW wiring
const bool LED_OFF = HIGH; // HIGH for active LOW wiring
const int onClocks = 4; // number of clock messages with LED on for tempo flash
const int waitflash = 2; // number of dark flash cylces after bank change before tempo flash resumes
//******VARIABLES***********
// a data array to remember the current state of each switch
boolean state[MODE_COUNT][D_PINS];
elapsedMillis modeTimer,flashTimer;
boolean modeSelectActive = false;
int bank = 0 ;
int flashcount= (-1*waitflash); // default is effective sequence stop of flash counter
int shiftUp; // keeps track of whether the mode change needs to be handled (true) or was (false)
int modeLED; // keeps track of whether LED is on without testing it..
int ClockCount; // for tempo tracking
boolean tempoFlashOn = true;// tempo flash defaults to on
//************INITIALIZE LIBRARY OBJECTS**************
// initialize the bounce objects
Bounce digital[] = {
Bounce(DIGITAL_PINS[0],BOUNCE_TIME),
Bounce(DIGITAL_PINS[1], BOUNCE_TIME),
Bounce(DIGITAL_PINS[2], BOUNCE_TIME),
Bounce(DIGITAL_PINS[3], BOUNCE_TIME),
Bounce(DIGITAL_PINS[4], BOUNCE_TIME)
};
Bounce modeTap = Bounce(MODE_TAP_PIN, BOUNCE_TIME);
//************SETUP**************
void setup() {
MIDI.begin(MIDI_CHANNEL_OMNI);
//'set a handle for returning control change messages'
usbMIDI.setHandleProgramChange(OnProgramChange);
usbMIDI.setHandleSongPosition(onSongPosition);
usbMIDI.setHandleClock(onClock);
usbMIDI.setHandleStart(onStart);
//'loop to configure input pins and internal pullup resisters for digital section'
for (int i=0;i<D_PINS;i++){
pinMode(DIGITAL_PINS[i], INPUT_PULLUP);
pinMode(RED_LED_PINS[i], OUTPUT);
pinMode(GREEN_LED_PINS[i], OUTPUT);
}
pinMode(MODE_TAP_PIN, INPUT_PULLUP);
pinMode(MODE_TAP_LED_PIN, OUTPUT);
digitalWrite(MODE_TAP_LED_PIN, LED_OFF);
for (int i=0;i<D_PINS;i++){
digitalWrite(GREEN_LED_PINS[i], LED_OFF); // - GREEN OFF
digitalWrite(RED_LED_PINS[i], LED_ON); // - RED ON
}
}
//************LOOP**************
void loop() {
getMain();
getModeTap();
flasher();
while (usbMIDI.read()) {
//' controllers must call .read() to keep the queue clear even if they are not responding to MIDI'
}
while (MIDI.read()){
}
}
//************DIGITAL SECTION**************
void getMain(){
for (int i=0;i<D_PINS;i++){
digital[i].update();
if (digital[i].fallingEdge() || digital[i].risingEdge() ) {
if (state[bank][i]) {
usbMIDI.sendProgramChange(MIDI_PC_NUMS[bank][i], firstchannel);
MIDI.sendProgramChange(MIDI_PC_NUMS[bank][i], secondchannel);
MIDI.sendProgramChange(MIDI_PC_NUMS2[bank][i], thirdchannel);
digitalWrite(RED_LED_PINS[i], LED_ON);
digitalWrite(GREEN_LED_PINS[i], LED_OFF);
}else {
usbMIDI.sendProgramChange(MIDI_PC_NUMS[bank][i], firstchannel);
MIDI.sendProgramChange(MIDI_PC_NUMS[bank][i], secondchannel);
MIDI.sendProgramChange(MIDI_PC_NUMS2[bank][i], thirdchannel);
digitalWrite(RED_LED_PINS[i], LED_OFF);
digitalWrite(GREEN_LED_PINS[i], LED_ON);
}
state[bank][i] = !state[bank][i] ;
}
}
}
//************MODE/TAP SECTION**************
void getModeTap(){
modeTap.update();
if (modeTap.fallingEdge()) {
usbMIDI.sendControlChange(TAP_CC, ON_Value, firstchannel);
MIDI.sendControlChange(TAP_CC, ON_Value, secondchannel);
modeTimer = 0;
shiftUp = true;
tempoFlashOn = false;
flashcount = 0; // is this error or magic?
Serial.println("suspend tempo on tap");
}
if (modeTap.risingEdge()){
shiftUp = false;
if (modeTimer<modeThreshold){
tempoFlashOn = true;
Serial.println("resume tempo no mode change");
}
}
if (modeTimer>modeThreshold && shiftUp) {
shiftUp = false;
bank++;
bank = bank%MODE_COUNT;
for (int i = 0; i < D_PINS ; i++){
digitalWrite(GREEN_LED_PINS[i], !state[bank][i]);
digitalWrite(RED_LED_PINS[i], state[bank][i]);
}
// set counter of flashes 'owed' -- count them down after main part
flashcount = bank + 1;
flashTimer = 0 ; // is this needed?
}
}
void flasher(){
if (flashcount>= -1*waitflash){
if (flashcount> 0){
if (flashTimer>(flashOnTime+flashOffTime)){
flashcount-- ;// decrement flashcount
flashTimer = 0;
if (modeLED){
modeLED = false;
digitalWrite(MODE_TAP_LED_PIN, LED_OFF);
}
}else{
if (modeLED == false && flashTimer>flashOnTime){
modeLED = true;
digitalWrite(MODE_TAP_LED_PIN, LED_ON);
}
}
}else{
if (flashTimer>(flashOnTime+flashOffTime)){
flashcount-- ;// decrement flashcount
flashTimer = 0;
}
}
}else{
if (!tempoFlashOn){
tempoFlashOn = true;
Serial.println(flashcount);
Serial.println("resume tempo after bank select");
}
}
}
void OnProgramChange(byte rcvChannel, byte controller, byte value) {
if (rcvChannel == firstchannel){
for (int i = 0; i < D_PINS ; i++){
if (MIDI_PC_NUMS[bank][i] == controller) {
if (value >= 64) {
digitalWrite(GREEN_LED_PINS[i], LED_ON);
digitalWrite(RED_LED_PINS[i], LED_OFF); //'receiving >64 turns green on and red off'
state[bank][i] = true;
}else{
digitalWrite(GREEN_LED_PINS[i], LED_OFF);
digitalWrite(RED_LED_PINS[i], LED_ON); //'receiving <64 turns red on and green off'
state[bank][i] = false;
} // 'if not the controller for i then skip this loop'
}
}
}
}
void onClock() {
if (tempoFlashOn){
if (ClockCount<=onClocks){
digitalWrite(MODE_TAP_LED_PIN, LED_ON);
}else{
digitalWrite(MODE_TAP_LED_PIN, LED_OFF);
}
}
ClockCount = (ClockCount+1)%24;
}
void onStart(){
ClockCount = 0;
}
void onSongPosition(uint16_t semiQ){
ClockCount= semiQ*6 ;
}