I use millis, and several if( ) combinations - they are tested in a select sequence so that only 1 can be true.
// ***********************************************************************************************
// Loop here endlessly, checking if time or score needs updating, if wireless message came in,
// if touch lights are on
// ***********************************************************************************************
void loop()
{
// check if time needs updating
if ((time_running == 1) || (time_running == 2)) // fencing time is counting down or delay time is counting down
{
unsigned long currentMillis = millis(); // see how long its been
if (currentMillis - previousMillis >= interval) // more than our quarter second interval?
{
// save the last time we okayed time updates
previousMillis = currentMillis;
quarter_interval = quarter_interval+1;
// cycle the colon state
if (colon == 0x80)
{
colon = 0x00;
}
else
{
colon = 0x80;
}
update_time = 1; // enable time display to be updated
if (quarter_interval == 4) // we hit the one second update time
{
quarter_interval = 0;
// update the time digits
// cases:
// 0:01, final second - stop time, disable touch lights, sound buzzer
// Tens of seconds rollover: time = x:50, x:40, x:30, x:20, x:10: decrement tens of seconds, rollover seconds to 9
// Minutes rollover: time = 9:00, 8:00, etc. 2:00, 1:00: decrement ones of minutes, rollover tens of
// seconds to 5, ones of seconds to 9
// 10:00: Roll all the digits over
// otherwise: just roll over the seconds
// Case: Final Second
if ((minutes_ones == 0) && (seconds_tens == 0) && (seconds_ones == 1)) // don't need minutes_tens, can't have 10:01
{
touchlight_enable = 0; // score touches are locked out
time_running = 0; // stop time running
seconds_ones = 0; // clear the last second
updated = 1; // fake a Case complete flag
buzzer = 1; // add a buzzer for this: end of time buzzer sounds
if ((time_running == 1) && (period>0) && (period<9)) { // update period counter if was fencing time, not 1:00 or 10:00 break
period = period +1;
update_period=1; // enable period display to be updated
}
} // end of if final second
// Case: x:50, x:40, x:30, x:20, x:10
if ((seconds_tens >0) && (seconds_ones == 0)) // case for the last tens of seconds
{
seconds_tens = seconds_tens - 1; // decrement the tens
seconds_ones = 9; // rollover the ones
updated = 1;
} // end of if 10 of seconds rollover
// Case: 9:00, 8:00, etc 2:00, 1:00
if ((minutes_ones > 0) && (seconds_tens == 0) && (seconds_ones == 0)) // case for the last ones of minutes
{
minutes_tens = 0x00; //
minutes_ones = minutes_ones - 1; // decrement the minutes
seconds_tens = 5; // rollover the tens of seconds;
seconds_ones = 9; // rollover the ones of seconds;
updated = 1;
} // end of if minutes rollover
// Case: starting from 10:00
if (minutes_tens == 0x01) // roll over all digits
{
minutes_tens = 0x00; // rollover the tens of minutes
minutes_ones = 9; // rollover the ones of mints;
seconds_tens = 5; // rollover the tens of seconds;
seconds_ones = 9; // rollover the ones of seconds;
updated = 1;
} // end of if 10:00 rollover
// General Case: just decrement the seconds
if (updated == 0) // nothing else updated - but don't decrement if = 0.
{
seconds_ones = seconds_ones - 1;
}
updated = 0; // reset for next pass thru
} // end of if quarter_interval
} // end of reaching our interval
} // end of if time_running
else
{
update_time = 0; // no time update this time around - probably don't need this
}