need a delay on a release of a button

hello i'm a noob and I'v looked everywere and i cant solve this problem

I need to: on a press of a button led to come on, and on a release of the same button a 5 minute delay, but if the button is pressed before time's up reset delay, and turn off wen time is up.

thanks in advance. Sorry for my bad English :blush:

tape:
hello i'm a noob and I'v looked everywere and i cant solve this problem

Well no, it's unlikely that you would find an answer to that specific problem. What did you find and what code have you come up with so far?

void setup()
{
pinMode(13,OUTPUT);
pinMode(3,INPUT);
}

void loop()
{delay (2000);
while(digitalRead(3)==HIGH)
{digitalWrite(13,HIGH);
delay(900000);
}
if (digitalRead(3)!=HIGH)
{digitalWrite (13,LOW);

}}

  delay(900000);

What you want won't work with delay() because you need to do something during the delay (like check the status of a switch).

millis() can return the time. When the switch is pressed, record the time in a variable and turn the LED on. In your loop() function, independent of the switch being pressed, check how long it has been since it was pressed, and if it has been longer than 5 minutes, turn the LED off.

Take a look at the Blink Without Delay example to see how millis() is used.

i'v tried to use millis but the result was not the expected

the "delay" incresed with the time of the pressed button. :blush:

Thanks Arrch :smiley:

tape:
i'v tried to use millis but the result was not the expected

the "delay" incresed with the time of the pressed button. :blush:

So obviously it wasn't implemented properly, but without seeing how you actually tried to implement it, can't really help you on that.

i'v tried to use millis but the result was not the expected

the "delay" incresed with the time of the pressed button

You probably read millis() when the button became pressed: you probably need to read millis() and start the timer when the button becomes released.

i'v tried this

unsigned long elapsedTime;
unsigned long onTime;
const int estado =2;

void setup()
{
onTime = millis();
onTime = elapsedTime;
pinMode(13, OUTPUT);
pinMode(estado, INPUT);
}

void loop()
{
if (digitalRead(estado == LOW))
{
digitalWrite(12, HIGH);
onTime = millis();
}
if(onTime > 0 && millis() - onTime > 5000);
{
digitalWrite(12, LOW);
onTime = 0;
}
}

and this

const int buttonPin = 2;
const int ledPin = 13;
unsigned long off_time;
boolean ledState=false;
int buttonState = 0;

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

}

void loop(){

if ((ledState) && (millis()>=off_time))
{
digitalWrite(ledPin,LOW);
ledState = false;
}
else if (!ledState)
{
buttonState = digitalRead(buttonPin);
if(buttonState == HIGH)
{
digitalWrite(ledPin, HIGH);
ledState = true;
off_time = millis() + 5000;
}
}}

thank's once again

  if (digitalRead(estado == LOW))

You're reading the state of the pin returned by the expression estado == LOW. LOW doesn't equal 2, so you're essentially saying this:

if (digitalRead(false))

... which doesn't make sense, does it? Should look like this:

  if (digitalRead(estado) == LOW)

Why not just set the led timer on a button press and ignore releases? It all about handing the reading of the switch. Think of a switch as a signal that can either be LOW or HIGH and every time through loop() you check for a change from the last known signal state. If there is a change you start the debouncing timer. If the debouncing timer is set (non-zero) then you can see if it has been in that state long enough to be a valid state change (passes debouncing). Then you can act on the state, knowing it's a valid change. I think for your purposes you should just ignore button releases. Start timing the LED on presses.

By timing the led on presses it will automatically reset for another cycle any time it is pressed. Basically like the debounce timer. Then you can check for the LED timer being set and handle the LED switching.

// Your problem is that you have to focus your attention first on reading the button.
// Once you do that properly handling the LED is quite trivial.
// Handling the button properly means detecting state changes and debouncing

// use constants for pin numbering
// ALLCAPS style denotes global constant
const byte SWITCH_PIN = 2;
const byte LED_PIN = 13;
const unsigned long DEBOUNCE_TIME = 20UL;
const unsigned long LED_ON_TIME = 1000UL * 60UL * 5UL; // 5 minutes


// global variables to handle switch reading
unsigned long debounceTimer = 0;
int switchState;
// for LED timing
unsigned long ledTimer = 0;
boolean ledOn = false;

void setup()
{
  pinMode (SWITCH_PIN, INPUT_PULLUP);
  switchState = digitalRead(SWITCH_PIN);
  pinMode (LED_PIN, OUTPUT);
}

