Football timer using millis()

I am new to arduino. I am trying to make an electronic football scoreboard. It is meant to be operated using an LCD screen and five buttons as digital inputs. I have managed to code the LCD and seven segments. But I am having some difficulty coding the timer. I was trying to use delay(1000) to drive the timer but it was naturally delaying the rest of the code. After searching the Arduino site and internet I have found out that the way around this is to use millis(). I have tries reading about this function and watched a few videos on Youtube but I cannot get my head wrapped around it.

Attached is flow diagram showing what the LCD screen shows and what the seven segments are suppose to do.

I am basically trying to use four variables to drive the timer:
start_time
match_length
end_time
injury_time

An additional variable called match_stage is used to determine if the match is in first half or first half injury or second half or second half injury or penalties.
I want to drive the timer variables using the following logic:

if match_stage is first half then
start_time = 0
end_time = match_length / 2
set injury_time to user entered value
if injury_time value is greater than 1 then
start_time = injury_time
end_time = 0

NOTE: HALF TIMER IS COUNTING UP WHERE INJURY TIMER IS COUNTING DOWN

At the end of injury count down or if injury_time = 0
match_stage = second half

if match_stage is second half then
start_time = match_length / 2
end_time = match_length
set injury_time to user entered value
if injury_time value is greater than 1 then
start_time = injury_time
end_time = 0

I want to code this and learn how to use millis() for this. If someone can please help me started with this code I would really appreciate it.

Thanks

LCD Menu flow diagram w Seven Segment Output.pdf (563 KB)

I have tries reading about this function and watched a few videos on Youtube but I cannot get my head wrapped around it.

Here is some sample code, look at it and tell us if you understand how it works? Next change TaskTime to 100. What did this do?

const unsigned long TaskAtime  = 500;  //Run TaskA every 1/2 second

unsigned long TimerA;                   //Times up Task A timer

//etc.

void setup()
{
  TimerA = millis();                      //Initailize  
  pinMode(13,OUTPUT);
}         // END of setup()

void loop()
{
  unsigned long millisNow = millis();

  if (millisNow - TimerA >= TaskAtime)       // Is it time to run TaskA?
  {
    TimerA = millis();      //Re-initialize
    TaskA();
  } 

}                   // END of loop()

//************************************************

void TaskA()
{
  digitalWrite(13,!digitalRead(13));   //Toggle pin 13
}

Imagine you were watching the game and your only timepiece was a watch. How would you go about it?

For a start, the end of the game will be when the game started, plus the length of the game, right?

So if it is now 4 pm, and it started at 3 pm, then it has been going for an hour (4 - 3).

Thanks Larry and Nick.

I have tested the example posted by Larry and now I am trying to integrate it into my LED segments code. Will update you guys shortly how it all went.

Here is my code for the timer so far. I am trying to code the scoreboard in bite size chunks. I will integrate this code with the LCD code once I get is working properly.

The issue I am having with this is that the for loop for counting up the timer completes counting up and displays the end result only. Rather than updating the seven segments every second as intended.

#define ShiftReg_LatchPin  49
#define ShiftReg_ClockPin  47
#define ShiftReg_DataPin   45

#define DisplayCount 8
byte g_digits [15];
int g_numberToDisplay = 0;
byte g_registerArray [DisplayCount]; 

long unsigned int start_time = 0;
long unsigned int match_length = 20;
long unsigned int end_time;
long unsigned int injury_time = 2 * 60;

const unsigned long TaskAtime  = 1000;
unsigned long TimerA;

int Tens;
int Mins;
int Secs;

int home_score = 0;
int away_score = 0;

void setup(){
TimerA = millis();

pinMode (ShiftReg_LatchPin, OUTPUT);
pinMode (ShiftReg_ClockPin, OUTPUT);
pinMode (ShiftReg_DataPin, OUTPUT);
 
 g_digits [0] = B01111110;  //0   Bxxxxxxxx
 g_digits [1] = B01001000;  //1   BdCDEBAFG
 g_digits [2] = B00111101;  //2   B number order
 g_digits [3] = B01101101;  //3       --A--
 g_digits [4] = B01001011;  //4    F |     | B
 g_digits [5] = B01100111;  //5      |--G--|
 g_digits [6] = B01110111;  //6    E |     | C
 g_digits [7] = B01001100;  //7       --D-- o = d
 g_digits [8] = B01111111;  //8
 g_digits [9] = B01101111;  //9
 g_digits [10] = B01011011;  //H
 g_digits [11] = B01011111;  //A
 g_digits [12] = B00110010;  //L
 g_digits [13] = B00010111;  //F
 g_digits [14] = B01111010;  //U
}

