Adding a 3 second input delay, using 'delay' lesson for me.

I'm trying to watch a switch input, and not respond unless the input persists for over 2 seconds, etc. My code is as follows, but what I'm curious about is why after a delay(2000) my code immediately proceeds to the next command. I have tried 5 or 8 seconds, there is no delay. My delay(xxxx) is Not pausing the execution.

What am I missing?

void loop()
{
      if (digitalRead(8) == LOW)  // Switch is closed -- Normal position
          digitalWrite(12, HIGH), digitalWrite(13, LOW);  
      else                        // Switch Opened
        if (digitalRead(8) == HIGH)  // Test for immediate open loop
        delay(2000);  // Pause to test persistance
        if (digitalRead(8) == HIGH)  // Switch must still be open, continue
        digitalWrite(13, HIGH), digitalWrite(12, LOW), doStuff();
}

Any suggestions appreciated.

digitalWrite(12, HIGH),

I've never seen a comma used like that before.

You shouldn't use commas to group statements. Use curly braces:

void loop()
{
    if (digitalRead(8) == LOW) {  // Switch is closed -- Normal position
        digitalWrite(12, HIGH);
        digitalWrite(13, LOW);
    }
    else {                        // Switch Opened
        if (digitalRead(8) == HIGH)  // Test for immediate open loop
            delay(2000);  // Pause to test persistance
    }

    if (digitalRead(8) == HIGH) {  // Switch must still be open, continue
        digitalWrite(13, HIGH);
        digitalWrite(12, LOW);
        doStuff();
    }
}

Ashton: I'm trying to watch a switch input, and not respond unless the input persists for over 2 seconds, etc. My code is as follows, but what I'm curious about is why after a delay(2000) my code immediately proceeds to the next command. I have tried 5 or 8 seconds, there is no delay. My delay(xxxx) is Not pausing my execution.

What am I missing?

void loop()
{
      if (digitalRead(8) == LOW)  // Switch is closed -- Normal position
          digitalWrite(12, HIGH), digitalWrite(13, LOW);  
      else                        // Switch Opened
        if (digitalRead(8) == HIGH)  // Test for immediate open loop
        delay(2000);  // Pause to test persistance
        if (digitalRead(8) == HIGH)  // Switch must still be open, continue
        digitalWrite(13, HIGH), digitalWrite(12, LOW), doStuff();
}

Any suggestions appreciated.

You should just put curly braces where you need them instead of the comma operators, this is C not python. Your second "if(digitalRead(8)==HIGH)" statement will not execute based upon the way you have it indented. It is outside the the first if/else/if statement and will execute every time thru loop().

will not execute based upon the way you have it indented.

As you yourself said:-

this is C not python.

Indentation makes no difference in C, it is only decorative.

...but very useful decoration.

My syntax is now corrected with curly braces, and all is operating as expected now. Thank you.

My only remaining related question is, the delay function pauses execution of everything, not just one item. Is there an accepted method of starting a timer (function) on say a given output, while not pausing execution of the entire code? So the timed item can execute and finish while the main code finishes tasks that need immediate continuation.

Like using OnTimer, SetTimer, etc. Maybe a Timer library? I'm continuing to research this.

Let us all intone : Look at the blink without delay example, without delay.

Ashton: I'm trying to watch a switch input, and not respond unless the input persists for over 2 seconds, etc.

With the delay(2000) you're not checking for input persists for over 2 seconds but rather seeing the switch HIGH one very short moment then checking 2 seconds later and if it's HIGH right then, assuming it must have been HIGH the whole time between. What it was really, the delay() keeps you from knowing at all.

With the delay(2000) you're not checking for input persists for over 2 seconds but rather seeing the switch HIGH one very short moment then checking 2 seconds later and if it's HIGH right then, assuming it must have been HIGH the whole time between. What it was really, the delay() keeps you from knowing at all.

I understand about not checking for persistence, continuous input, I probably worded my intent incorrectly. But I'm satisfied with an assumption that if the (normally steady-state) input is is still there in a couple seconds, its assumed on then. I'm trying to keep the basic code of this project as simple as possible, initially, to leave as much space as possible for necessities. I can always improve various modules after its completely roughed-in and operating.