void loop()
{
  unsigned long currentTime = millis();
  int currentSwitchState = digitalRead(SWITCH_PIN);

  if (switchState != currentSwitchState)
  {
    switchState = currentSwitchState;
    debounceTimer = currentTime;
  }

  if ((debounceTimer > 0) && (currentTime - debounceTimer >= DEBOUNCE_TIME))
  {
    debounceTimer = 0;
    if (switchState == HIGH) // released
    {
      // nothing to do on button release
    }
    else // switchState == LOW pressed
    {
      // start the timer for the LED
      ledTimer = currentTime;
    }
  }

  if (ledTimer > 0)
  {
    // check for LED turn on
    if (!ledOn)
    {
      digitalWrite(LED_PIN, HIGH);
      ledOn = true;
    }
    // check for LED turn off
    if (ledOn && (currentTime - ledTimer >= LED_ON_TIME))
    {
      digitalWrite(LED_PIN, LOW);
      ledOn = false;
      ledTimer = 0;
    }
  }
}

That ignores releases so if you hold the button for longer than five minutes it will turn off at five anyway. To reset the led timer the button has to be released then pressed again. I think that represents fairly typical operation of such a button.

Jimmy60:
It all about handing the reading of the switch.

Not really. If you simply record the time when the switch is pressed, it will update to the last time it is released. Considering a five minute interval, I would imagine the amount of time the switch is pressed would be negligible. That means edge detection and debounce handling isn't necessary.

Jimmy60:
Why not just set the led timer on a button press and ignore releases? It all about handing the reading of the switch. Think of a switch as a signal that can either be LOW or HIGH and every time through loop() you check for a change from the last known signal state. If there is a change you start the debouncing timer. If the debouncing timer is set (non-zero) then you can see if it has been in that state long enough to be a valid state change (passes debouncing). Then you can act on the state, knowing it's a valid change. I think for your purposes you should just ignore button releases. Start timing the LED on presses.

By timing the led on presses it will automatically reset for another cycle any time it is pressed. Basically like the debounce timer. Then you can check for the LED timer being set and handle the LED switching.

// Your problem is that you have to focus your attention first on reading the button.

// Once you do that properly handling the LED is quite trivial.
// Handling the button properly means detecting state changes and debouncing

// use constants for pin numbering
// ALLCAPS style denotes global constant
const byte SWITCH_PIN = 2;
const byte LED_PIN = 13;
const unsigned long DEBOUNCE_TIME = 20UL;
const unsigned long LED_ON_TIME = 1000UL * 60UL * 5UL; // 5 minutes

// global variables to handle switch reading
unsigned long debounceTimer = 0;
int switchState;
// for LED timing
unsigned long ledTimer = 0;
boolean ledOn = false;

void setup()
{
  pinMode (SWITCH_PIN, INPUT_PULLUP);
  switchState = digitalRead(SWITCH_PIN);
  pinMode (LED_PIN, OUTPUT);
}

void loop()
{
  unsigned long currentTime = millis();
  int currentSwitchState = digitalRead(SWITCH_PIN);

if (switchState != currentSwitchState)
  {
    switchState = currentSwitchState;
    debounceTimer = currentTime;
  }

if ((debounceTimer > 0) && (currentTime - debounceTimer >= DEBOUNCE_TIME))
  {
    debounceTimer = 0;
    if (switchState == HIGH) // released
    {
      // nothing to do on button release
    }
    else // switchState == LOW pressed
    {
      // start the timer for the LED
      ledTimer = currentTime;
    }
  }

if (ledTimer > 0)
  {
    // check for LED turn on
    if (!ledOn)
    {
      digitalWrite(LED_PIN, HIGH);
      ledOn = true;
    }
    // check for LED turn off
    if (ledOn && (currentTime - ledTimer >= LED_ON_TIME))
    {
      digitalWrite(LED_PIN, LOW);
      ledOn = false;
      ledTimer = 0;
    }
  }
}




That ignores releases so if you hold the button for longer than five minutes it will turn off at five anyway. To reset the led timer the button has to be released then pressed again. I think that represents fairly typical operation of such a button.

First of all thank You for Your help

But in this case my led turns off if I have the button pressed,

and I need wen pressed to be on (as long as it is pressed)

and off after a 5min delay (after released)

best regards

thank You once again

I know this is not the right way but for me it did the trick i think XD

void setup()
{
pinMode(13,OUTPUT);
pinMode(3,INPUT);

}

void loop()
{delay (50);
while(digitalRead(3)==HIGH)
{digitalWrite(13,HIGH);

}
if ((digitalRead(3)==LOW)&&(digitalRead(13)==HIGH))
{digitalWrite (13,HIGH);
delay(9000000);
digitalWrite(13, LOW);
}

}

it still turn off the led, but for my purpose not a big deal!!!

I keep trying to have the perfect solution!!!

best regars to You all

Thank You once again

tape:
I keep trying to have the perfect solution!!!

Its a shame., you almost had it; you just had a misplace parenthesis.

tape:
I know this is not the right way but for me it did the trick i think XD

 if ((digitalRead(3)==LOW)&&(digitalRead(13)==HIGH))
{digitalWrite (13,HIGH);  //why do you need this line?
 // You've already established, in the if statement, that it's HIGH.
// If it was LOW, you'd never get here.
delay(9000000);
digitalWrite(13, LOW);
}