Need to make button presses in a specific order

I have been working on a project, the goal of which is to make a circuit that requires 2 switches to both be switched on (SW1 and SW2) after which 2 buttons (BUTN1 and BUTN2) need to be pressed in that order. I need the TOOL pin to switch to LOW when any of the conditions is no longer met, and only switch to HIGH when the conditions are met in that exact order.

So far, the program works fine except it also works if you press the buttons in the opposite order. Code and diagram of the circuit are below.

Any help would be appreciated, thanks!

const int TOOL = 9;
const int SW1 = 8;
const int SW2 = 10;
const int BUTN1 = 11;
const int BUTN2 = 12;

void setup()
{
  pinMode(TOOL,OUTPUT);
  pinMode(SW1,INPUT);
  pinMode(SW2,INPUT);
  pinMode(BUTN1,INPUT);
  pinMode(BUTN2,INPUT);
}

void loop()
{
  if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH)
  {
    if (digitalRead(BUTN2) == HIGH)
    {
      digitalWrite(TOOL, HIGH);
    }
    else
    {
      digitalWrite(TOOL, LOW);
    }
  }
  else
  {
    digitalWrite(TOOL, LOW);
  }
}

|469x500

How do you (don't worry about the Arduino, yet) define "the proper order"?

Does it not involve time? You need to record when the switches BECOME pressed. When a switch IS pressed is almost irrelevant. See the state change detection example.

You need two times - one for each switch. Then, you can compare the times to see which switch was pressed first.

nps130: I need the TOOL pin to switch to LOW when any of the conditions is no longer met,

In addition to what @PaulS has said, you need to explain how "is no longer met" is defined - in other words, what logic makes the system go back to its original state.

As an alternative to measuring the time when the buttons are pressed you could have a variable that records whether BUTN1 is pressed and if it is NOT pressed you would ignore any action on BUTN2.

And in similar style you could precede the button logic with another variable that records whether the switches are both ON - ignore the BUTN action if the two switches are not ON.

I was trying to outline how the code might work, but I can't without knowing what should happen if the wrong thing is done. For example if pressing in the order 2 1 is wrong is 2 1 2 acceptable? Or should the wrong order cause the system to lock-out for a period.

...R

How do you (don't worry about the Arduino, yet) define "the proper order"?

The proper order is:

Assuming both slider switches are on to begin with, BUTN1 is pressed, for an arbitrary amount of time, and then BUTN2 is pressed while BUTN1 is held down. The system is acting as a deadman switch so if either is released, the system shuts down, but will only start if they are pressed in that order.

if pressing in the order 2 1 is wrong is 2 1 2 acceptable? Or should the wrong order cause the system to lock-out for a period.

2 1 is wrong obviously, but 2 1 2 would be ok as long as the 1 was held down as 2 is pressed for the second time and held down as well (deadman switch). The wrong order would not need to lock out but rather make the user start the sequence again.

Using the code I linked in the OP, it works like i want it to, but the order of presses is not a factor. I was trying to do something along the lines of button states, but as I'm new to this, was having trouble working out the details.

Hope this explains what I meant better, thank you for your responses

So, the order is not really important. You would simply not read the state of switch 2 unless switch 1 is pressed.

So, the order is not really important. You would simply not read the state of switch 2 unless switch 1 is pressed.

@PaulS, that is correct, I really only want the program to check the status of button 2 if button 1 is pressed and held. I tried to do this by putting the if statement concerning button 2 inside the if statement for button 1, but it isn't working the way I expected.

It seems like you just want something to work ONLY when all 4 switches are on.

Why not something like

void loop() {
   readSwitches();
   switchTotal = sw1State + sw2State + btn1State + btn2State;
   if (switchTotal == 4) {
      // do stuff
   }
}

However you must be careful to ensure that the "stuff" is non-blocking so that loop() repeats frequently and checks the switches.

...R

@Robin2: all 4 need to be switched to satisfy the requirements, but I want the order of buttons to be 1 then 2, that is the part I am having trouble getting done. I don't care which order the sliders were switched in though.

This was the code I had initially, before I decided to try to get the order of presses as part of the equation.

void loop()
{
  if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == HIGH)
  {
    digitalWrite(TOOL, HIGH);
  }
  else
  {
    digitalWrite(TOOL, LOW);
  }
}

Something like this maybe: ( I left the switches out but that should be trivial to put back in)

boolean halfwayThere = false;
byte button1 = 2;
byte button2 = 3;

void setup(){
  // do your pinModes and stuff
}


void loop(){
  
  if(!halfwayThere){
    if(digitalRead(button1) && !digitalRead(button2)){
      halfwayThere = true;
    }
  }
  else {
    if(!digitalRead(button1)){
      halfwayThere = false;  // let go of button1 cancel
    }
    if(halfwayThere && digitalRead(button2)){
      // button2 was pressed after button1
      // do your thing
    }
  }
}

Try adding states so that you will only look at button 2 if the two switches plus button 2 are HIGH and button 2 is LOW.

// states
const int OFF = 0;
const int READY = 1;
const int ON = 2;

int toolState = OFF;  // current state

void loop()
{

  switch( toolState )
  {

  case OFF:

    // if two switches plus button 1 only
    if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == LOW)
    {
      // ready for button 2 to be pressed
      toolState = READY;

    } // if

    break;

  case READY:

    // if tow switches pluse button 1 plus button 2 
    if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == HIGH)
    {

      // turn on, set state
      digitalWrite(TOOL, HIGH);
      toolState = ON;

    } 
    else {

      // no longer ready
      toolState = OFF;

    } // else


    break;

  case ON:

    // if tool should be off
    if (!(digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == HIGH) )
    {

      // turn off, set state
      digitalWrite(TOOL, LOW);
      toolState = OFF;

    } // if

    break;

  default:
    break;

  } // switch

}

