Hello everyone,
I transformed an old bass foot pedal keyboard from a old organ into a MIDI keyboard to be able to send MIDI notes to synth and other organ with 2 mode: Momentary and Latch mode. I have some strange behaviour with the latch mode.
I made a mix from these two links to code my program:
_ Arduino MIDI foot pedal
_ MIDI Foot pedal from ElectroniqueAmateur (sorry, it's in French)
Since the keyboard has 13 foot pedals, I used only 1 ATmega to realize the MIDI emitter with the following features:
_ 1 potentiometer for the volume of the MIDI note sent.
_ 2 buttons to be able to octave up or down the MIDI note sent
_ 1 button to choose the mode: momentary or latch mode.
All the buttons have schmitt latches to avoid bouncing issues.
About the latch mode: I tried to program it to follow this algorithm:
_ when Latch is ON, when you hit the C foot pedal, a C noteOn is sent. When you release the C foot pedal, the C note "hold" until
_ If you hit C foot pedal again. In this case, a C noteOff is sent (here a noteOn with 0 velocity).
_ If you hit any other foot pedal except the C foot pedal, the current "holding" note is turned off and a [new note] noteOn is sent.
The momentary mode is ok and works great but when in Latch mode, I encounter sometimes a stange behaviour: when I hit another note when a previous one was hold, the note is still on and I cannot turn it off even if I hit back the corresponding foot pedal. I have to turn the arduino off by removing the power...
Is there a problem in the way I coded the program? Or Do I have forget something to take into consideration for my approach that is a lot of If...Else statements?
Here is the code:
// ces pins de l'Arduino sont reliées aux 4 boutons-poussoir
// (apres passage par un cd40106, pour éviter les rebonds)
#define pinOctaveUp 17
#define pinOctaveDown 18
#define pinHold 16
int octave = 0; //valeur initiale par défaut de l'octave
int octaveDownReady = 1; //vrai quand le bouton n'est pas enfoncé
int octaveUpReady = 1; // vrai quand le bouton n'est pas enfoncé
int holdReady = 1; // utile pour le hold mode
int holdNew;
int holdingNote = 0;
int holdingNotelast = 0;
boolean boolHold = 0;
boolean C = 1;
boolean CS = 1;
boolean D = 1;
boolean DS = 1;
boolean E = 1;
boolean F = 1;
boolean FS = 1;
boolean G = 1;
boolean GS = 1;
boolean A = 1;
boolean AS = 1;
boolean B = 1;
boolean C2 = 1;
boolean Clast = 1;
boolean CSlast = 1;
boolean Dlast = 1;
boolean DSlast = 1;
boolean Elast = 1;
boolean Flast = 1;
boolean FSlast = 1;
boolean Glast = 1;
boolean GSlast = 1;
boolean Alast = 1;
boolean ASlast = 1;
boolean Blast = 1;
boolean C2last = 1;
int vol = 0;
void setup() {
Serial.begin(31250);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(13, INPUT);
pinMode(14, INPUT);
}
void loop() {
// faut-il changer d'octave?
if (digitalRead(pinOctaveDown)) // bouton octave down enfoncé
{
if ((octaveDownReady) && (octave > -2))
{
octaveDownReady = 0;
octave = octave - 1;
}
}
else // bouton octave down n'est pas enfoncé
{
octaveDownReady = 1;
}
if (digitalRead(pinOctaveUp)) // bouton octave up enfoncé
{
if ((octaveUpReady) && (octave < 2))
{
octaveUpReady = 0;
octave = octave + 1;
}
}
else // bouton octave up n'est pas enfoncé
{
octaveUpReady = 1;
}
//changer de mode ? hold ou released
holdNew = digitalRead(pinHold);
if (holdReady == 0 && holdNew == 1) // bouton octave down enfoncé
{
if (boolHold == 0)
{
//holdReady = 0;
boolHold = 1;
}
else
{
boolHold = 0;
}
}
holdReady = holdNew;
vol = analogRead(A5);
vol = map(vol, 0, 1023, 0, 127);
C = digitalRead(2);
D = digitalRead(3);// passe de pin4 à pin3
E = digitalRead(4);// passe de pin6 à pin4
FS = digitalRead(5);// passe de pin8 à pin5
GS = digitalRead(6);// passe de pin10 à pin6
AS = digitalRead(7);// passe de pin12 à pin7
C2 = digitalRead(8);// passe de pin14 à pin8
CS = digitalRead(13);// passe de pin3 à pin13
DS = digitalRead(12);// passe de pin5 à pin12
F = digitalRead(11);// passe de pin7 à pin11
G = digitalRead(10);// passe de pin9 à pin10
A = digitalRead(9);// passe de pin11 à pin9
B = digitalRead(14);// passe de pin13 à pin14
if(boolHold){
if(C != Clast) {
if(C == 0) {
holdingNote=36+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(CS != CSlast) {
if(CS == 0) {
holdingNote=37+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(D != Dlast) {
if(D == 0) {
holdingNote=38+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(DS != DSlast) {
if(DS == 0) {
holdingNote=39+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(E != Elast) {
if(E == 0) {
holdingNote=40+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(F != Flast) {
if(F == 0) {
holdingNote=41+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(FS != FSlast) {
if(FS == 0) {
holdingNote=42+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(G != Glast) {
if(G == 0) {
holdingNote=43+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(GS != GSlast) {
if(GS == 0) {
holdingNote=44+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(A != Alast) {
if(A == 0) {
holdingNote=45+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(AS != ASlast) {
if(AS == 0) {
holdingNote=46+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(B != Blast) {
if(B == 0) {
holdingNote=47+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
if(C2 != C2last) {
if(C2 == 0) {
holdingNote=48+12*octave;
if(holdingNotelast != holdingNote){
noteOn(0x90, holdingNotelast, 0x00);
noteOn(0x90, holdingNote, vol);
}
else {
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
}
}
}
holdingNotelast = holdingNote;
}
else
{
noteOn(0x90, holdingNote, 0x00);
holdingNote = 0;
if(C != Clast) {
if(C == 0) {
noteOn(0x90, 36+12*octave, vol);
}
else {
noteOn(0x90, 36+12*octave, 0x00);
}
}
if(CS != CSlast) {
if(CS == 0) {
noteOn(0x90, 37+12*octave, vol);
}
else {
noteOn(0x90, 37+12*octave, 0x00);
}
}
if(D != Dlast) {
if(D == 0) {
noteOn(0x90, 38+12*octave, vol);
}
else {
noteOn(0x90, 38+12*octave, 0x00);
}
}
if(DS != DSlast) {
if(DS == 0) {
noteOn(0x90, 39+12*octave, vol);
}
else {
noteOn(0x90,39+12*octave, 0x00);
}
}
if(E != Elast) {
if(E == 0) {
noteOn(0x90, 40+12*octave, vol);
}
else {
noteOn(0x90, 40+12*octave, 0x00);
}
}
if(F != Flast) {
if(F == 0) {
noteOn(0x90, 41+12*octave, vol);
}
else {
noteOn(0x90, 41+12*octave, 0x00);
}
}
if(FS != FSlast) {
if(FS == 0) {
noteOn(0x90, 42+12*octave, vol);
}
else {
noteOn(0x90, 42+12*octave, 0x00);
}
}
if(G != Glast) {
if(G == 0) {
noteOn(0x90, 43+12*octave, vol);
}
else {
noteOn(0x90, 43+12*octave, 0x00);
}
}
if(GS != GSlast) {
if(GS == 0) {
noteOn(0x90, 44+12*octave, vol);
}
else {
noteOn(0x90, 44+12*octave, 0x00);
}
}
if(A != Alast) {
if(A == 0) {
noteOn(0x90, 45+12*octave, vol);
}
else {
noteOn(0x90, 45+12*octave, 0x00);
}
}
if(AS != ASlast) {
if(AS == 0) {
noteOn(0x90, 46+12*octave, vol);
}
else {
noteOn(0x90, 46+12*octave, 0x00);
}
}
if(B != Blast) {
if(B == 0) {
noteOn(0x90, 47+12*octave, vol);
}
else {
noteOn(0x90, 47+12*octave, 0x00);
}
}
if(C2 != C2last) {
if(C2 == 0) {
noteOn(0x90, 48+12*octave, vol);
}
else {
noteOn(0x90, 48+12*octave, 0x00);
}
}
}
Clast = C;
CSlast = CS;
Dlast = D;
DSlast = DS;
Elast = E;
Flast = F;
FSlast = FS;
Glast = G;
GSlast = GS;
Alast = A;
ASlast = AS;
Blast = B;
C2last = C2;
delay(50);
}
void noteOn(byte cmd, byte data1, byte data2) {
Serial.write(cmd);
Serial.write(data1);
Serial.write(data2);
delay(10);
}
Thank you by advance for your consideration about my code issues!