Basic Question

Hi All
I have a scenario here. I am a newbie starting to explore Arduino. I know my question is quiet stupid but i feel wise enough to post in this forum and learn some tips. Here it is. In middle of a Loop function, I wanted to start an event run it for few seconds, switch it off and rest of the functions in the loop be continued.
In other words I can say if a switch is being pressed continuously, i want a led to be on for just few seconds and then off and no repetition. I would appreciate a small block of code as an example. Thanks

This is a great use of blink-without-delay.

You note the time using millis() when the switch was first pressed, and turn an output on.
Next pass thru loop, you check if its time to turn that output off, ignoring the hi/lo state of the switch.
If sufficient time has passed, you turn the output off, and if the switch has gone back unpressed, you go back to watching for a switch press.

Here is the code I had written
int ButtonPin = 2;
int LED = 13 ;
long StartTimer ;
void setup()
{
pinMode(LED,OUTPUT);
pinMode(ButtonPin,INPUT);
//digitalWrite(LED,LOW);
}

void loop()
delay (100);
if (digitalRead (ButtonPin) == HIGH) {
digitalWrite (LED,HIGH);

StartTimer = millis();
}
LEDOff();

}
void LEDOff()
{
if ((millis()- StartTimer) > 2000)
digitalWrite (LED,LOW);
//else
// digitalWrite (LED,HIGH);
// switch off the LED after 2 sec irrespective of Status of ButtonPin.
}

When I press the button the LED is on and is supposed to switch off after two seconds irrespective of the Status of ButtonPin, which is not happening in my case. Kindly suggest.

That code doesn't even compile.

moorthies:
When I press the button the LED is on and is supposed to switch off after two seconds irrespective of the Status of ButtonPin, which is not happening in my case. Kindly suggest.

Try this (untested)

int ButtonPin = 2;
int LED = 13 ;
unsigned long StartTimer;
int state;
void setup(){
  pinMode(LED,OUTPUT);
  pinMode(ButtonPin,INPUT);
  state = 0;
  }

void loop(){
    if (digitalRead (ButtonPin) == HIGH && state == 0) {
      //only do this if button hasn't been pressed yet
            digitalWrite (LED,HIGH);  
            StartTimer =millis();
            state = 1; //record the button press
    }
    if ((millis()- StartTimer) > 2000 && state ==1){  
       //only do this if button has been pressed and 2 sec. elapsed
           digitalWrite (LED,LOW);
           state = 0; //reset ready for next button press
        //switch off LED after 2 sec irrespective of _current_ Status of Button.
    }
}

@
Henry_Best
Thanks for the kind suggestions, I tried your code. I still have the same result. If the button is pressed The LED should lit and go off after two seconds irrespective of the button state. Here the LED is not getting switched of and remains lit until the button state is high, If the button is released then the LED is only lit for 2 seconds.

That is what I'd expect from your code. You [ re ] start the time each time you see the input is HIGH. Instead, you should only start timing when the input changes from LOW to HIGH.

The code posted by Henry_Best does that part correctly as far as I can see, although I haven't actually run it. What it doesn't do is wait for the input to go LOW again before going back to the initial state - as a result, the LED would go off after two seconds but would then immediately be turned back on again.

I'd suggest taking a slightly different approach. Use the StateChangeDetection example to detect when the switch becomes activated. When that happens, turn the LED on and start timing. When the timer expires, turn the LED off again.

You will have to decide what to do is the switch is released and then activated again during the two seconds - do you want the timing to restart, or will you ignore it?

PeterH:
That is what I'd expect from your code. You [ re ] start the time each time you see the input is HIGH. Instead, you should only start timing when the input changes from LOW to HIGH.

The code posted by Henry_Best does that part correctly as far as I can see, although I haven't actually run it. What it doesn't do is wait for the input to go LOW again before going back to the initial state - as a result, the LED would go off after two seconds but would then immediately be turned back on again.

I thought that the button press would be less than 2 seconds or, if it was longer, he wanted to start the sequence again.

I'd suggest taking a slightly different approach. Use the StateChangeDetection example to detect when the switch becomes activated. When that happens, turn the LED on and start timing. When the timer expires, turn the LED off again.

You will have to decide what to do is the switch is released and then activated again during the two seconds - do you want the timing to restart, or will you ignore it?

Or simply add a line:

while(digitalRead (ButtonPin) == HIGH ); 
  //do nothing until finger removed from button.

after:

digitalWrite (LED,LOW);

Thank All for your quick words.
@
Henry_Best
Thanks for your quick suggestion, by adding the last two lines , the code went perfect. Now, continue to explore I tried the code in a different manner by using it along with a ping sensor.

const int pingPin = 7;
unsigned int duration, inches;
int ButtonPin = 2;
int LED = 13 ;
unsigned long StartTimer;
int state;

void setup() {
Serial.begin(9600);
}

void loop() {
pinMode(pingPin, OUTPUT); // Set pin to OUTPUT
digitalWrite(pingPin, LOW); // Ensure pin is low
delayMicroseconds(2);
digitalWrite(pingPin, HIGH); // Start ranging
delayMicroseconds(5); // with 5 microsecond burst
digitalWrite(pingPin, LOW); // End ranging
pinMode(pingPin, INPUT); // Set pin to INPUT
duration = pulseIn(pingPin, HIGH); // Read echo pulse
inches = duration / 74 / 2; // Convert to inches
Serial.println(inches); // Display result
delay(200); // Short delay

if (inches < 25 && state == 0) {
digitalWrite (LED,HIGH);
StartTimer =millis();
state = 1;
}
if ((millis()- StartTimer) > 2000 && state ==1){
digitalWrite (LED,LOW);
state = 0;
while(inches < 25 );
digitalWrite (LED,LOW);}
}

When the distance is below 25 inches the LED lits for 2 seconds.
The problem is if the “inches” is below 25 even after 2 seconds the whole system stops functioning, I had to reset the arduino board. If the distance is above 25 inches after 2 seconds , the system functions well.
Kindly suggest

while(inches < 25 );

What do you think will happen if inches is less than 25 when this statement executes?

My assumption is, if there isn't a while statement, then the LED will blink every 2 seconds until the distance is more than 25 inches. So while the distance measured remains below 25 inches, I wanted the LED to be lit for the first 2 seconds only.

OK, but what do you think the while loop will do?

moorthies:
Thank All for your quick words.
@
Henry_Best
Thanks for your quick suggestion, by adding the last two lines ,

Two lines? Read it again. I only suggested one line and where to place it.

the code went perfect. Now, continue to explore I tried the code in a different manner by using it along with a ping sensor.
When the distance is below 25 inches the LED lits for 2 seconds.
The problem is if the “inches” is below 25 even after 2 seconds the whole system stops functioning

That’s because the while statement I gave you is constantly reading the state of the button, which will change when the button is released.
The while statement you’ve used is constantly reading inches, but nowhere does it, nor can it, change within that statement, so it goes into a loop that it cannot break out of.
Try:

if (inches < 25 && state == 0) {
            digitalWrite (LED,HIGH);  
            StartTimer =millis();
            state = 1; 
    }
 if ((millis()- StartTimer) > 2000 && state ==1){  
     digitalWrite (LED,LOW);
     while(inches < 25 ){
       // get 'new' inches by Pinging again here 
       }
     state = 0; 
   }
}

@ Henry_Best, the code is working fine. This is our first arduino project and sure we are acting dumber. We sincerely appreciate people like you and similar in the forum for guiding us and also reliving from our frustration which we face in the beginning. Thank you.

You're welcome. Stay with us and learn some more. I certainly have learnt a lot here.