I need to send one message per button press

sorry for all the questions lately!

i am getting real close to getting this controller to work properly.
the new issue is:
i am trying to send a midi note on then off (like a key on a keyboard) with a momentary switch.
i can not figure out a way to get it to only send one message out when i press the button.

when i press the button it sends out a ton of on messages, then when i release it sends an infinite amount of off messages.
i have searched and tried everything i could think of with no luck. i know it must be something simple i am missing.

here is the complete code: (the part with the midi note is boxed in with a row of $$$$$$$$$$ to make it easier to find.

/*
#define xLow  15
#define xHigh 17
#define yLow  16
#define yHigh 14
*/
//modified to match my sparkfun connector
#define xLow  15
#define xHigh 17
#define yLow  16
#define yHigh 14
#define midiChannel 1


const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int samplePin = 10;

 int touchX, touchY;
 int lastTouchX, lastTouchY;
 int pin1 = 1;
 int sampleState = 0;

 //--------------------------------------------
 int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
//------------------------------------------------

 
void setup(){
 //  Setup serial / MIDI
    Serial.begin(31250);       // MIDI speed
 //  Serial.begin(9600);    // Debug speed
 
 
 //-------------------------------------
 // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
 pinMode(samplePin, INPUT);  
  //------------------------------------
 
}
 
void loop(){
 touchScan();
 touchOut(); 
   delay(0);

//$$$$$$$$$$$$$$$$$$$$$$$$$$$$

     [glow]sampleState = digitalRead(samplePin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (sampleState == HIGH) {     
    noteOn(0x90, 66, 0x40);

  } 
  else {
    // SEND A MIDI OFF NOTE
    noteOn(0x80, 66, 0x40);
 
  }[/glow]
 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 

   
//---------------------------------------
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter, DEC);
    }
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off");
    }

    // save the current state as the last state,
    //for next time through the loop
    lastButtonState = buttonState;
  }
  
  // sends a midi CC message of 0 or 127
  // checking the modulo of the button push counter.
  // the modulo function gives you the remainder of
  // the division of two numbers:
  if (buttonPushCounter % 2 == 0) {
  sendCC(95, char(127));  // send CC message 95
}
 else {
  sendCC(95, char(0));  // send CC message 95
}
  

//++++++++++++++++++++++
if (analogRead(14) > 2)
{
  sendCC(22, char(127));  // send CC message 22
}

if (analogRead(14) < 1)
{
  sendCC(22, char(0));  // send CC message 22
}

//++++++++++++++++++++++






//++++++++++++++++++++++++++ 
}

void touchOut()
{
   if(touchX > 0 && touchY > 0)
   {
        if(touchX > lastTouchX + 1 || touchX < lastTouchX - 1) //the 1 can be any whole number step
       {
         sendCC(20, char(touchX));  // send CC message 20
             lastTouchX = touchX;
       }

        if(touchY > lastTouchY + 1 || touchY < lastTouchY - 1)
        {
            sendCC(21, char(touchY));  // send CC message 21
           lastTouchY = touchY;
        }

 
   
   }
   }

//------------------------------------------------
   void noteOn(byte cmd, byte data1, byte  data2) {
   Serial.print(cmd, BYTE);
   Serial.print(data1, BYTE);
   Serial.print(data2, BYTE);
 }


//---------------------------------------
//  sends a CC message
void sendCC(char control, char data) {
  int cmd;
  cmd = 0xB0 | midiChannel;  // merge channel number
  Serial.print(cmd, BYTE);
  Serial.print((control & 0x7F), BYTE);
  Serial.print((data & 0x7F), BYTE);  // use the 0x7F to restrict the data to a maximum of 127
}

void touchScan(){
   pinMode(xLow,OUTPUT);
  pinMode(xHigh,OUTPUT);
  digitalWrite(xLow,LOW);
  digitalWrite(xHigh,HIGH);
 
  digitalWrite(yLow,LOW);
  digitalWrite(yHigh,LOW);
 
  pinMode(yLow,INPUT);
  pinMode(yHigh,INPUT);
  delay(0);
 
  //xLow has analog port -14 !!
  touchX=analogRead(yLow -14);
  
  touchX = map(touchX , 0, 1023, -15, 159); //set size from 0 to 127

 
  pinMode(yLow,OUTPUT);
  pinMode(yHigh,OUTPUT);
  digitalWrite(yLow,LOW);
  digitalWrite(yHigh,HIGH);
 
  digitalWrite(xLow,LOW);
  digitalWrite(xHigh,LOW);
 
  pinMode(xLow,INPUT);
  pinMode(xHigh,INPUT);
  delay(0);
 
  //xLow has analog port -14 !!
  touchY=analogRead(xLow - 14); 

  touchY = map(touchY , 0, 1023, -15, 162); //set size from 0 to 127
  
}

The thing to remember is that "loop" will execute many times in the time that the switch contact is made, so you need to only send your message when the input transitions from LOW to HIGH, and not just when the pin is HIGH.

To do this, you obviously need to know the state of the pin last time you looked at it, so you need a variable that save this value, and is upated each time through "loop".

hmmm yeah that makes sense, do you happen to know of a clear example of a situation like that i can look at?

This is how I would've done it:
http://www.arduino.cc/playground/Code/Button

#include <Button.h>
/*
create a Button object at pin 12
connect button between pin 12 and GND
*/
Button button = Button(12,PULLUP);
 
void setup(){
  Serial.begin(9600);
}
 
void loop(){
  if(button.uniquePress()){
    Serial.println("A message that will be sendt only when the button changes state to 'pressed'");
  }
}

:slight_smile:

ah ha!
shoot i need to check out the playground more.

thanks for the example!

Another thing that anyone checking this tread might be fighting with is the question of switch bounce. There are many discussions of this in other threads, just search on "switch bounce".