Help with timing function

First here is the code:

void F_countdown() { 
  if (ClearLCD == true) {
    lcd.clear();
    ClearLCD = false;
  }
  
  LCDBacklight(0, 0, 255); // Blue
  lcd.setCursor(2, 0);
  lcd.print("Time Started:");
  
  // If second has passed then we subtract that from the AllowedPlaytime
  if (millis() - CurrentMillis > 1000) {
    AllowedPlaytime = AllowedPlaytime - 1000;
    CurrentMillis = millis();
    F_timeDisplay();
    
  // If there is less than 5 minutes of playtime left start sounding an audible alarm at the interval defined.  
  if (AllowedPlaytime <= 300000) { // 5 min
    if (millis() - LastWarningTime > WarningBeepInterval1) {
      F_warning1();
    }
  
  // Or if there is less than 10 seconds of playtime left start sounding an audible alarm at the interval defined. 
  else if (AllowedPlaytime <= 10000) { // 10 seconds
    if (millis() - LastWarningTime > WarningBeepInterval2) {
      F_warning2();
    }
  }
}
  }

  if (digitalRead(PauseSW) == LOW) { // Logic is inverted since we're using the internal resistors. When button is pressed the PIN goes LOW, when not pressed it's HIGH.
    lcd.clear();
    state = S_pause;
  }
  
  if (AllowedPlaytime == 0) {
    lcd.clear();
    state = S_timeup; 
  } 
}

Hopefully that’s enoug to get us going, I can post the whole sketch but it’s a lot. The part that I’m wondering if anyone can help on is the:

 if (AllowedPlaytime <= 300000) { // 5 min
    if (millis() - LastWarningTime > WarningBeepInterval1) {
      F_warning1();

As you can see when a certain time is reached a warning function is run that sounds an audible alarm (a tone to a speaker). The alarm function is called every x number of seconds/minutes/etc, as defined by WarningBeepInterval1. As set now this sounds a tone every minute (WarningBeepInterval1 = 60000;).

This works great - as the timer counts down and reaches the 5 min mark a tone is sounded every minute

The issue that I’m having is that if the pause button is pressed if (digitalRead(PauseSW) == LOW) then the program goes into the pause state which causes the main main timer:

if (millis() - CurrentMillis > 1000) {
    AllowedPlaytime = AllowedPlaytime - 1000;
    CurrentMillis = millis();
    F_timeDisplay();

to stop running. When the start button is pressed then it goes back into the count down function - if you’ve reached the 5 minute mark and tones have started to sound when the pause button is pressed then when it comes out of pause the tones are out of sync with the main timer. They still sound every minute but, again not in sync with the main timer.

I know this has to do with the fact that I’m using millis() to keep track of the time passed and even in the pause state it’s still running so if you pause for 2 minutes and then un-pause if (millis() - LastWarningTime > WarningBeepInterval1) { is true and so it runs like you’d expect it to.

I’m at a loss on how to resolve this and hoping someone can help with ideas. If you need more info, ro the whole sketch, let me know. Thanks.

When the button is pressed again, you'll probably want to set the LastWarningTime so that it is in sync with the main timer. Its hard to say how exactly, without seeing the full code.

Yeah, figure out how many millis you paused, and add it to both LastWarningTime and CurrentMillis.

Also, does this work?

  if (AllowedPlaytime <= 300000) { // 5 min

because 300000 is bigger than will fit in an integer. I have to do 300000L in order for it to work in my sketches.

Here's a link to the full code (too big to post directly): // include the Arduino LCD and math libraries#include <LiquidCrystal.h>// - Pastebin.com

So every time you push the pause button you get two more seconds of play time? I think there's an exploit in there somewhere.

:slight_smile: Not really. Think about it. You hit the pause button at 10 minutes, come back and hit the start button, by the time the video is back in sync and you can play you’ve only gained an extra second so after the pause you’re at 00:10:01. To exploit this you’d then have to press the pause button again before you lost that second, possible but you’d only gain a second for each run through. There are two other ways that you can exploit this that are much more “profitable” and easier.