1

Let's say we have two buttons - button 1 and button 2. What I need to do is to do something (like turn LED on) when button 1 is press, then button 2 is pressed. I can do it realy simple by just using two boolean variables, but how can we tell button 1 was the first pressed button?

  • Look up what a "finite state machine" is. Use interrupts or digitalRead to check status of the buttons. – MichaelT May 18 at 10:55
2

A nice solution is to use a state variable. In C/C++ (thus Arduino) you can use an enum variable for that.

enum EState
{
  // Button 1 and 2 are not pressed
  NoButtonsPressed,

  // Button 1 is pressed, button 2 is not pressed
  FirstButtonPressed,

  // Both buttons are pressed
  BothButtonsPressed
};

EState _state;


void setup() {
  // put your setup code here, to run once:
  _state = NoButtonsPressed;
}

void loop() {
  // put your main code here, to run repeatedly:
  switch (_state)
  {
  case NoButtonsPressed:
    if (digitalRead(1) == HIGH)
    {
      _state = FirstButtonPressed;
    }
    break;

  case FirstButtonPressed:
    if (digitalRead(1) == HIGH)
    {
      // Button 1 is still pressed, ignore second button.
    } 
    else if (digitalRead(2) == HIGH)
    {
      // Button 1 is not pressed, button 2 is pressed.
      _state = BothButtonsPressed;
    }
    break;

 case BothButtonsPressed:
   // Switch on LED
   digitalWrite(2, HIGH);

   // Reset state.
   _state = NoButtonsPressed;
   break;

 default:
   // Other state, illegal.
   break;
  }
}

In every state you can define exactly what needs to be done. Because of the loop function being ran continuously, you just need to handle one state (change) at a time.

Additional notes:

  • Your requirements are not fully complete (like when to switch off the LED), probably when button 2 is released (which I don't check for), you can add a new state for this.
  • I did not take debouncing of buttons into account; you might need to do this especially if you check for releasing buttons. On the official Arduino website there is a good article about it.
  • I haven't tested the sketch.
  • Thank you! This solution is great! :) – Svetoslav Nedelchev May 17 at 9:11
  • Nice clean answer. (Voted) – Duncan C May 17 at 13:07
  • 1
    It looks like this code should not have button bounce problems because it ignores button presses unless it's in the state waiting for that button press, and then it advances to a new state where it will ignore that button press and wait for the next one. As you say, if you get more elaborate, like responding to button releases, it will need debouncing. – Duncan C May 17 at 13:07
  • @DuncanC Thanks for the upvote and comment. In the example above debouncing is not strictly needed, although I can imagine the user wants to have the LED off after the second button has been released, without debouncing, the LED will stay on a ms or less after the second button has been pressed because the second button will be pressed (LED on) and bounces back (switching off the LED). If the requirements are that the LED should be on until the first button is pressed, than debouncing is not strictly needed. – Michel Keijzers May 17 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.