Thanks all for your help.

@Blue Eyes: I was able to get your suggestion to work, but it seems inconsistent when I press the buttons. I will continue tweaking it but it seems to get a bit temperamental unless I try pushing button 1 and 2 a few times. I linked all the code, but I think it's not resetting for some reason when I release buttons in the wrong order or something.

One general question though. In the setup part at the top, what is the 0, 1, and 2 for OFF, READY, and ON? It doesn't seem to come back up in the code itself.

const int TOOL = 9;
const int SW1 = 8;
const int SW2 = 10;
const int BUTN1 = 11;
const int BUTN2 = 12;
const int OFF = 0;
const int READY = 1;
const int ON = 2;
int TOOLstate = OFF;

void setup()
{
  pinMode(TOOL,OUTPUT);
  pinMode(SW1,INPUT);
  pinMode(SW2,INPUT);
  pinMode(BUTN1,INPUT);
  pinMode(BUTN2,INPUT);
}
void loop()
{
  switch(TOOLstate)
  {
    case OFF:
      if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == LOW)
      {
        TOOLstate = READY;
      }
      break;
    case READY:
      if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == HIGH)
      {
        digitalWrite(TOOL, HIGH);
        TOOLstate = ON;
      }
    else
      {
        TOOLstate = OFF;
      }
      break;
    case ON:
      if (!(digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH && digitalRead(BUTN2) == HIGH))
      {
        digitalWrite(TOOL, LOW);
        TOOLstate = OFF;
      }
      break;

      default:
      break;
  }
}

nps130: One general question though. In the setup part at the top, what is the 0, 1, and 2 for OFF, READY, and ON? It doesn't seem to come back up in the code itself.

He's just giving names to those numbers. If he had the states labeled 0, 1, and 2 you might wonder which was which. By calling them ON, and OFF and READY there is little doubt which state is which. It just makes the code more readable.

Cool, thanks for clarifying

nps130: @Robin2: all 4 need to be switched to satisfy the requirements, but I want the order of buttons to be 1 then 2, that is the part I am having trouble getting done.

Dare I ask WHY?

If the system is intended to stop if any switch becomes OFF and if the start process is not locked out if the wrong button order arises I can't see any value in requiring the switches to be pressed in any particular order.

