briandtinker
Well-known member
All the joints are soldered even if a bit of wire comes out either end of the joint. The terminals are connected to the wire and then the wire into the breadboard alongside the corresponding PIN number.
#include <Bounce.h>
//**********CONSTANTS**********
const int BOUNCE_TIME = 25; // fine tune if the buttons need more/less time
const int LEDPIN = 13; // Upper BANK indicator LED
const int DIGITAL_PINS = 5; // size of the PINS array (no longer includes toggle button!)
const int PINS[DIGITAL_PINS] = {0,1,2,3,4}; // set pin numbers of swtiches
const int channel = 1;
[COLOR="#0000CD"]const int CCchan = 0; // arbitrary 'on' value for D2 of CC message[/COLOR]
const int resetThreshold = 2000; /// mS hold to change bank
const byte CC[][DIGITAL_PINS] = {
{60,61,62,63,64},
{65,66,67,68,69},
{70,71,72,73,74},
{75,76,77,78,79},
{80,81,82,83,84},
{85,86,87,88,89}
}; // this is the banks by switches matrix of CC values for the bank system
//**********VARIABLES/LIBRARY OBJECTS**********
int bank = 0; // this is the bank variable to be toggled
boolean CCstate[DIGITAL_PINS]; // array of current CC on/off toggle state
boolean timerOn; // timer toggle memory tracks whether a new fallingEdge was heard since the last rising; used in bank switching
Bounce btn[] = {
Bounce(PINS[0], BOUNCE_TIME),
Bounce(PINS[1], BOUNCE_TIME),
Bounce(PINS[2], BOUNCE_TIME),
Bounce(PINS[3], BOUNCE_TIME),
Bounce(PINS[4], BOUNCE_TIME),
};
elapsedMillis toggleReset; // mS clock counter to reset on contact/risgingEdge()
//**********SETUP**********
void setup() {
//Serial.begin(9600);
for (int i = 0;i<DIGITAL_PINS;i++){
pinMode(PINS[i], INPUT_PULLUP);
}
pinMode(LEDPIN, OUTPUT);
}
//**********LOOP**********
void loop() {
for (int i = 0;i<DIGITAL_PINS;i++){ // loop through each object in the BOUNCE arrray for the note switches (no longer includes TOGGLE)
btn[i].update();
if (btn[i].fallingEdge()) {
timerOn = true ;
toggleReset = 0;
}
if (btn[i].risingEdge()) {
if(toggleReset<resetThreshold){
if (CCstate[i]){
usbMIDI.sendControlChange(CCchan, CC[bank][i], channel);
}else{
usbMIDI.sendControlChange(CCchan, CC[bank][i], channel);
}
CCstate[i] = !CCstate[i] ; //toggle state memory
timerOn = false ; //turn off timer (resets each cycle)
}
}
if (timerOn && (toggleReset>resetThreshold)){
toggleReset = 0;
bank = i;
//digitalWrite(LEDPIN, bank); // turn off for now...
}
}
}
if (btn[i].risingEdge()) {
if(toggleReset>resetThreshold){
toggleReset = 0;
bank = i;
//digitalWrite(LEDPIN, bank); // turn off for now...
}
else{
usbMIDI.sendControlChange(CCchan, CC[bank][i], channel);
timerOn = false ; //turn off timer (resets each cycle)
}
}
}
I don't recall how well I tested but the intended behavior is to change mode to whatever switch was down longer than the threshold time. The problem testing it is not having the feedback of the LED like you do in the two-mode version. Maybe the LED could flash i+1 times (1 to 5) to tell you what mode was selected (and the flashing would tell you the command took as well).... Is the bank switching dependent on which switch is the long press? Sometimes holding pin zero will result in switching from 60 to 80. Pin 0 should call only one definitive bank. Pin 1 the same. The switching does not seem absolute based on pin held down
D1 is the CC message and D2 is it's parameter value. For on/off functions the convention is that D2<64 = OFF and >=64 is ON. I had assumed a common OFF and ON value would be enough but if you want these can be replaced by arrays. But now I'm not even sure you want toggling behaviour.Also can the array for CC contain D1 and D2 of the CC message? So instead of sending 60 127 and then 60 0 it will just always send 60 0? Or 60 1?
It seems the software I'm using accepts codes for CC this way. You declare which CC so say CC 0 and then it uses D2 to make the switching. So everything would be base CC 0 and unique codes would be set via D2 so it would be like this?
{0 1,0 2,0 3,0 4,0 5}
{0 6,0 7,0 8,0 9,0 10}
I thought it already works this way. That very test (togglereset<resetThreshold) is around the code that sends the CC.oh i want to figure out how to not send CC code after toggling. Just complete the bank integer storage but not send a cc code. only send cc code if togglereset<resetThreshold
[COLOR="#FF0000"]const byte ONvalue[][DIGITAL_PINS][/COLOR] = {
{65,66,67,68,69},
{127,127,127,127,127},
{127,127,127,127,127},
{127,127,127,127,127},
{127,127,127,127,127}
};
[COLOR="#FF0000"]const byte OFFvalue[][DIGITAL_PINS][/COLOR] = {
{65,66,67,68,69},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
};
...
const byte CC[][DIGITAL_PINS] = {
{0,0,0,0,0},
{65,66,67,68,69},
{70,71,72,73,74},
{75,76,77,78,79},
{80,81,82,83,84},
{85,86,87,88,89}
};
...
if(toggleReset<resetThreshold){
if (CCstate[i]){
usbMIDI.sendControlChange(CC[bank][i], ONvalue[COLOR="#FF0000"][bank][i][/COLOR], channel);
}else{
usbMIDI.sendControlChange(CC[bank][i], OFFvalue[COLOR="#FF0000"][bank][i][/COLOR], channel);
}
CCstate[i] = !CCstate[i] ; //toggle state memory
timerOn = false ; //turn off timer (resets each cycle)
}
Nearly...So if btn rising edge && togglereset>resetThreshold. ?
Nearly...
if (digitalRead[PINS]=LOW && togglereset>resetThreshold){...}
or something like that... I'm saying don't worry about the BOUNCE edges as they are long ago by the time the code gets here but the pin reading itself will be stable and so BOUNCE is not needed either.
I need a compiler to stop me from including nonsense so if you can you may want to wait until I can give you working code.
(EDIT - reading the pin may be something we shouldn't do every pass of the code since we don't have to and so it might be better to test the threshold first and only read the pin if we're in the long-hold already).
Nearly...
if (digitalRead[PINS]=LOW && togglereset>resetThreshold){...}
or something like that... I'm saying don't worry about the BOUNCE edges as they are long ago by the time the code gets here but the pin reading itself will be stable and so BOUNCE is not needed either.
I need a compiler to stop me from including nonsense so if you can you may want to wait until I can give you working code.
(EDIT - reading the pin may be something we shouldn't do every pass of the code since we don't have to and so it might be better to test the threshold first and only read the pin if we're in the long-hold already).
so in theory you could also set that time to be the switching time for int FxMode
that way if FxMode=1 send CC if FxMode = 0 send CC 0 Value. the array can stay the same even for the banks. Its simply switching the order of the code for constant vs bank variable