how can i check if a button was released?

Hello!

At first: i'm sorry for my bad english!

here is my problem:
I'm a newbie with arduino. At the moment I'm trying to implement the game "whac-a-mole" with arduino and processing.
the processing part already works really good with the mouse.

the arduino part:
i use 7 buttons, each button is a molehill. My problem is, that the loop is too fast - if i press the button for too long, than the programm thinks that i pressed it twice - any ideas how i can check if the button was pressed once or multiple times?

this is the source for checking the buttons (just for the first 3 buttons):

// choose the input pin (for a pushbutton)
int inPin_1 = 3;  
int inPin_2 = 4; 
int inPin_3 = 5;  

// variable for reading the pin status
int val_1 = 0; 
int val_2 = 0;  
int val_3 = 0; 

// variable to send state of the buttons to processing
int send = 0;

// button already pressed?
boolean buttonState = true;

// just for testing
int ledPin =13;

void setup() {
  // declare pushbutton as input
  pinMode(inPin_1, INPUT);  
  pinMode(inPin_2, INPUT);
  pinMode(inPin_3, INPUT);  
  pinMode(ledPin, OUTPUT); //testing
  Serial.begin(9600);      
}

void loop(){
  send=0;
  buttonpress();
}

void  buttonpress(){

// stay inside the loop till a button was pressed
    while(buttonState){

    // read input value
    val_1 = digitalRead(inPin_1); 
    val_2 = digitalRead(inPin_2); 
    val_3 = digitalRead(inPin_3); 


    if (val_1 == LOW) {
      buttonState=false;
      send_byte = send_byte | 1; 
      digitalWrite(ledPin, HIGH); //testing
      Serial.println("1"); //testing
      break;
    }
    if (val_2 == LOW) { 
      buttonState=false;
      send_byte = send_byte | 2; 
      digitalWrite(ledPin, HIGH); //testing
      Serial.println("2"); //testing
      break;
    } 
    if (val_3 == LOW) { 
      buttonState=false;
      send_byte = send_byte | 4; 
      digitalWrite(ledPin, HIGH); //testing
      Serial.println("3");
      break;
    } 
    else{
      digitalWrite(ledPin, LOW); 
    } 
  }
  printByte(send);
  delay(100);      
  buttonState=true;
}

thanks for answers,
selestra

Whenever your software gets two button presses where the user only thinks there is one press, the solution is a technique called "debouncing."

When you notice a button is pressed, look at the clock and check if the last time this button was pressed was very recently. If so, ignore the button. If not, record the current clock time for the button and proceed to control the software.

int pinButton = 3;
long whenButton = 0;
// ...
long now = millis();
if (digitalRead(pinButton) == LOW && (now-whenButton) < 200)
{
    whenButton = now;
    // do whatever you need to do
}

If you really need the user to lift the button clearly before accepting another press, then just "debounce" the release too. This is common in games, to avoid the player just leaving his mole-whacker blocking the hole.

int pinButton = 3;
long whenButton = 0;
long whenButtonReleased = 0;
// ...
long now = millis();
if (digitalRead(pinButton) == LOW && (now-whenButton) < 200) && whenButton > whenButtonReleased)
{
    whenButton = now;
    // do whatever you need to do
}
if (digitalRead(pinButton) == HIGH && (now-whenButtonReleased) < 200)
{
    whenButtonReleased = now;
}

You may also want to check if only ONE button is being pressed at a time... sneaky players always gaming the system.

hei,

thanks for your help halley!
I was a little busy the last days, so i tried it out today.

I used the first way - i think it's okay to give the player 300ms to release the button. if not, than he has a wrong turn.
but it was necessary to change the <200 to > 200.

at the "only one button thing": if the user presses more than one button at a time, my programm just takes the first of the buttons in the button list - the other one is ignored. f.e.: button 5 + button 1 = button 1;

so.. now the arduino part for this game is done.

many thanks!

Selestra

Glad you got it to work, and yes, I meant "greater than" instead of "less than." I was typing without thinking again.