Off-delay, triggered by push button

I'm not very experienced in programming, but in the past I've had pretty good luck working off of the examples in the Arduino IDE.
I'm having trouble figuring out what seems to be a simple task...
All I want to do is activate an output when a corresponding input (push-button) becomes high.
I'd like the output to remain high for a set time after the button is released, then deactivate.
if the push button is activated while the output is already active, reset the timer until it is again released.
Basically an off-delay timer. I've done this many times via an analog 555 IC, but I'd like to be able to accomplish this with the Arduino, and don't know how.

I've looked through the IDE examples, a few Arduino workshop text books, and this forum. But can't find what I'm looking for.
It seems like this would be a pretty common programming task (particularity for beginners), so I'm sure I'm not the only one who would find this helpful.
Can anybody show how to do this? (or point me to a thread that has already explained this).
Thank you in advance.

Can we guess that you are de-bouncing the push button?

Paul

look at the State Change Example in the IDE (File->example-02.Digital->State Change Detetion) and that will show you how to detect the events of your button being pushed and released.

After you get that working, look at the Blink Without Delay example as an example of how to measure elapsed time without using delay(). This will be the basis for keeping your output off for a set amount of time.

Combine the two examples. When the button is PRESSED, turn the output off. When the button is RELEASED, note the time of that event. Maybe set a variable to indicate what state you are in. Check the amount of elapsed time and, if suffucient, turn the output back on. While waiting, if the button is PRESSED again, reset the start timer.

Give it a shot. If/When you get stuck, post your code and people will help.

Paul_KD7HB:
Can we guess that you are de-bouncing the push button?

Paul

Yes, technically I am debouncing the push button, but the interval i want to the output to stay active would be in the ballpark of around 10 min or so.
This is just a part of what I want the program to do, and this would need to be happening in the background.
I am using the same push button to also toggle between two other outputs. I have that part figured out already, but figured I wouldn't mention it to keep the discussion as simple as possible.

When the debounced button *becomes * released set a flag true. Use the flag to run your output, or whatever. Simultaneously the flag enables a timer to run - which timer is held reset while the flag is false. When the timer reaches preset set the flag back to false.

File => Examples => 02. Digital => Debounce
File => Examples => 02. Digital => Blink Without Delay

When you turn the output on, set...

previousMillis = currentMillis;

...as per the Blink Without Delay example. This will start the timer to turn off the output.

When the timer expires turn the output off.

I'm having trouble seeing what lines are of use within the Debounce & Blink Without Delay example code.
I just don't know enough about what I am looking at. If somebody wrote out example code of what I am trying to do, I'd have better luck dissecting that and modifying it to fit my application.

If not, I'm just going to use a 555. I could have a circuit wired up within several minuets...

Do you understand how the samples work? Ask questions if there are things you are unsure about. There’s no point giving you a more complex example if you do not understand the samples in the first instance.

The debounce example allows you to toggle an output on/off by pressing a button. Start with that and get it to toggle your output pin.

The blink without delay cause the if statement to execute after a defined interval. That interval is a certain number of ms after the line of code “previousMillis = currentMillis;” is executed.

If you move that line of code elsewhere it will become the “start trigger” for the blink “if” statement to execute later on. So put that line of code in your debounce example to start the delay. Then when the timeout for the delay happens just turn your output off.

(deleted)

smarts-jb:
If that meets your requirement, why even think about not doing it with a 555?

Well, just to play devil’s advocate, one reason would be as a learning exercise.

Or if there is a possibility the requirements may change such that a 555 is no longer appropriate - a lot easier to change the Arduino code than swap out a hardwired circuit.

(deleted)

smarts-jb:
If that meets your requirement, why even think about not doing it with a 555?

Well, not to get too far off topic, but technically I would need a 555 as well as a flip-flop circuit to complete everything I need to do.

This would still be a simple circuit, so I guess I was looking at learning how to do this with a Arduino as an added benefit.

I'm also looking to simultaneously alternate between two other outputs every time the push button is pressed. I have this part already figured out and working. I just need the the first output to respond the the push button in an off-delay fashion.

I'll just keep hacking away at this (based off of pcbbc advice), and maybe I'll get it.
Otherwise I'll stick to an analog approach, which I'm more experienced with.

Thanks for the help.

I figured it out.
Thanks

(deleted)

smarts-jb:
Perhaps you could share the solution for the sake of those who might follow with a similar question.

Here is a version of off-delay code with a 5 second time interval. But this can be changed to whatever is needed in code.

const byte buttonPin = 2; // momentary button pin
const byte ledPin13=13; // LED (built-in on Uno)

unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 0; // wait to turn on LED (keep at 0 for this project)
unsigned long turnOffDelay = 5000; // Off-delay time (ms)
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

long time = 0;         // the last time the output pin was toggled
long debounce = 1;   // the debounce time, increase if the output flickers

 
void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(ledPin13, OUTPUT);
 digitalWrite(ledPin13, LOW);
}
 
void loop() {
 // get the time at the start of this loop()
 unsigned long currentMillis = millis(); 
 reading = digitalRead(buttonPin);
 
 // check the button
 if (digitalRead(buttonPin) == HIGH) {
  // update the time when button was pushed
  buttonPushedMillis = currentMillis;
  ledReady = true;
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    
  }

  previous = reading;
 }
  
 // make sure this code isn't checked until after button has been let go
 if (ledReady) {
   //this is typical millis code here:
   if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
     // okay, enough time has passed since the button was let go.
     digitalWrite(ledPin13, HIGH);
     // setup our next "state"
     ledState = true;
     // save when the LED turned on
     ledTurnedOnAt = currentMillis;
     // wait for next button press
     ledReady = false;
   }
 }
  
 // see if we are watching for the time to turn off LED
 if (ledState) {
   // okay, led on, check for now long
   if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
     ledState = false;
     digitalWrite(ledPin13, LOW);
   }
 }
}