nested if statements- how they work

This might be a dumb question, but something I haven't seen in my tutorials/books.

I don't fully understand nested if statements... for example, if I have two if statements (if 1),( if 2). Also, lets say (if 1) had a nested if statement (if 1-A). When the loop starts, does it stay within (if 1) and (if 1-A) until conditions cause it to go on and only then enters (if 2)?

Thanks

Write an example of your abstract question. Execution doesn't stay in an if statement. It hits the end of the if statement and runs the next statement unless it is else or else if.

Why not write a sketch and test the hypotheses?

Execution does't "stay" in if statements.

Execution "stays" in loops.

The reason I'm looking for clarification is that it SEEMS to be staying within my 'else' statement until done with execution of the full routine.

Here's my full loop, but it's just the first if else that needs to be looked at. The first if basically just starts my time reference and turns on my first pin (ch1) for operation in the else loop. I was getting some really goofy stuff, like my button was malfunctioning or something. I removed the button and occasionally the else sequence would start before I manually plugged the button lead into the breadboard. Eventually, I held a ground lead while plugging in the button lead and it seems to work 100% correct, so I'm assuming that galvanic skin response/voltage might be the culprit? I am hoping it's not my coding. :slight_smile: When I just touch the button lead to the board and remove it, it goes into the else and completes the else routine.

void loop() {
  
    digitalRead(buttonPin);
   
    if(digitalRead(buttonPin) == HIGH && trip == 0)
    {
          startTime = millis();   
          digitalWrite(ch1,HIGH);
          trip = 1;
    }
    else {
         if(digitalRead(buttonPin) == HIGH && trip ==1)
         {
        
          // My relay loop
           if (millis() - startTime >= ch1Dur)     //  ch1 operation
              {
              digitalWrite(ch1,LOW);
              digitalWrite(ch1Led,HIGH);           // ch1 LED ON
              } 
  
  
              // ch2 operation
            if (millis() - startTime >= ch2GapDur  && millis() - startTime <= ch2GapDur + ch2Dur)   
               {digitalWrite(ch2,HIGH);}
            else 
              { 
              digitalWrite(ch2,LOW);
              }  
          if (millis() - startTime >= ch2GapDur + ch2Dur)   // ch2 LED ON
              digitalWrite(ch2Led,HIGH); 
      
   
          // ch3 operation    
          if (millis() - startTime >= ch2GapDur + ch3GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch3Dur)   
             {digitalWrite(ch3,HIGH);}
          else 
            { 
            digitalWrite(ch3,LOW);
            }
      
          if (millis() - startTime >= ch2GapDur + ch3GapDur + ch3Dur)   // ch3 LED ON
            digitalWrite(ch3Led,HIGH); 
      
      
          // ch4 operation
          if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch4GapDur + ch4Dur)   
           {digitalWrite(ch4,HIGH);}
          else 
            { 
            digitalWrite(ch4,LOW);
            }
      
          if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch4Dur)   // ch4 LED ON
             digitalWrite(ch4Led,HIGH); 
      
      
          // ch5 operation
          if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur + ch5Dur  )   
             {digitalWrite(ch5,HIGH);}
          else 
            { 
            digitalWrite(ch5,LOW);
            }
      
          if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur + ch5Dur)   // ch5 LED ON
            digitalWrite(ch5Led,HIGH); 
          
    }      
  }
}
          if (millis() - startTime >= ch2GapDur + ch3GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch3Dur)   
             {digitalWrite(ch3,HIGH);}
          else 
            { 
            digitalWrite(ch3,LOW);
            }

It really helps to be consistent with the { and } placement. NOTHING follows the { on the same line. Nothing goes on the same line as the }. You got the else statement right, but not the if part.

Using Tools + Auto Format to fix that horrid indenting would help, too.

Finally, "The reason I'm looking for clarification is that it SEEMS to be staying within my 'else' statement" needs clarification. You have many else blocks. Which one is it executing?

