Pushbutton & LED Timing Question - Using the ElapsedMillis Library

I’m sure there is a simple way to do this, but I just can’t figure it out. :o

What I’m trying to do:

When I push and hold the button attached to pin 3 of my Arduino for 5 seconds, I would like the LED light to turn on after those 5 seconds have passed. If the button is not pushed down for the entire 5 seconds, I don’t want the LED to turn on.

What is happening:
The timeElapsed variable starts running as soon as the board is turned on, this means that after 5 seconds, if I press the button just for a split second and let go, the LED will turn on because the timeElapsed has already reached 5 seconds. I’ve tried moving the global “elapsedMillis timeElapsed;” into my main program loop, but that doesn’t seem to help. Any ideas would be greatly appreciated.

NOTE: I installed the ElapsedMillis Library in the hopes of getting away from the terrible delay() timer. (I will be adding more code to this, and I don’t want the timer to slow down my program.

/*  
  Simple example of using elapsedMillis library
  
  This example does nothing more than blinking a LED... but the difference 
  here to just using delay(1000) to control the delay between blinks is that 
  you can do more in the loop - like get user input, check buttons, get sensor
  input and other tasks that take time - while you wait for the next time the 
  LED is to change state. All you need to do is add it before or after the 
  'if' statement that controls the check of the time elapsed. 
  
  This example code is in the public domain.
*/

#include <elapsedMillis.h>

 const int buttonPin = 3;  // The number of the Pushbutton pin
 int buttonState = 0;  // Variable for reading the pushbutton status
 
 elapsedMillis timeElapsed; //declare global if you don't want it reset every time loop runs

// Pin 13 has an LED connected on most Arduino boards.
int led = 13;

// delay in milliseconds between blinks of the LED
unsigned int interval = 5000;

void setup() 
{                
  
   // initialize the digital pin as an output.
   pinMode(led, OUTPUT);  

   pinMode(buttonPin, INPUT);  // initialize the pushbutton pin as an input

}




void loop()
{
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);
   
   //The button is pushed
   while (buttonState == LOW) {
   
     if (timeElapsed > interval) //timeElapsed > 5 seconds
     {	
      		
         digitalWrite(led, HIGH);
         timeElapsed = 0;              // reset the counter to 0 so the counting starts over...
     }
  
   }
   
}

Declare long previousMillis = 0; in your set-up

When the button is pressed, you need to call the millis as a reference point: unsigned long currentMillis = millis() and use that to compare to previousMillis:
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
digitalWrite(led, HIGH); }

else {

digitalWrite(led,LOW);

millis never stops counting so you have to assign it to a variable for basis of comparison when an event occurs.

I hope that makes sense.

CBR74:
Declare long previousMillis = 0; in your set-up

When the button is pressed, you need to call the millis as a reference point: unsigned long currentMillis = millis() and use that to compare to previousMillis:
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
digitalWrite(led, HIGH); }

else {

digitalWrite(led,LOW);

millis never stops counting so you have to assign it to a variable for basis of comparison when an event occurs.

I hope that makes sense.

Thank you for the prompt reply! Yes, that make sense, but I still can't seem to get it working. This is what I have now:

/*  
  Simple example of using elapsedMillis library
  
  This example does othing more than blinking a LED... but the difference 
  here to just using delay(1000) to control the delay between blinks is that 
  you can do more in the loop - like get user input, check buttons, get sensor
  input and other tasks that take time - while you wait for the next time the 
  LED is to change state. All you need to do is add it before or after the 
  'if' statement that controls the check of the time elapsed. 
  
  This example code is in the public domain.
*/

 const int buttonPin = 3;  // The number of the Pushbutton pin
 int buttonState = 0;  // Variable for reading the pushbutton status
 
 // constants won't change. Used here to 
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin
 

// Variables will change:
long previousMillis = 0;        // will store last time LED was updated

long interval = 5000;           // interval at which to blink (milliseconds)

void setup() 
{                
  
   // initialize the digital pin as an output for LED.
   pinMode(ledPin, OUTPUT); 

   pinMode(buttonPin, INPUT);  // initialize the pushbutton pin as an input

}




void loop()
{
  
  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
  unsigned long currentMillis = millis();
  
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);
   
   //The button is pushed
   while (buttonState == LOW) {
      
      if(currentMillis - previousMillis > interval) {
      // save the last time you blinked the LED 
      previousMillis = currentMillis;   
      digitalWrite(ledPin, HIGH);
      }
   
   }

}

You're not updating currentMillis() in your while loop. Try this (untested):

