Firing a single midi message from button presses

Hi there, I'm a pretty inexperienced programmer and am looking for some steering to get my project going.

My project is a midi button box which will send 4 specific midi messages out through a midi port from button presses. I've coded the device a few times with varying success but have some issues and can't quite get the box to do what I need it to.

I have 2 coded versions. One which sends loads of messages looping for as long as the button is held down which isn't acceptable, the second which only sends one message but I need to add debounce to it as it's unstable and I can't quite figure out how to do it.

can anyone help me? I'm so close but just need to add the last addition to make the box stable.. the box is to control a show control system which needs to be stable so that multiple midi outputs don't accidentally trigger more than one sound effect..

Thanks in advance!

Qbox_Remote_V1_updated.ino (3.35 KB)

Try Arduino Playground - Bounce

Yeah I gave that a try but kept getting into trouble. I'm not really sure how to apply the bounce stuff to my program :slight_smile:

Cheers
Andy

Here's the code in my current project:

Maybe someone could put me in the right direction of how to adapt it with the bounce library..

/*
Midi button controller

8 Buttons send 8 different midi messages on CH0

Created March 2012
by Andrew Kirkby <http://www.kirkbysound.co.uk>
*/

//Constants to set pin numbers

const int buttonPin1 = 2;  //pushbutton 1
const int buttonPin2 = 3;  //pushbutton 2
const int buttonPin3 = 4;  //pushbutton 3
const int buttonPin4 = 5;  //pushbutton 4
const int ledPin = 6; //setup string ledPin as output 6
//const int ledPin1 = 7; //setup string ledPin1 as output 7

int buttonState1 = 0;   // Set variable for reading button status
int buttonState2 = 0;   // Set variable for reading button status
int buttonState3 = 0;   // Set variable for reading button status
int buttonState4 = 0;   // Set variable for reading button status

int val1;  //variables for checking button status
int val2;
int val3;
int val4;



// ########################################################################


void setup() {
  // put your setup code here, to run once:
  

pinMode(ledPin, OUTPUT);
//pinMode(ledPin1, OUTPUT);

Serial.begin(31250); // Set Midi Baud Rate

// Initialize buttons as inputs
pinMode (buttonPin1, INPUT);
pinMode (buttonPin2, INPUT);
pinMode (buttonPin3, INPUT);
pinMode (buttonPin4, INPUT);
digitalWrite(ledPin, LOW);

long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers


  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);

}


// ########################################################################

void loop() {
  // put your main code here, to run repeatedly: 


  //midimsg(0x90,0x1E,0x45);
              
  val1 = digitalRead(buttonPin1);      // read input value and store it in val
  val2 = digitalRead(buttonPin2);
  val3 = digitalRead(buttonPin3);
  val4 = digitalRead(buttonPin4);
  
  
  if (val1 != buttonState1) {          // the button state has changed!
    if (val1 == HIGH) {                // check if the button is pressed
      midimsg(0x90,0x45,0x45);
    } else {                         // the button is -not- pressed...
      //digitalWrite(ledPin, LOW);
    }
  }

  if (val2 != buttonState2) {          // the button state has changed!
    if (val2 == HIGH) {                // check if the button is pressed
      midimsg(0x90,0x40,0x45);
    } else {                         // the button is -not- pressed...
      //digitalWrite(ledPin, LOW);
    }
  }

  if (val3 != buttonState3) {          // the button state has changed!
    if (val3 == HIGH) {                // check if the button is pressed
      midimsg(0x90,0x35,0x45);
    } else {                         // the button is -not- pressed...
      //digitalWrite(ledPin, LOW);
    }
  }

  if (val4 != buttonState4) {          // the button state has changed!
    if (val4 == HIGH) {                // check if the button is pressed
      midimsg(0x90,0x30,0x45);
    } else {                         // the button is -not- pressed...
      //digitalWrite(ledPin, LOW);
    }
  }






  buttonState1 = val1;
  buttonState2 = val2;
  buttonState3 = val3;
  buttonState4 = val4;
  
}


//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void midimsg(int M1, int M2, int M3) {

  Serial.write(M1);
  Serial.write(M2);
  Serial.write(M3);
  
}

Sun 6/10/2012 8:17 am. Hi! I was looking about for MIDI button boxes, and happened upon your project. I've been doing this for years and years (owenlabs.org/resume.htm) but of course with brutal assembly language, and one of the things I discovered along the way is I didn't have to debounce! IF there was enough delay in the loop. On most of my machines, this delay just occurred naturally. With your code I'd suggest trying

  1. Put a delay in loop(); try making it 2 seconds -- i.e. too long -- and see if bouncing stops. Then adjust. I'd put it right at the top of loop().

  2. Another thing which seems to be important is verify the buttons are OFF before trying to "see" another button press. With my matrix keyboards, I'd check all the inputs and make sure they were all inactive. That is, the loop() only checks at some "slow-enough" rate, determined by delay; one of those checking cycles has to see the button off, before seeing the button on again. In your case, you might do it button-by-button, I don't know. It'd be simplest with the code you've got, right after reading val1-val4 at the top of loop(), to go something like "if ( (val1==HIGH) || (val2==HIGH) || (val3==HIGH) || (val4==HIGH) ) goto LOOPAGAIN"; the LOOPAGAIN: label elsewhere in the code shouldn't skip the delay. Arduino may forbid gotos I dunno -- well actually they seem to be latter-day tolerant!

At the bottom of my resume is a wretched MIDI pedalboard I created ages ago which I assume, although I haven't checked recently, operates in this fashion. In 8048 assembler. ... I checked; it looks like I don't check for key-off in that code! Ah well those halcyon days. ... Oh I see! I was doing note on AND note off; you're just doing note-on. When I was doing both, that's a built-in "check for off"; what with the actual delay in the loop, and a bit of delay sending the MIDI message (note message ~= 1 millisecond?), it worked-out.

Anyway, I'm pretty sure -- I guesstimate -- a loop delay, and checking for off, will make things better.

-- jgo owenlabs.org