I concur with Majenko, although your code would work, the code is blocking, meaning that your code stops at that point until the button is released again. The remaining code in your loop does not execute until the button is resolved.
A much better method is to check the state of the button in each passing of the loop. If the state changes (ie goes low) you can set a flag. Then when you read that the button is high again and the flag has been set then you execute the appropriate code. For example:
const int buttonPin = 2; // the number of the pushbutton pin
boolean buttonWasLow = false; // variable flag for when the pushbutton goes low
void setup() {
pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input:
}
void loop() {
// read the state of the pushbutton and set a flag if it is low:
if (digitalRead(buttonPin) == LOW) {
buttonWasLow = true;
}
// This if statement will only fire on the rising edge of the button input
if (digitalRead(buttonPin) == HIGH && buttonWasLow) {
// reset the button low flag
buttonWasLow = false;
// Button event here
}
}
My favorite way to detect a rising edge of an input is actually much simpler:
void loop() {
button = digitalRead(buttonPin);
// If the button is pressed
if (button && !buttonLast)
{
// Button event here
}
// Update button flag
buttonLast = button;
}
user8886193 brings up the very good point about button debounce.
Bouncing is the tendency of any two metal contacts in an electronic device to generate multiple signals as the contacts close or open; debouncing is any kind of hardware device or software that ensures that only a single signal will be acted upon for a single opening or closing of a contact.
I prefer to debounce the pushbutton inputs through hardware by adding a 100nF (or larger) from the input pin to ground. Note that this requires a 10K (or larger) resistance in series with the button circuit in order for the capacitor to charge/discharge.
Alternatively, in software, the most common debounce for beginners is adding a delay such as delay(100);
, which would look something like this:
void loop() {
button = digitalRead(buttonPin);
// If the button is pressed
if (button && !buttonLast)
{
// Button event here
delay(100); // <---- Delay inserted after the button event
}
// Update button flag
buttonLast = button;
}
This has the downside that it is blocking for 100ms while the delay executes. A better method is to debounce without a delay. One of the built in examples demonstrates button debounce. The main loop is shown below:
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// set the LED:
digitalWrite(ledPin, ledState);
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastButtonState = reading;
}