How is you switch wired? Your description follows the classic floating pin problem.
Where is your setup() function? Are you using the internal pullup resistor? Or, do you have an external pullup or pulldown resistor?

Hit auto format in arduino IDE menu. Your code is hard to read without proper indentation:

void loop() {

  digitalRead(buttonPin);

  if(digitalRead(buttonPin) == HIGH && trip == 0)
  {
    startTime = millis();   
    digitalWrite(ch1,HIGH);
    trip = 1;
  }
  else 
  {
    if(digitalRead(buttonPin) == HIGH && trip ==1)
    {

      // My relay loop
      if (millis() - startTime >= ch1Dur)     //  ch1 operation
      {
        digitalWrite(ch1,LOW);
        digitalWrite(ch1Led,HIGH);           // ch1 LED ON
      } 


      // ch2 operation
      if (millis() - startTime >= ch2GapDur  && millis() - startTime <= ch2GapDur + ch2Dur)   
      {
        digitalWrite(ch2,HIGH);
      }
      else 
      { 
        digitalWrite(ch2,LOW);
      }  
      if (millis() - startTime >= ch2GapDur + ch2Dur)   // ch2 LED ON
        digitalWrite(ch2Led,HIGH); 


      // ch3 operation    
      if (millis() - startTime >= ch2GapDur + ch3GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch3Dur)   
      {
        digitalWrite(ch3,HIGH);
      }
      else 
      { 
        digitalWrite(ch3,LOW);
      }

      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch3Dur)   // ch3 LED ON
        digitalWrite(ch3Led,HIGH); 


      // ch4 operation
      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch4GapDur + ch4Dur)   
      {
        digitalWrite(ch4,HIGH);
      }
      else 
      { 
        digitalWrite(ch4,LOW);
      }

      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch4Dur)   // ch4 LED ON
        digitalWrite(ch4Led,HIGH); 


      // ch5 operation
      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur + ch5Dur  )   
      {
        digitalWrite(ch5,HIGH);
      }
      else 
      { 
        digitalWrite(ch5,LOW);
      }

      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur + ch5Dur)   // ch5 LED ON
        digitalWrite(ch5Led,HIGH); 

    }      
  }
}

Your code is a bit long with all the logic that you didn't explain what they are doing. Is it drawing some bar graph on an led column? Tell us what you intend your code to do, besides what it is currently doing.

If you are doing bar graph with leds, I recommend you to use arrays for anything more than 3 leds. You have 5? It saves tremendous amount of time and code to use arrays. But first, describe what you want your leds to do.

Cool, didn't know about auto format and haven't learned all the properness yet, thanks!
Here's the code again after formatting. My questions pertained to the very first if/else statement; the rest of the loop is within the first else statement and works as expected.

Liudr, this is for sequenced pyro explosions/gunshots in SFX film work. I will end up with many channels and I know that initially I am using longhand, but I'll convert it to better coding at some future date, my partner is ready to use this soon. Everything after the first if/else statement are the sequenced ignitions along with variable durations that each one stays on (for when they are using air mortars, etc. which have a longer 'unload' time)

I'm using a button on the internal pullup resistor for now, but may change that later....

Here's my full loop, but it's just the first if else that needs to be looked at. The first if basically just starts my time reference and turns on my first pin (ch1) for operation in the else loop. I was getting some really goofy stuff, like my button was malfunctioning or something. I removed the button and occasionally the else sequence would start before I manually plugged the button lead into the breadboard. Eventually, I held a ground lead while plugging in the button lead and it seems to work 100% correct, so I'm assuming that galvanic skin response/voltage might be the culprit? I am hoping it's not my coding. smiley When I just touch the button lead to the board and remove it, it goes into the else and completes the else routine.

