Push a button hold the led on for X time and if the button is pushed again...

Ok, what would be the simplest way, without using delay to do the following

An input that turns on a LED the LED is held on for say 5 seconds If the input is hit again within the 5 secs it will restart the 5 sec timer thus keeping the led on and won't turn off until no input for 5 seconds.

Could be push a button, the led turns on a timer keeps it on for 5 secs, then it's hit again and timer is reset thus keeping the led on until no input is hit within 5 secs.

The problem my noob self is having is how to do the timing.

you can try this untested code:

button may need debouncing…

int buttonPin = 2;
int ledPin = 13;
unsigned long duration = 5000UL; // five seconds
unsigned long startTime;
int lastButtonState;

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}
void loop()
{
 int buttonState = digitalRead(buttonPin);
 if (buttonState == LOW)
 {
   if (lastButtonState == HIGH)
   {
     startTime = millis();
     Serial.println(F("Button Pressed"));
   }
 }
 lastButtonState = buttonState;
 ledOn(startTime);
}

void ledOn(unsigned long myStart)
{
  if (millis() - myStart < duration)
  {
    digitalWrite(ledPin, HIGH);
  }
  else
  {
    digitalWrite(ledPin, LOW);
  }
}

Ok, let me clear up some, I couldn't get that code to work, plus I'm not trying to do this in loop.

I have a function that turns on and off a pump. Instead of the pump turning off right after input off, i'd like to keep it on uncase there is another input that requires it to stay on.

So the function that tells the pump function on or off pump(0) or pump(1) and it just runs a switch and turns the pump on or off.

void pump(int sysPump){
  switch(sysPump){
  case 0:
    digitalWrite(rlay9, HIGH); // HIGH TURNS OFF RELAY
    break;
  case 1:
    digitalWrite(rlay9, LOW); // LOW TURNS ON RELAY
    break;
  }
}

I need the pump to keep running for 5 seconds in case another input requires it on. So just keeping the pump on for X time. I'm using 5 seconds, but that could be changed of course.

I hope this clears up what I'm trying to do.

I have a function that reads an analog reading, and if it's between set readings (high/low) it will kick the pump on. I need the pump to stay on in case another reading needs it, it just helps keep lag of the pump turning on and off down to a min.

Any way of changing up the pump function to keep the pump on for X time?

I think @BulldogLowell has the basic requirements in his code.

This demo several things at a time uses the same principle but with the code in short functions.

Record the time when the button is pressed and don't turn the LED off until a suitable number of milliseconds has elapsed.

...R

I have the millis thing working, and it does hold it on for the extra 5 seconds, but if another input uses it again, it doesn't reset the timer so it stays on another 5 secs continued. So when the 1st input turns it on, as soon as it's off it's turning off in 5 secs no matter what and then comes right back on if input active.

Not that the small pulse off would hurt anything, it's just that there is a off pulse for about 50ms.

void pump(int sysPump){
  switch(sysPump){
  case 0:
  
      jcurrentMillis = millis();
     if (jcurrentMillis - jpreviousMillis >= jinterval == true ) {
    
            digitalWrite(rlay9, HIGH); // LOW TURNS ON RELAY PUMP ON
      
      // save the time when we displayed the string for the last time
      jpreviousMillis = jcurrentMillis;
      }
    break;
  case 1:
    digitalWrite(rlay9, LOW); // LOW TURNS ON RELAY PUMP OFF
    break;
  }
}

I would like it if the "pump on" signal is given again within that 5 secs it just continues to stay on, like resets the 5 sec counter. I can't figure out how to reset the 5 sec counter if pumpon is called again.

Every time the ON button is pressed set jPreviousMIllis = jCurrentMillis which will effectively restart the count. ???

...R

I thought that's what it's doing, but it doesn't reset

putting previousMillis = currentMillis in the pump on switch fixed it. Now it stays on and the counter resets on every push of the button. Works perfect now thanks!

// PUMP OPS
void pump(int sysPump){
  switch(sysPump){
  case 0: // turns off the pump
      jcurrentMillis = millis();
     if (jcurrentMillis - jpreviousMillis >= jinterval == true ) {
            digitalWrite(rlay9, HIGH); // LOW TURNS ON RELAY
      // save the time when we displayed the string for the last time
      jpreviousMillis = jcurrentMillis;
      }
    //digitalWrite(rlay9, HIGH); // HIGH TURNS OFF RELAY
    break;
  case 1: // turns on the pump
      jpreviousMillis = jcurrentMillis;
    digitalWrite(rlay9, LOW); // LOW TURNS ON RELAY Turns on the pump
    break;
  }
}