#include <MIDI.h>
#include "Controller.h"
MIDI_CREATE_DEFAULT_INSTANCE();
//**************************************************************************************************
//serial debug, to change manually:
int DEBUG = false;
//debounce time for buttons (channel and octave shift):
int debouncetime = 100;
//DEFINES:
#define PITCHBEND_POT A1
//midi channel buttons
#define MIDICH_BUTTON_UP 29
#define MIDICH_BUTTON_DOWN 30
//FSR:
#define FSR_PIN A0
#define FSR_LED_PIN 44
//trill buttons:
#define QUARTERTONEUP_BUTTON 8
#define QUARTERTONEDOWN_BUTTON 7
#define SEMITONEUP_BUTTON 9
#define TONEUP_BUTTON 10
#define THIRDUP_BUTTON 11
#define FIFTHUP_BUTTON 12
//octave buttons:
#define OCTAVEDOWN_BUTTON 3
#define OCTAVEUP_BUTTON 2
#define OCTAVE_LED_UP 46
#define OCTAVE_LED_DOWN 45
//VARIABLES:
//trill buttons:
int QUARTERTONEUPCOUNTER = 0;
int QUARTERTONEDOWNCOUNTER = 0;
int SEMITONEUPCOUNTER = 0;
int TONEUPCOUNTER = 0;
int THIRDUPCOUNTER = 0;
int FIFTHUPCOUNTER = 0;
int QUARTERTONEVALUE = 170; //a semi-tone = 16384/48 = 341.
int SEMITONEVALUE = 341;
int TONEVALUE = 682;
int THIRDVALUE = 1023;
int FIFTHVALUE = 2387;
int trillvalue;
//midi channel buttons:
int MIDICH = 1;
int midich_plus;
int midich_moins;
//pitchbend:
int PB_INPUT_CURRENT = 0;
int PB_INPUT_ADJUST;
int PB_INPUT_LAST = 0;
int PB_MAP;
int PB_INVERT;
int PB_ADJUST;
int PB_TOTAL;
int PB;
int PB_INPUT_CURRENT_LED_MAP;
//FSR LED:
int FSR_INPUT;
int FSR_INPUT_LED_MAP;
//ajustements:
float PBmultiplier = 1.25;
int middleCadjust = 15;
//octaves buttons:
int OCTAVECOUNTER = 0;
int OCTAVECOUNTERX;
int OCTAVE_COUNTER_LAST = 0;
int OCTAVE_COUNTER_CURRENT = 0;
//FSR notetrigger:
int currentNoteTriggerState = 0;
int lastNoteTriggerState = 0;
//NOTES AND VOLTS:
//************************************************************
//***SET THE NUMBER OF CONTROLS USED**************************
//************************************************************
//combien de TrillButtons:
//byte NUMBER_TRILLBUTTONS = 6;
//---How many buttons are connected directly to pins?---------
byte NUMBER_BUTTONS = 1;
//---How many potentiometers are connected directly to pins?--
byte NUMBER_POTS = 13;
//---How many buttons are connected to a multiplexer?---------
byte NUMBER_MUX_BUTTONS = 0;
//---How many potentiometers are connected to a multiplexer?--
byte NUMBER_MUX_POTS = 0;
//************************************************************
//***ANY MULTIPLEXERS? (74HC4067)************************************
//MUX address pins must be connected to Arduino UNO pins 2,3,4,5
//A0 = PIN2, A1 = PIN3, A2 = PIN4, A3 = PIN5
//*******************************************************************
//Mux NAME (OUTPUT PIN, , How Many Mux Pins?(8 or 16) , Is It Analog?);
//Mux M1(10, 16, false); //Digital multiplexer on Arduino pin 10
//Mux M2(A5, 8, true); //Analog multiplexer on Arduino analog pin A5
//*******************************************************************
//***DEFINE DIRECTLY CONNECTED POTENTIOMETERS************************
//Pot (Pin Number, Command, CC Control, Channel Number)
//**Command parameter is for future use**
Pot PO1(A3, 0, 85, MIDICH); //BRIGHT
Pot PO2(A5, 0, 20, MIDICH); //D3
Pot PO3(A6, 0, 22, MIDICH); //D2
Pot PO4(A7, 0, 23, MIDICH); //D1
Pot PO5(A8, 0, 24, MIDICH); //LINE
Pot PO6(A9, 0, 25, MIDICH); //8
Pot PO7(A10, 0, 26, MIDICH); //N
Pot PO8(A11, 0, 27, MIDICH); //C
Pot PO9(A12, 0, 28, MIDICH); //O
Pot PO10(A13, 0, 29, MIDICH); //G
Pot PO11(A14, 0, 30, MIDICH); //g
Pot PO12(A15, 0, 31, MIDICH); //S
Pot PO13(A0, 0, 11, MIDICH); //FSR
//Pot PO14(A5, 0, 31, 1);
//*******************************************************************
//Add pots used to array below like this-> Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6};
Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6, &PO7, &PO8, &PO9, &PO10, &PO11, &PO12, &PO13};
//*******************************************************************
//***DEFINE DIRECTLY CONNECTED BUTTONS*******************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
//** Command parameter 0=NOTE 1=CC 2=Toggle CC **
Button BU1(6, 2, 86, MIDICH, 5 ); //TUTTI toggle
//Button BU2(x, x, x, x, x);
//Button BU3(4, 1, 64, 1, 5 );
//Button BU4(5, 2, 63, 1, 5 );
//Button BU5(6, 0, 64, 1, 5 );
//Button BU6(7, 0, 65, 1, 5 );
//Button BU7(8, 1, 64, 1, 5 );
//Button BU8(9, 2, 64, 1, 5 );
//*******************************************************************
//Add buttons used to array below like this-> Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8};
Button *BUTTONS[] {&BU1};
//*******************************************************************
//***DEFINE BUTTONS CONNECTED TO MULTIPLEXER*************************
//Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
//** Command parameter 0=NOTE 1=CC 2=Toggle CC **
//Button MBU1(M1, 0, 0, 70, 1, 5);
//Button MBU2(M1, 1, 1, 71, 1, 5);
//Button MBU3(M1, 2, 2, 72, 1, 5);
//Button MBU4(M1, 3, 0, 73, 1, 5);
//Button MBU5(M1, 4, 0, 74, 1, 5);
//Button MBU6(M1, 5, 0, 75, 1, 5);
//Button MBU7(M1, 6, 0, 76, 1, 5);
//Button MBU8(M1, 7, 0, 77, 1, 5);
//Button MBU9(M1, 8, 0, 78, 1, 5);
//Button MBU10(M1, 9, 0, 79, 1, 5);
//Button MBU11(M1, 10, 0, 80, 1, 5);
//Button MBU12(M1, 11, 0, 81, 1, 5);
//Button MBU13(M1, 12, 0, 82, 1, 5);
//Button MBU14(M1, 13, 0, 83, 1, 5);
//Button MBU15(M1, 14, 0, 84, 1, 5);
//Button MBU16(M1, 15, 0, 85, 1, 5);
//*******************************************************************
////Add multiplexed buttons used to array below like this-> Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
Button *MUXBUTTONS[] {};
//*******************************************************************
//***DEFINE POTENTIOMETERS CONNECTED TO MULTIPLEXER*******************
//Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
//**Command parameter is for future use**
//assigns au cc 20 27 inclusivement (midi cc qui sont de base unasigned...)
//Pot MPO1(M2, 0, 0, 20, 1);
//Pot MPO2(M2, 1, 0, 21, 1);
//Pot MPO3(M2, 2, 0, 22, 1);
//Pot MPO4(M2, 3, 0, 23, 1);
//Pot MPO5(M2, 4, 0, 24, 1);
//Pot MPO6(M2, 5, 0, 25, 1);
//Pot MPO7(M2, 6, 0, 26, 1);
//Pot MPO8(M2, 7, 0, 27, 1);
//Pot MPO9(M2, 8, 0, 50, 1);
//Pot MPO10(M2, 9, 0, 55, 2);
//Pot MPO11(M2, 10, 0, 50, 1);
//Pot MPO12(M2, 11, 0, 55, 2);
//Pot MPO13(M2, 12, 0, 50, 1);
//Pot MPO14(M2, 13, 0, 55, 2);
//Pot MPO15(M2, 14, 0, 50, 1);
//Pot MPO16(M2, 15, 0, 55, 2);
//*******************************************************************
//Add multiplexed pots used to array below like this-> Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
Pot *MUXPOTS[] {};
//*******************************************************************
void setup() {
//pinModes pour octave buttons:
pinMode(OCTAVEDOWN_BUTTON, INPUT);
pinMode(OCTAVEUP_BUTTON, INPUT);
//pinModes pour trillbuttons:
pinMode(QUARTERTONEUP_BUTTON, INPUT);
pinMode(QUARTERTONEDOWN_BUTTON, INPUT);
pinMode(SEMITONEUP_BUTTON, INPUT);
pinMode(TONEUP_BUTTON, INPUT);
pinMode(THIRDUP_BUTTON, INPUT);
pinMode(FIFTHUP_BUTTON, INPUT);
//MIDICH buttons:
pinMode(MIDICH_BUTTON_DOWN, INPUT);
pinMode(MIDICH_BUTTON_UP, INPUT);
//leds:
pinMode(OCTAVE_LED_DOWN, OUTPUT);
pinMode(OCTAVE_LED_UP, OUTPUT);
pinMode(FSR_LED_PIN, OUTPUT);
//MIDI.begin();
Serial.begin(115200); //115200 = default rate of Hairless MIDI/serial bridge software.
}
//*************************************************************************************************************
void loop() {
//added:
MIDIChannel();
PBVOID();
NoteTrigger();
LEDs();
//original:
if (NUMBER_BUTTONS != 0) updateButtons();
if (NUMBER_POTS != 0) updatePots();
if (NUMBER_MUX_BUTTONS != 0) updateMuxButtons();
if (NUMBER_MUX_POTS != 0) updateMuxPots();
//added, serial debug:
if (DEBUG == true) {
Serial.print(PB_INPUT_CURRENT);
Serial.print(", "); Serial.print(PB_INPUT_ADJUST);
Serial.print(", "); Serial.print(PB_TOTAL);
Serial.print(", "); Serial.print(MIDICH);
Serial.print(", "); Serial.print(currentNoteTriggerState);
Serial.print(", "); Serial.print(OCTAVECOUNTER);
//Serial.print(", "); Serial.print();
//Serial.print(", "); Serial.print();
//Serial.print(", "); Serial.print();
//Serial.print(", "); Serial.print();
//Serial.print(", "); Serial.print();
//Serial.print(", "); Serial.print();
Serial.println();
}
}
//*************************************************************************************************************************************
void MIDIChannel() {
MIDICH = constrain(MIDICH, 1, 16);
midich_plus = digitalRead(MIDICH_BUTTON_UP);
midich_moins = digitalRead(MIDICH_BUTTON_DOWN);
//+:
if (midich_plus == HIGH) {
MIDICH++;
delay(debouncetime);
}
//-:
if (midich_moins == HIGH) {
MIDICH--;
delay(debouncetime);
}
}
//***********************************************************************
void NoteTrigger() {
OCTAVECOUNTER = constrain(OCTAVECOUNTER, -3, 3); //+- 3 octaves max shift
//octave buttons:
if (digitalRead(OCTAVEUP_BUTTON) == HIGH) {
OCTAVECOUNTER++;
delay(debouncetime);
}
if (digitalRead(OCTAVEDOWN_BUTTON) == HIGH) {
OCTAVECOUNTER--;
delay(debouncetime);
}
OCTAVECOUNTERX = OCTAVECOUNTER * 12;
currentNoteTriggerState = analogRead(FSR_PIN);
if (currentNoteTriggerState > 0 && lastNoteTriggerState == 0) {
MIDI.sendNoteOn(60 + OCTAVECOUNTERX, 127, MIDICH);
}
if (currentNoteTriggerState == 0 && lastNoteTriggerState > 0) {
MIDI.sendNoteOff(60 + OCTAVECOUNTERX, 127, MIDICH);
}
lastNoteTriggerState = currentNoteTriggerState;
}
//************************************************************************
void PBVOID() {
//quarter tone up:
if (digitalRead(QUARTERTONEUP_BUTTON) == HIGH) {
QUARTERTONEUPCOUNTER = QUARTERTONEVALUE;
}
if (digitalRead(QUARTERTONEUP_BUTTON) == LOW) {
QUARTERTONEUPCOUNTER = 0;
}
//quarter tone down:
if (digitalRead(QUARTERTONEDOWN_BUTTON) == HIGH) {
QUARTERTONEDOWNCOUNTER = -QUARTERTONEVALUE;
}
if (digitalRead(QUARTERTONEDOWN_BUTTON) == LOW) {
QUARTERTONEDOWNCOUNTER = 0;
}
//semi-tone up:
if (digitalRead(SEMITONEUP_BUTTON) == HIGH) {
SEMITONEUPCOUNTER = SEMITONEVALUE;
}
if (digitalRead(SEMITONEUP_BUTTON) == LOW) {
SEMITONEUPCOUNTER = 0;
}
//tone up:
if (digitalRead(TONEUP_BUTTON) == HIGH) {
TONEUPCOUNTER = TONEVALUE;
}
if (digitalRead(TONEUP_BUTTON) == LOW) {
TONEUPCOUNTER = 0;
}
//third up:
if (digitalRead(THIRDUP_BUTTON) == HIGH) {
THIRDUPCOUNTER = THIRDVALUE;
}
if (digitalRead(THIRDUP_BUTTON) == LOW) {
THIRDUPCOUNTER = 0;
}
//fifth up:
if (digitalRead(FIFTHUP_BUTTON) == HIGH) {
FIFTHUPCOUNTER = FIFTHVALUE;
}
if (digitalRead(FIFTHUP_BUTTON) == LOW) {
FIFTHUPCOUNTER = 0;
}
trillvalue = QUARTERTONEUPCOUNTER + QUARTERTONEDOWNCOUNTER + SEMITONEUPCOUNTER + TONEUPCOUNTER + THIRDUPCOUNTER + FIFTHUPCOUNTER;
//pitch bend pot:
PB_INPUT_CURRENT = analogRead(PITCHBEND_POT);
PB_INPUT_CURRENT_LED_MAP = map(PB_INPUT_CURRENT, -8192, 8191, 0, 255);
PB_INPUT_ADJUST = PB_INPUT_CURRENT + middleCadjust;
PB_INPUT_ADJUST = constrain(PB_INPUT_ADJUST, 0, 1023);
PB_MAP = map(PB_INPUT_ADJUST, 1023, 0, -8192, 8191); //signed integer value.
PB_ADJUST = PB_MAP * PBmultiplier;
PB_TOTAL = PB_ADJUST + trillvalue;
PB_TOTAL = constrain(PB_TOTAL, -8192, 8191);
//send pitchbend continuoulsy:
MIDI.sendPitchBend(PB_TOTAL, MIDICH);
delay(2); //for stability
}
//*******************************************************************
void LEDs() {
OCTAVE_COUNTER_CURRENT = OCTAVECOUNTER;
if(OCTAVE_COUNTER_CURRENT != OCTAVE_COUNTER_LAST) {
if (OCTAVECOUNTER == -3) {
analogWrite(OCTAVE_LED_DOWN, 255);
digitalWrite(OCTAVE_LED_UP, LOW);
}
if (OCTAVECOUNTER == -2) {
analogWrite(OCTAVE_LED_DOWN, 170);
digitalWrite(OCTAVE_LED_UP, LOW);
}
if (OCTAVECOUNTER == -1) {
analogWrite(OCTAVE_LED_DOWN, 85);
digitalWrite(OCTAVE_LED_UP, LOW);
}
if (OCTAVECOUNTER == 0) {
digitalWrite(OCTAVE_LED_DOWN, LOW);
digitalWrite(OCTAVE_LED_UP, LOW);
}
if (OCTAVECOUNTER == 1) {
digitalWrite(OCTAVE_LED_DOWN, LOW);
analogWrite(OCTAVE_LED_UP, 85);
}
if (OCTAVECOUNTER == 2) {
digitalWrite(OCTAVE_LED_DOWN, LOW);
analogWrite(OCTAVE_LED_UP, 170);
}
if (OCTAVECOUNTER == 3) {
digitalWrite(OCTAVE_LED_DOWN, LOW);
analogWrite(OCTAVE_LED_UP, 255);
}
}
OCTAVE_COUNTER_LAST = OCTAVE_COUNTER_CURRENT;
FSR_INPUT = analogRead(FSR_PIN);
FSR_INPUT_LED_MAP = map(FSR_INPUT, 0, 1024, 0, 255);
//FSR LED:
if(analogRead(FSR_PIN) > 0) {
analogWrite(FSR_LED_PIN, FSR_INPUT_LED_MAP);
}
if(analogRead(FSR_PIN) == 0) {
digitalWrite(FSR_LED_PIN, LOW);
}
}
//**********************************************************************************************
void updateButtons() {
// Cycle through Button array
for (int i = 0; i < NUMBER_BUTTONS; i = i + 1) {
byte message = BUTTONS[i]->getValue();
// Button is pressed
if (message == 0) {
switch (BUTTONS[i]->Bcommand) {
case 0: //Note
MIDI.sendNoteOn(BUTTONS[i]->Bvalue + OCTAVECOUNTER * 12, 127, BUTTONS[i]->Bchannel);
break;
case 1: //CC
MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
break;
case 2: //Toggle
if (BUTTONS[i]->Btoggle == 0) {
MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, MIDICH); //origine: BUTTONS[i]->Bchannel
BUTTONS[i]->Btoggle = 1;
}
else if (BUTTONS[i]->Btoggle == 1) {
MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, MIDICH); //origine: BUTTONS[i]->Bchannel
BUTTONS[i]->Btoggle = 0;
}
break;
}
}
// Button is not pressed
if (message == 1) {
switch (BUTTONS[i]->Bcommand) {
case 0:
MIDI.sendNoteOff(BUTTONS[i]->Bvalue + OCTAVECOUNTER * 12, 0, BUTTONS[i]->Bchannel);
break;
case 1:
MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
break;
}
}
}
}
//*******************************************************************
void updateMuxButtons() {
// Cycle through Mux Button array
for (int i = 0; i < NUMBER_MUX_BUTTONS; i = i + 1) {
MUXBUTTONS[i]->muxUpdate();
byte message = MUXBUTTONS[i]->getValue();
// Button is pressed
if (message == 0) {
switch (MUXBUTTONS[i]->Bcommand) {
case 0: //Note
MIDI.sendNoteOn(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
break;
case 1: //CC
MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
break;
case 2: //Toggle
if (MUXBUTTONS[i]->Btoggle == 0) {
MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
MUXBUTTONS[i]->Btoggle = 1;
}
else if (MUXBUTTONS[i]->Btoggle == 1) {
MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
MUXBUTTONS[i]->Btoggle = 0;
}
break;
}
}
// Button is not pressed
if (message == 1) {
switch (MUXBUTTONS[i]->Bcommand) {
case 0:
MIDI.sendNoteOff(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
break;
case 1:
MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
break;
}
}
}
}
//***********************************************************************
void updatePots() {
for (int i = 0; i < NUMBER_POTS; i = i + 1) {
byte potmessage = POTS[i]->getValue();
if (potmessage != 255) MIDI.sendControlChange(POTS[i]->Pcontrol, potmessage, MIDICH); //origine: POTS[i]->Pchannel
}
}
//***********************************************************************
void updateMuxPots() {
for (int i = 0; i < NUMBER_MUX_POTS; i = i + 1) {
MUXPOTS[i]->muxUpdate();
byte potmessage = MUXPOTS[i]->getValue();
if (potmessage != 255) MIDI.sendControlChange(MUXPOTS[i]->Pcontrol, potmessage, MUXPOTS[i]->Pchannel);
}
}
// ******************** END ***************************** //
Comments
Please log in or sign up to comment.