Take a look at what I did here, using millis() to track when 1 second updates need to be displayed.
This decrements time from 10:00, 3:00, or 1:00, you could easily adapt it to count up instead.
I have 'interval' set so that the colon flashes on-off-on-off every second to easily see that time is running.
If you needed 6 digits you could change 'interval' to be the fastest incrementing digit, and let things roll / increment from there as it increments.
I had the code take care of rolling over the digits at the time boundaries vs straight counting and then dividing & dealing with the remainder, etc.
Take out the stuff I have for fencing references, add in your code to read the button and disable updating the display while still maintaining the time running. (I have another section that follows this one - if update_time gets set to 1, the updated digits are written into a MAX7221 to be displayed as part of 8 digits that display stuff - at the end of that section, it resets update_time to 0).
Also, look into tpic6b595 shift registers if you want to stay with that vs a chip that multiplexes the segments/digits, then you can create your own multi-LED segment digits (like 6-8 LEDs in series per segment) running from a higher voltage (say 24Vif you use eight 3V LEDs) while still drawing just 20mA/segment.
These variables have to be data type 'long': currentMillis, previousMillis, interval
// ***********************************************************************************************
// 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
}