Simple non-blocking, more accurate approach:

static unsigned long lastLowReading = 0;

if (digitalRead(someInput) == LOW)
  lastLowReading = millis();

if (millis() - lastLowReading > 2000)
{
  // It's been HIGH for two seconds
}

Pretty simple concept. It updates a variable with the current time whenever it reads a LOW reading. That variable won't be updated when the reading is HIGH, so the difference between the current time and the recorded time will be how long it has been HIGH for. The only caveat would be that the second if statement will fire for as long as the input remains HIGH, so if you want to perform an action only once, you would need to implement a flag or latch variable.

Ashton:

With the delay(2000) you're not checking for input persists for over 2 seconds but rather seeing the switch HIGH one very short moment then checking 2 seconds later and if it's HIGH right then, assuming it must have been HIGH the whole time between. What it was really, the delay() keeps you from knowing at all.

I understand about not checking for persistence, continuous input, I probably worded my intent incorrectly. But I'm satisfied with an assumption that if the (normally steady-state) input is is still there in a couple seconds, its assumed on then. I'm trying to keep the basic code of this project as simple as possible, initially, to leave as much space as possible for necessities. I can always improve various modules after its completely roughed-in and operating.

You will have to regardless but the route you chose is the road to spaghetti-ville.

Add: and besides, debouncing usually takes less than 2 seconds.

My only remaining related question is, the delay function pauses execution of everything, not just one item. Is there an accepted method of starting a timer (function) on say a given output, while not pausing execution of the entire code? So the timed item can execute and finish while the main code finishes tasks that need immediate continuation.

Like using OnTimer, SetTimer, etc. Maybe a Timer library? I'm continuing to research this.

The simple non-blocking approach provided by Arrch above looks sound and is good for timers from switch on. However, if you are looking for a real time clock that continues even when the arduino is switched off then you should look into using an RTC module. There are several that have libraries for the arduino and the DS1307 is discussed on the forum here:

http://arduino.cc/forum/index.php?topic=8833.0

Testing Arrch's approach, I'm getting no response at all from switch input change. Switch position is only recognized on startup, high or low.

void loop()
{
      if (digitalRead(8) == LOW)   // Switch is closed - Normal resting condition
          {
          digitalWrite(12, HIGH); // Turn on Green Normal LED
          digitalWrite(13, LOW);  
          }
      else {                        // Switch Opened

       static unsigned long lastLowReading = 0;
       
         //  if (digitalRead(8) == HIGH)
         lastLowReading = millis(); 
      
       if (millis() - lastLowReading > 2000)  //No response to this condition being met
          {
          digitalWrite(13, HIGH);
            digitalWrite(12, LOW);
          }
}
}

Did I miss something?

  if (digitalRead(8) == HIGH)

If the pin wasn't LOW, why bother reading it again to see if it is HIGH? What else could it be?

Move your lastlowreading = millis() statement up into the if block where the switch is actually LOW. The switch must be HIGH where you have it right now.

Ok, with all suggestion included, not working. There is no 2000 ms delay.

void loop()
{
      if (digitalRead(8) == LOW)   // Switch is closed - Normal resting condition
          {
          lastLowReading = millis();  
          digitalWrite(12, HIGH);  // Turn on Green Normal LED
          digitalWrite(13, LOW);    // Turn off yellow Uno LED
          }
      else {                        // Reed switch Opened
       static unsigned long lastLowReading = 0;
       if (millis() - lastLowReading > 2000)
          {
          digitalWrite(13, HIGH);  /Immediate response, no 2000 delay
            digitalWrite(12, LOW);
           // digitalWrite(7, HIGH);
          // doStuff(); // Do other stuff.
          }
}
}

Why did you create another lastlowreading variable inside the else leg? I assume you have another defined somewhere else since the if clause didn't get an error when you put the statement up there to assign it to millis() return value. Don't clear lastlowreading until after you check the value.

with all suggestion included, not working.

I disagree. When was "lastLowReading"?

Thanks afremont that solved it.