Order of operations in an if statement

I am having trouble writing if statements in a specific order. I would like my tilt sensor to be in a specific state BEFORE a switch being in a specific state.

Specifically, I have a box and I want the box to only be able to be opened if you tilt the tilt sensor and then push the button after. If you push the button and then tilt the tilt sensor, the box should not open. So, order matters.

This is what I have tried so far:

if (tiltsensor == LOW) 
  if (pushbutton1 == HIGH)
   if (doorswitch == HIGH)
{ //
digitalWrite(3, LOW); // Yellow LED off
digitalWrite(4, LOW); // Magnet on
digitalWrite(5, HIGH); // Green LED off
digitalWrite(7, LOW); // Red LED on
}

&

if (tiltsensor == HIGH && (pushbutton1 == LOW && (doorswitch == LOW))) //Switchstate 3 will need to be high (pressed in)


{ //
digitalWrite(3, HIGH); //Yellow LED on
digitalWrite(4, HIGH); //Magnet on
digitalWrite(5, LOW); //Green LED off
digitalWrite(7, LOW); // Red LED off

The digitalWrites of the inputs are different, but the behavior is the same in that in both cases the board only analyzes if the combined set of inputs are in the proper state, I need it to do one and then the other.

Sorry if this has been posted before, but I couldnt find anything that helped me. Thank you in advance for the help!

There is nothing to keep meaningful track of (human relevant) time in either approach.

If you want to know when an event happens and compare that with the timing of another event, you need to timestamp the events, for example by recording the value of millis(), and compare timestamps.

Im basically brand new to arduino and have some experience with MATLAB so if I need to rethink the way Im trying to program this let me know, but is there not a way to say:

if (button1 == true)
and if (button2 ==true)
{ do something}

??

BTW I'm surprised this even compiles, but it does:

if (tiltsensor == LOW) 
  if (pushbutton1 == HIGH)
   if (doorswitch == HIGH)

Normally you would use braces:

if (tiltsensor == LOW)  {
  if (pushbutton1 == HIGH) {
   if (doorswitch == HIGH) {
    do_something();
    }
  }
}

But that is the same as

if (tiltsensor == LOW && pushbutton1 == HIGH &&
   doorswitch == HIGH) {
do_something();
}

Still no time element involved, except for the microsecond or so between digital input reads.

Furthermore, there is no inherent execution order (e.g. right to left) implied in C/C++ statements, except when evaluating mathematical expressions.

1 Like

Okay so if you don't mind, how would you personally add an execution order?

See reply #2, if I understand your question correctly.

Take a look at the State Change Detection example in the Arduino IDE to determine when a switch BECOMES closed, rather than whether it IS closed.

Okay, I will look into that and see if I can figure something out. Thank you!

In the Arduino IDE, File>Examples>02.Digital>StateChangeDetection.

BTW this code compiles with a warning, and runs, but gives an unexpected answer. Can you guess the answer? Lesson: use braces.

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
int x=1,y=2;
if (x == 2)
if (y == 2)
Serial.println("true");
else Serial.println("false");
}
void loop() {
  // put your main code here, to run repeatedly:

}

You can write a state machine using the switch-case statement. When you use millis around it you can ensure the state machine advances in a fixed interval.

Have a look at the following example

File -> Examples -> 02.Digital -> BlinkWithoutDelay

State machine example (not complete code) (Click to view)
#define STATE_MACHINE_INTERVAL 10

void loop()
{
  stateMachineFunction();

}

void stateMachineFunction( void )
{
  static uint16_t state = 0;
  static uint32_t previousMillis = 0;

// This makes it easier to keep track of the states when you read the code.
  enum STATE_TYPE { STATE_IDLE,
                    STATE_START,
                    ...
                    STATE_RESTART = 255
                  };

  uint32_t currentMillis = millis();
  if ( currentMillis - previousMillis > STATE_MACHINE_INTERVAL )
  {
    previousMillis = currentMillis;
    
    switch ( state )
    {
      case STATE_IDLE:
        if (  )
        {
          state++;
          break;
        }
      case STATE_START:
        if (  )
        {
          // do something
          
          state++;
          break;
        }
...
      default:
        state = 0;
        break;
    }
  }
}

Of course you can have a state where a longer time is needed to advance. Simply add a counter and advance only when the counter reaches a fixed value.

1 Like

Its about sequence.
The first conditions if tilt and only tilt has to be correct.

If tilt==low {condition1=0}
If sw==low {condition2=0}

If sw == low && door==low{
If tilt== high
Condition1=1
}

If condition1==1{
If door==low
If sw== high
Condition2=1
}

