0

I have created a device that allows my son to track time spent on activities and exchanges that time into a time he can use with his electronics (eTime).

Full code in GITHUB

I am having trouble coding the part of the code that handles the countdown from his earned eTime. As it is right now it can count down and give him a warning when his eTime has run out, but the process can't be interrupted.

I would like to have him be able to stop his eTime and use the remainder later. I tried putting the function in a while loop.

while(digitalRead(button_9)==LOW){
    delay(60000);
    avail_time -= 1;
    if(avail_time<0){
      playAlarm();
      return;
}

This one registers the keypress but ignores the delay.

I have also tried using a for loop to count down and another to check every second for a keypress.

void useTime() {
  for(int i=avail_time+1; i>0; i--){
    displayTime(i);
    for(int minute=60; minute>0; minute--){
      if(digitalRead(button_9)==HIGH){
        avail_time = i;
        return;
      }
      delay(1000);
    }
  }
  while(digitalRead(button_9)==LOW){
    tone(buzzer, 2000);
    }
  noTone(buzzer);
  avail_time=0;
  displayOptions();
  return;
 }

That one does not register the keypress.

5
  • 1
    look at the blink without delay example sketch
    – jsotola
    Commented Jan 8, 2020 at 7:52
  • 2
    Use timestamp instead of delay(), see Blink Without Delay example Commented Jan 8, 2020 at 7:58
  • 2
    I took a look to your code in Github. I think you also need to debounce for button Commented Jan 8, 2020 at 8:01
  • You asked "How can I interrupt a delay() when a button is pressed?" The short answer is that you can't. delay() is a blocking function. It can't be interrupted. You need to refactor your code as others have suggested.
    – Duncan C
    Commented Jan 8, 2020 at 22:52
  • You can if you handle your button press in a pin change interrupt handler. But still it is bad practice to use delay(). The only legit use is a timed sequence where you are not doing anything else.
    – Kwasmich
    Commented Feb 5, 2020 at 9:41

1 Answer 1

1

You can use the millis function to check the current 'time'. If you store this, and later call this function again, by subtracting you can see how much time has been passed. so instead of delay(500) you use if (millis() - timeStamp >= 500) { ... to continue your code.

As others said in comments, you also need to debounce to prevent multiple button triggers.

Edit: Debouncing

There is not a library for debouncing (at least not one on the Arduino site), but you can easily copy the needed code from the following sketch:

Arduino Debounce

2
  • 1
    I was able to use this solution. I have not implemented debounce yet but I'm looking into it. Is there a debounce library or do I need to implement it myself?
    – Gabe Ruiz
    Commented Feb 5, 2020 at 8:10
  • I have updated my answer according to your question in the comment. Commented Feb 5, 2020 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.