void loop(){

unsigned long millisNow = millis();

if (millisNow - TimerA >= TaskAtime)// Is it time to run TaskA?
  {
  TimerA = millis();      //Re-initialize
  BuildSendStringForLEDs();
  }
}

void BuildSendStringForLEDs()
{
        for(start_time = start_time; start_time <= end_time; start_time++){
          Mins = start_time / 60;
          Secs = (start_time - (Mins * 60));
            
            Tens = Mins / 10;
            g_registerArray[3] = g_digits [Tens];
            g_registerArray[2] = g_digits [(Mins - (Tens * 10))];
            Tens = Secs / 10;
            g_registerArray[1] = g_digits [Tens];
            g_registerArray[0] = g_digits [(Secs - (Tens * 10))];
                     
        if (home_score < 10){
           Tens = home_score / 10;
           g_registerArray[5] = 0;
           g_registerArray[4] = g_digits [(home_score - (Tens * 10))];
        }
        else{
           Tens = home_score / 10;
           g_registerArray[5] = g_digits [Tens];
           g_registerArray[4] = g_digits [(home_score - (Tens * 10))];
        }
        if (away_score < 10){
           Tens = away_score / 10;
           g_registerArray[7] = 0;
           g_registerArray[6] = g_digits [(away_score - (Tens * 10))];
        }
        else{
           Tens = away_score / 10;
           g_registerArray[7] = g_digits [Tens];
           g_registerArray[6] = g_digits [(away_score - (Tens * 10))];
        }
        sendSerialData(DisplayCount,g_registerArray);
        
      }
        
        for(start_time = start_time; start_time = end_time; start_time){
          if (injury_time > 0){
            for(injury_time > 0 ; injury_time >= 0; injury_time --){
                Mins = injury_time / 60;
                Secs = (injury_time - (Mins * 60));
                Tens = Mins / 10;
                g_registerArray[3] = g_digits [Tens];
                g_registerArray[2] = g_digits [(Mins - (Tens * 10))];
                Tens = Secs / 10;
                g_registerArray[1] = g_digits [Tens];
                g_registerArray[0] = g_digits [(Secs - (Tens * 10))];
             }
          }
          if (injury_time = 0){
            g_registerArray[3] = g_digits [10];
            g_registerArray[2] = g_digits [11];
            g_registerArray[1] = g_digits [12];
            g_registerArray[0] = g_digits [13];
          }
        if (home_score < 10){
           Tens = home_score / 10;
           g_registerArray[5] = 0;
           g_registerArray[4] = g_digits [(home_score - (Tens * 10))];
        }
        else{
           Tens = home_score / 10;
           g_registerArray[5] = g_digits [Tens];
           g_registerArray[4] = g_digits [(home_score - (Tens * 10))];
        }
        if (away_score < 10){
           Tens = away_score / 10;
           g_registerArray[7] = 0;
           g_registerArray[6] = g_digits [(away_score - (Tens * 10))];
        }
        else{
           Tens = away_score / 10;
           g_registerArray[7] = g_digits [Tens];
           g_registerArray[6] = g_digits [(away_score - (Tens * 10))];
        }
        sendSerialData(DisplayCount,g_registerArray);      
      }
}

void sendSerialData (byte registerCount, byte *pValueArray)
{
  digitalWrite (ShiftReg_LatchPin, LOW);
  for (byte reg = 0; reg < DisplayCount; reg++)
  {
    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (ShiftReg_ClockPin, LOW);
      if ((pValueArray[reg] & bitMask) == bitMask)
      {
        digitalWrite (ShiftReg_DataPin, HIGH );
      }
      else
      {
        digitalWrite (ShiftReg_DataPin, LOW );
      }
      digitalWrite (ShiftReg_ClockPin, HIGH);
    }
  }
  digitalWrite (ShiftReg_LatchPin, HIGH);
}
  TimerA = millis();      //Re-initialize

The millis() function is a watch, not a timer. Use names that mean something in that context. Forget you even know how to spell timer. DO NOT USE timer as a name. Ever!