Is tiltsensor the pin number or the result of digitalReading it? Please post all your code rather than a snippet.

No surprise, perfectly valid syntax and for some fewer braces is not a bad thing.

Similarly

for (ii = 0; ii < 10; ii++)
    for (jj = 0; jj < 10; jj++)
        for (kk = 0; kk < 10; kk++)
            Serial.println(ii + jj + kk);

Perfectly valid syntax.

I usually don't use braces until I have to. Since I answer only to myself, it is I who will ever pay the price. I just like less clutter generally.

BTW!

a7

In regard to the "if" and similar statements, the braces simply denote a compound statement which is a group of statements to be performed as a unit, since "if" and similar statements have only one execution argument.

But that one argument can itself be another "if" statement with its own arguments.

You should understand what braces are for - not simply decoration but having a very specific function; they therefore should specifically not be used where that function is not intended.

That is also why braces cause a level of indentation.

int tiltsensor = 0;
int pushbutton1 = 0;
int doorswitch = 0;
//const int switchPin = 2;
void setup() {
  // put your setup code here, to run once:
pinMode(6, INPUT); // Tilt sensor
pinMode(3, OUTPUT); // Yellow LED
pinMode(4, OUTPUT); // Magnet
pinMode(5, OUTPUT); // Green LED
pinMode(2, INPUT); // Manual Switch
pinMode(7, OUTPUT); // Red LED
pinMode(8, INPUT); // Door Switch

}

void loop() {
  // put your main code here, to run repeatedly:
tiltsensor = digitalRead(6); //Read input from tilt sensor
pushbutton1 = digitalRead(2); //Read input from switch
doorswitch = digitalRead(8); //Read input from door switch

//Resting condition

if (tiltsensor == HIGH && (pushbutton1 == LOW && (doorswitch == LOW))) //Switchstate 3 will need to be high (pressed in)


{ //
digitalWrite(3, HIGH); //Yellow LED on
digitalWrite(4, HIGH); //Magnet on
digitalWrite(5, LOW); //Green LED off
digitalWrite(7, LOW); // Red LED off
}


//untilted, button not pushed, door open

else if (tiltsensor == HIGH && (pushbutton1 == LOW && (doorswitch == HIGH)))
{ //
digitalWrite(3, LOW); // Yellow LED off
digitalWrite(4, HIGH); // Magnet on
digitalWrite(5, LOW); // Green LED off
digitalWrite(7, HIGH); // Red LED on
}


//tilted, button not pushed, door open

else if (tiltsensor == LOW && (pushbutton1 == LOW && (doorswitch == HIGH)))
{ //
digitalWrite(3, LOW); // Yellow LED off
digitalWrite(4, HIGH); // Magnet on
digitalWrite(5, LOW); // Green LED off
digitalWrite(7, HIGH); // Red LED on
}


//untilted, button pushed, door open, alarm

else if (tiltsensor == HIGH && (pushbutton1 == HIGH && (doorswitch == HIGH)))
{ //
digitalWrite(3, LOW); // Yellow LED off
digitalWrite(4, HIGH); // Magnet on
digitalWrite(5, LOW); // Green LED off
digitalWrite(7, HIGH); // Red LED on
}


else if (tiltsensor == LOW && (pushbutton1 == HIGH && (doorswitch == HIGH)))
{ //
digitalWrite(3, LOW); // Yellow LED off
digitalWrite(4, LOW); // Magnet off
digitalWrite(5, HIGH); // Green LED on
digitalWrite(7, LOW); // Red LED off
}
}

Just curious: did you manage to correctly guess the result of the program posted in reply #8?

What result? :wink:

a7

Presumably prints both "true" and "false" since the second "if" is indeed true, completing that "if" and the first false, completing the first.

Something about the semicolons ...

So, the answer is no, for both of you.

The program prints "true".

Well, no, it doesn't… not in my corner of the universe.

Perhaps cutting and pasting is somehow broken.

Here's your own code with but one extra line, as carefully as I could.

Now it's your turn guess the result…

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
int x=1,y=2;
if (x == 2)
if (y == 2)
Serial.println("true");
else Serial.println("false");

Serial.println("no it don't");
}
void loop() {
  // put your main code here, to run repeatedly:

}

???

x does not equal 2, so the execution argument of the first "if" is skipped. The execution argument of the first "if" is the if-else statement, y == 2 is never tested.

What I saw, what I thought, what I confirmed on the Arduino (after having done using an online C interpreter).

a7

I'm comfortable with the braces, but thanks anyway.

The OP is facing a different problem.