It would be different if you required an interval between the presses, for example.

Having said that it would be easy to ensure that button2 is only read if button1 is alredy ON. HOWEVER that does not rule out the chance that button1 is released immediately after button2 is pressed. What should happen then?

I really think that you need either to simplify the logic (as in my earlier Reply) or make it significantly more complex.

...R

I was thinking that you may want to add a delay immediately after setting the state to READY in order to give the person time to click button 2, since all four states are checked in only one pass of loop().

Of course, this adds another condition - that button 2 has to be clicked in a given amount of time after clicking button 1 with the two switches on and if not button 1 has to be released then clicked again.

Robin2:
Having said that it would be easy to ensure that button2 is only read if button1 is alredy ON.
HOWEVER that does not rule out the chance that button1 is released immediately after button2 is pressed. What should happen then?

It also doesn’t rule out the possibility that button 2 had been pressed the whole time while we were waiting for the press of button 1 violating the OPs requirement that button 2 not be pressed before button 1.

Delta_G: It also doesn't rule out the possibility that button 2 had been pressed the whole time while we were waiting for the press of button 1 violating the OPs requirement that button 2 not be pressed before button 1.

Indeed.

And when you take Replies 13, 14 and 15 together I hope the OP can see why I suggested that more complex logic OR simpler logic seems to be indicated.

...R

nps130: I have been working on a project, the goal of which is to make a circuit that requires 2 switches to both be switched on (SW1 and SW2) after which 2 buttons (BUTN1 and BUTN2) need to be pressed in that order. I need the TOOL pin to switch to LOW when any of the conditions is no longer met, and only switch to HIGH when the conditions are met in that exact order.

So far, the program works fine except it also works if you press the buttons in the opposite order. Code and diagram of the circuit are below.

Any help would be appreciated, thanks!

const int TOOL = 9;
const int SW1 = 8;
const int SW2 = 10;
const int BUTN1 = 11;
const int BUTN2 = 12;

void setup() {   pinMode(TOOL,OUTPUT);   pinMode(SW1,INPUT);   pinMode(SW2,INPUT);   pinMode(BUTN1,INPUT);   pinMode(BUTN2,INPUT); }

void loop() {   if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH && digitalRead(BUTN1) == HIGH)   {     if (digitalRead(BUTN2) == HIGH)     {       digitalWrite(TOOL, HIGH);     }     else     {       digitalWrite(TOOL, LOW);     }   }   else   {     digitalWrite(TOOL, LOW);   } }




![|469x500](http://i.imgur.com/RA6vrzu.jpg)

requires 2 switches to both be switched on (SW1 and SW2) after which 2 buttons (BUTN1 and BUTN2) need to be pressed in that order.

YOU need to take control of the sequence and NOT work around the obstacle called "loop()".

Obviously you HAVE to wait for all the conditions to be met ( not doing anything else !), so letting the loop and if(s() to run just because everybody else does that makes no sense.

Here is pseudo code, hope you can add what is necessary in each while loop: ( ..and you could add safety timeouts later so it does not get stuck)

while( switch 1 and switch 2 not pressed ) just wait for both switches to operate both switches operated while( button 1 not pressed ) now wait for button 1 button 1 operated while(button1 and button2 not pressed ) now wait wait for both buttons to be pressed

launch the rocket

Doing it that way, if the guy pushes button 1 and then decides he's not quite ready to start and releases it, then the program is over and he doesn't get another chance to start the machine until the whole system is reset.

Delta_G: Doing it that way, if the guy pushes button 1 and then decides he's not quite ready to start and releases it, then the program is over and he doesn't get another chance to start the machine until the whole system is reset.

I disagree - the "and" will cover that, button 1 has to be pushed (again) and held with button 2 pushed , but it will not take care of the required sequence anymore in that case.

My suggestion covered the initial requirement so these ( and I am sure there are more ) "if this than that " codes need to be added. As long as "if" is replaced with "while" it will work.

while(button1 and button2 not pressed ) now wait wait for both buttons to be pressed