led on for 5 sec after button press

Hi guys,
I want to write a program to turn on led. After button press (push button) it should stay on for 5 seconds and then turn off. After that it should wait for another button press. How could I do that? I've heard something about millis() but I don't know how to implement that.
Thanks

Have a look at the blink without delay example provided in the IDE, and see if it gives you any ideas.

I've found a solution how to implement millis() as a delay Arduino Playground - AvoidDelay
I got it working now. Thanks

Well, show us what you tried.

You haven't told us about your circuit.

Also what else do you have in the code?

If you have a normally-open pushbutton, you can wire one end to GND, and the other to a pin, say pin 2;

In the code you set pin 2's mode to be INPUT_PULLUP. This enables a resistor internally so that the pin doesn't float high or low, its default state is pulled HIGH via the resistor.

Next, you have [at least] 2 choices here. you can frequently poll the value of the push button to determine if it's pressed, or you can set up an interrupt [preferred, but has to be on interrupt-enabled pin - see here]

Here is an example of that [not tested on board, but will compile]:

int pin = 2;
int led = 5;
void setup()
{
  pinMode(pin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  attachInterrupt(0, isr, FALLING);
}

volatile long last = 0;
volatile bool turnOff = false;
volatile long offAt = 0;

void isr()
{
    if( (millis() - last ) > 20 ) //if at least 20 ms has passed since last press, this is not a dup
    {
        last = millis(); //note the time, for ignoring duplicate presses
        turnOff = true;
        offAt = millis() + 5000; //save a variable of now + 5 seconds
        digitalWrite(led, HIGH); //turn on
    }
}

void loop()
{
  if(turnOff)
  {
   if(millis() >= offAt)
    {
       digitalWrite(led, LOW); //turn off led
    } 
  }
}

if you just wanted to poll the button in loop() instead, you can, and if you have nothing else going on that would be ok.
example:

int pin = 2;
int led = 5;
void setup()
{
  pinMode(pin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
}

long offAt = 0;
void loop()
{
  if( (digitalRead(led) == LOW ) && (digitalRead(pin) == LOW) ) //if LED is off  and button is pressed [low because it has pullup resistor]
  { 
    digitalWrite(led, HIGH);
    offAt = millis() + 5000; //store var of now + 5 seconds
  }
  
  if(digitalRead(led) == HIGH) //if led is on
  {
      if(millis() >= offAt) //see if it's time to turn off LED
      {
         digitalWrite(led, LOW); //it's time. this also re-enables the button
      }
  }
}

For that one, if you press the button, and LED is on, any more button presses will be ignored until the led is off again.

it is ok pal

well done

cheers

mvmacd,
Thank you so much for your help :slight_smile: I'll try this out 2moro.
I my code I just have an led on pin 2 and push button on pin 3. That's for start, as I wanted to learn how to do it on a simple example. Later I will change the code to suit my needs.
Thanks again!

One more question.. would be the same code (slightly changed) working with the bluetooth module?
I want the same procedure: sending char '1' via bluetooth, which turns on led for 5 seconds, then the led turns off and waits for another command? I will use interrupt for checking bluetooth.

Yes, it would definitely be different. I suggest you take a look at this page:
http://playground.arduino.cc/learning/tutorial01

Maybe you could also put the part that checks Serial.available() in a timer (Search for Timer1 arduino examples) in order to multi-task the board, but otherwise, after hooking up the hardware, this is something like what the code would look like:

int led = 5;
void setup()
{
  pinMode(led, OUTPUT);
}

long offAt = 0;

char val;

void loop()
{
 if( (digitalRead(led) == LOW) && Serial.available() )       // if data is available to read, AND if LED is off -- you can change this if you want, so that you could write 0 to turn off led instantly
  {
    val = Serial.read();         // read value and store it in 'val'
   }
  if( val == '1' )               // if '1' was received that's equivalent to the button being pressed
 {
     val = ''; //empty the char so we don't mistakenly use it again unless transmitted
     digitalWrite(led, HIGH); //turn on led
     offAt = millis() + 5000; //store var of now + 5 seconds
 }
  
  if(digitalRead(led) == HIGH) //check if led is on
  {
      if(millis() >= offAt) //see if it's time to turn off LED
      {
         digitalWrite(led, LOW); //it's time. this also re-enables the button
      }
  }
}

With that being said, I haven't used my Bluetooth board yet, but it should be close to [if not] working.

bolus66:
I've found a solution how to implement millis() as a delay Arduino Playground - AvoidDelay
I got it working now. Thanks

The author of that piece feels happy. :slight_smile:

i want following program if somebody can help me.
when i press button for 2sec then led turn on for 5sec.
if i again press button during led on then led remain on for next 5sec.
means led should not turn off if i press button for 2 sec again and again

Well have a try at writing a program (or even modifying the program earlier on in this old thread). Post it here and tell us what it does and what you want it to do differently. Then we can help you get it working.

Steve

i am using this code here when i press the button for 2sec then led turn on for 5sec but after 5 sec it goes to off.
I want that if I press the button again and again for 2 sec then the led remain turn on for next 5 5 second and never off. However, if i stop pressing the button then it turns off after 5sec.
Please tell what i should add in that code
const int ledPin = 13;
const int buttonPin = 2;

int programState = 0;

int buttonState;
long buttonMillis = 0;
const long intervalButton = 2000;

long ledMillis = 0;
const long intervalLed = 5000;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);
}

void loop()
{
unsigned long currentMillis = millis();
buttonState = digitalRead(buttonPin);

if (buttonState == LOW && programState == 0) {
buttonMillis = currentMillis;
programState = 1;
}
else if (programState == 1 && buttonState == HIGH) {
programState = 0; //reset
}
if(currentMillis - buttonMillis > intervalButton && programState == 1) {
programState = 2;
ledMillis = currentMillis;

digitalWrite(ledPin, HIGH);
}

if(currentMillis - ledMillis > intervalLed && programState == 2) {
programState = 0;

digitalWrite(ledPin, LOW);
}
}

Good! Now go and read the forum instructions so that you can go back and modify that post - the "More -> Modify" option below the right hand corner of your post - to mark up your code as such using the "</>" icon in the posting window. Just highlight each section of code (or output) from the IDE and click the icon. In fact, the IDE has a "copy for forum" link to put these markings on for you so you then just paste it here in a posting window.

But don't forget to use the "Auto-Format" (Ctrl-T) option first to make it easy to read. If you do not post it as "code", it can be quite garbled and is always more difficult to read.