void loop() {

  digitalRead(buttonPin);

  if(digitalRead(buttonPin) == HIGH && trip == 0)
  {
    startTime = millis();   
    digitalWrite(ch1,HIGH);
    trip = 1;
  }
  else {
    if(digitalRead(buttonPin) == HIGH && trip ==1)
    {

      // My relay loop
      if (millis() - startTime >= ch1Dur)     //  ch1 operation
      {
        digitalWrite(ch1,LOW);
        digitalWrite(ch1Led,HIGH);           // ch1 LED ON
      } 


      // ch2 operation
      if (millis() - startTime >= ch2GapDur  && millis() - startTime <= ch2GapDur + ch2Dur)   
      {
        digitalWrite(ch2,HIGH);
      }
      else 
      { 
        digitalWrite(ch2,LOW);
      }  
      if (millis() - startTime >= ch2GapDur + ch2Dur)   // ch2 LED ON
        digitalWrite(ch2Led,HIGH); 


      // ch3 operation    
      if (millis() - startTime >= ch2GapDur + ch3GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch3Dur)   
      {
        digitalWrite(ch3,HIGH);
      }
      else 
      { 
        digitalWrite(ch3,LOW);
      }

      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch3Dur)   // ch3 LED ON
        digitalWrite(ch3Led,HIGH); 


      // ch4 operation
      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch4GapDur + ch4Dur)   
      {
        digitalWrite(ch4,HIGH);
      }
      else 
      { 
        digitalWrite(ch4,LOW);
      }

      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch4Dur)   // ch4 LED ON
        digitalWrite(ch4Led,HIGH); 


      // ch5 operation
      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur  && millis() - startTime <= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur + ch5Dur  )   
      {
        digitalWrite(ch5,HIGH);
      }
      else 
      { 
        digitalWrite(ch5,LOW);
      }

      if (millis() - startTime >= ch2GapDur + ch3GapDur + ch4GapDur + ch5GapDur + ch5Dur)   // ch5 LED ON
        digitalWrite(ch5Led,HIGH); 

    }      
  }
}
  if(digitalRead(buttonPin) == HIGH && trip == 0)
  {
    startTime = millis();   
    digitalWrite(ch1,HIGH);
    trip = 1;
  }
  else {
    if(digitalRead(buttonPin) == HIGH && trip ==1)

When subsequent if statements start the same way, it's a sure sign that nested ifs will be easier to understand.

You'll want to look at the state change detection example, too, so you trigger an action only when the switch BECOMES pressed, rather than when the switch IS pressed.

Notice that, as written, your code requires that the switch be held down for the entire duration of the trip == 1 part. I doubt that's be intent.

Look at state machines, too. When the switch becomes pressed, you want to go from one state (waiting for the switch to be pressed) to another state (doing the stuff that the switch should trigger). There are external events that cause state changes, such as the switch becoming pressed, and internal events, such as reaching the end of the sequence of activities that are to be performed in a given state. You need to be able to make the change happen correctly, regardless of its nature (external or internal).

You might need to consider a "Whoa, stop, emergency!" type state and a means to get into and out of that state. Seriously consider this.

Hey PaulS,

Notice that, as written, your code requires that the switch be held down for the entire duration of the trip == 1 part. I doubt that's be intent.

That is the part that I'm not understanding... ALL of my action code (other than initial settings) are WITHIN the first else statement. Does it ever escape that before my sequence is finished? The sequence, as written, takes about 8 or 10 seconds to complete. I can just quickly tap and remove the wire to the buttonPin, and the entire sequence will run. Within the else statement, my LEDs are turned on and left on, which is my intent. Once it completes the sequence, it can loop forever and be rejected by both the if and else parameters because it has already done its job.

ALL of my action code (other than initial settings) are WITHIN the first else statement.

Yes, but that requires that the switch be pressed.

I can just quickly tap and remove the wire to the buttonPin, and the entire sequence will run. Within the else statement, my LEDs are turned on and left on, which is my intent.

So, when the pin floats, you get lucky. Your luck may change.

Get a real switch. Wire it properly. Then, pay attention to the state change detection examples and learn about state machines.

Thanks Paul,
I'll keep studying...