how to make an action take place within 3 seconds of the release of a button

I am trying to implement an action that would take place under the following condition:

if the button is pressed, do nothing. if the button is released, count 3 seconds but do nothing.

the system should count for 3 seconds. if the button is still in the released condition, make the event happen. else, if the button is pressed again, do nothing.

How can I convert that to code?

thank you.

First detect when the button becomes released. See the StateChangeDetection example in the IDE.

Then, when it becomes released save the value of millis(). Then each time through loop() you can test whether 3 seconds has elapsed and/or whether the button has become pressed in the meantime

See Using millis() for timing. A beginners guide

Here is a Flow Chart representation/coding (untested) for the 'Problem Statements' of the OP.

UKHeliBob:
First detect when the button becomes released. See the StateChangeDetection example in the IDE.

Then, when it becomes released save the value of millis(). Then each time through loop() you can test whether 3 seconds has elapsed and/or whether the button has become pressed in the meantime

See Using millis() for timing. A beginners guide

UKHeliBob, I appreciate all of your inputs. I really do. So, no disrespect. But I would appreciate it even more, if you could give me more specific advice from time to time, than just remind me of existence of examples in IDE. Could you please explain how to check if 3 seconds have elapsed or if the button has become pressed again in more detail?

Besides, using loop() for continuous checking is not an option for me because I have already used loop() somewhere else in the code.

Thank you.

I have already used loop() somewhere else in the code.

Can you show us all your code?

jbellavance:
Can you show us all your code?

Sure. I have to attach the .ino file because the code is so long that I can only paste it in 3 or 4 parts. So, please check the attached file.

Please check this section:

void flashingDisplay()
{
    if (minuteClock == 0 && secondClock == 0 && modeClock == true && ledsOnOffValue < 1000 && 
    hourValue > 1000 && minuteValue >1000) {

There is an action that follows this. I'm trying to make it so that, the action will only take place if the hourValue or minuteValue buttons are released for more than 3 seconds. If any of them is pressed again within 3 seconds, the event shouldn't happen. In other words, if I'm still in the process of setting time with hour/min buttons, and if one of those buttons is in pressed condition or is within 3 seconds from previous press, the event should not happen.

Can you help?

Full_work_copy.ino (23.5 KB)

Could you please explain how to check if 3 seconds have elapsed

That’s in the standard basic examples, look at blink without delay or the post pinned at the top of the forum titled “Using millis() for timing. A beginners guide

Could you please explain how to check if 3 seconds have elapsed

See :Using millis() for timing. A beginners guide

unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000;  //the value is a number of milliseconds
const byte ledPin = 13;    //using the built in LED

void setup()
{
  Serial.begin(115200);  //start Serial in case we need to print debugging info
  pinMode(ledPin, OUTPUT);
  startMillis = millis();  //initial start time
}

void loop()
{
  currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis >= period)  //test whether the period has elapsed
  {
    digitalWrite(ledPin, !digitalRead(ledPin));  //if so, change the state of the LED.  Uses a neat trick to change the state
    startMillis = currentMillis;  //IMPORTANT to save the start time of the current LED state.
  }
}

or if the button has become pressed again

Your code:

  alarmValue = analogRead(buttonAlarm);
  //обрабатываем нажатие на кнопку переключения режимов
  if (alarmValue < 1000)

Besides, using loop() for continuous checking is not an option for me because I have already used loop() somewhere else in the code.

Place this code in: flashingDisplay()

Hope this helps you towards a solution.

Jacques

jbellavance:
See :Using millis() for timing. A beginners guide

unsigned long startMillis;  //some global variables available anywhere in the program

unsigned long currentMillis;
const unsigned long period = 1000;  //the value is a number of milliseconds
const byte ledPin = 13;    //using the built in LED

void setup()
{
  Serial.begin(115200);  //start Serial in case we need to print debugging info
  pinMode(ledPin, OUTPUT);
  startMillis = millis();  //initial start time
}

void loop()
{
  currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis >= period)  //test whether the period has elapsed
  {
    digitalWrite(ledPin, !digitalRead(ledPin));  //if so, change the state of the LED.  Uses a neat trick to change the state
    startMillis = currentMillis;  //IMPORTANT to save the start time of the current LED state.
  }
}


Your code:

alarmValue = analogRead(buttonAlarm);
  //обрабатываем нажатие на кнопку переключения режимов
  if (alarmValue < 1000)


Place this code in: flashingDisplay()

Hope this helps you towards a solution.

Jacques

I'm a little bit confused. Which code do you mean to paste? You are mentioning the alarmValue. What does it have to do with my case?

Cheers

There is no code to paste.

The code I copied from Using millis() for timing. A beginners guide is to be understood. It contains all you need to verify if 3 seconds (or any time lapse) has passed.

The alarmValue code is taken from your own code as an answer to :

how to check if ... or if the button has become pressed

So:

void flashingDisplay()
{
  if (analogRead(thatButton) < 1000) abort = true;
  if (currentMillis - startMillis >= period && !abort)
  {
   Do your thing
  }
}

Do not attempt to copy this code, it will not work. Just take a look at the structure. the solution is almost entirely there.

Jacques

arduinoware:
Sure. I have to attach the .ino file because the code is so long that I can only paste it in 3 or 4 parts. So, please check the attached file.

When you are faced with the need to figure out a new technique it is always a good idea to learn it with a short program that does nothing else. It also makes it much easier for people to help you if they are not distracted by irrelevant code.

...R

jbellavance:
There is no code to paste.

The code I copied from Using millis() for timing. A beginners guide is to be understood. It contains all you need to verify if 3 seconds (or any time lapse) has passed.

The alarmValue code is taken from your own code as an answer to :
So:

void flashingDisplay()

{
  if (analogRead(thatButton) < 1000) abort = true;
  if (currentMillis - startMillis >= period && !abort)
  {
  Do your thing
  }
}




Do not attempt to copy this code, it will not work. Just take a look at the structure. the solution is almost entirely there.

Jacques

Thanks. But what about the void loop()? I have already used it somewhere else. The compiler gives me an error message saying it is re-occuring.

I placed everything in flashingDisplay(). Not in loop().

jbellavance:
I placed everything in flashingDisplay(). Not in loop().

What about these? in global area?

unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000;  //the value is a number of milliseconds

What about these? in global area?

Yes

jbellavance:
Yes

Thanks. :slight_smile:

And this?

startMillis = millis();  //initial start time

Also

jbellavance:
Also

Thanks. I will try that and see if I can get it to work.

Cheers

jbellavance:
Also

No, it didn't work.

I think:

startMillis =millis()

goes to void setup()
and

currentMillis=millis()

goes to the beginning of flashingDisplay(), right?

Yes, and... yes