void loop()
{ 
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);

   // this should really be on buttonState == HIGH, but at least for now it sets the value
   previousMillis = millis();
   digitalWrite(ledPin, LOW);
   
   // The button is pushed
   while (buttonState == LOW) {      
      if(millis() - previousMillis > interval) {
          digitalWrite(ledPin, HIGH);
      }   
   }
}

Normally you would do a transition check. Like:

   buttonState = digitalRead(pin);
   // test for low-high or high-low transition
   if (buttonState != lastButtonState) {
      lastButtonState = buttonState;
      if (buttonState == LOW) {
         ... code here
      } else {
         ... code here
      }
   }

All time variables should be unsigned long:

long previousMillis = 0;        // will store last time LED was updated

...and nowhere have you turned the LED off.

arduinodlb:
You're not updating currentMillis() in your while loop. Try this (untested):

void loop()

{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

// this should really be on buttonState == HIGH, but at least for now it sets the value
  previousMillis = millis();
  digitalWrite(ledPin, LOW);
 
  // The button is pushed
  while (buttonState == LOW) {      
     if(millis() - previousMillis > interval) {
         digitalWrite(ledPin, HIGH);
     }  
  }
}




Normally you would do a transition check. Like:



buttonState = digitalRead(pin);
  // test for low-high or high-low transition
  if (buttonState != lastButtonState) {
     lastButtonState = buttonState;
     if (buttonState == LOW) {
        ... code here
     } else {
        ... code here
     }
  }

I just tried your code.

The LED will turn on 5 seconds after I push the button once.

I had made a couple of edits so check you have the latest from the forum post.

Then report back what it is not doing that you want it to do.

arduinodlb:
I had made a couple of edits so check you have the latest from the forum post.

Then report back what it is not doing that you want it to do.

Below is your code that I tested.

What is happening: The LED will turn on 5 seconds after I push/tap the button once.

What I need: When I hold the button down for 5 seconds, the LED lights up. If I take my finger off the button before the full 5 seconds. the light should not turn on.

I really appreciate the help! Thanks! :slight_smile:

 const int buttonPin = 3;  // The number of the Pushbutton pin
 int buttonState = 0;  // Variable for reading the pushbutton status
 
 // constants won't change. Used here to 
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin
 

// Variables will change:
long previousMillis = 0;        // will store last time LED was updated

long interval = 5000;           // interval at which to blink (milliseconds)

void setup() 
{                
  
   // initialize the digital pin as an output for LED.
   pinMode(ledPin, OUTPUT); 

   pinMode(buttonPin, INPUT);  // initialize the pushbutton pin as an input

}




void loop()
{ 
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);

   // this should really be on buttonState == HIGH, but at least for now it sets the value
   previousMillis = millis();
   digitalWrite(ledPin, LOW);
   
   // The button is pushed
   while (buttonState == LOW) {      
      if(millis() - previousMillis > interval) {
          digitalWrite(ledPin, HIGH);
      }   
   }
}

I GOT IT WORKING! YEAH!!!!

I would like to thank all the great people that helped me on this thread. You guys are awesome. :smiley:

Here is the working code:

/*  
  Simple example of using elapsedMillis library
  
  This example does othing more than blinking a LED... but the difference 
  here to just using delay(1000) to control the delay between blinks is that 
  you can do more in the loop - like get user input, check buttons, get sensor
  input and other tasks that take time - while you wait for the next time the 
  LED is to change state. All you need to do is add it before or after the 
  'if' statement that controls the check of the time elapsed. 
  
  This example code is in the public domain.
*/

 const int buttonPin = 3;  // The number of the Pushbutton pin
 int buttonState = 0;  // Variable for reading the pushbutton status
 
 // constants won't change. Used here to 
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin
 

// Variables will change:
long previousMillis = 0;        // will store last time LED was updated

long interval = 5000;           // interval at which to blink (milliseconds)

long currentValue;

void setup() 
{                
  
   // initialize the digital pin as an output for LED.
   pinMode(ledPin, OUTPUT); 

   pinMode(buttonPin, INPUT);  // initialize the pushbutton pin as an input

}




void loop()
{
  
  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
   previousMillis = millis();
  
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);
   
   //The button is pushed
   while (buttonState == LOW) {
      
      
     currentValue = millis() - previousMillis;
     
     if (currentValue > interval)
     {
     
      // save the last time you blinked the LED 
      previousMillis = millis();   
      digitalWrite(ledPin, HIGH);
      
     }
   
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);
   
   }

}