Stop timer with only seconds and Milliseconds

Hello, I am working on a timer that displays the seconds and milliseconds using 4 seven segment displays on the Arduino Mega board. I am currently stuck with a dilemma with the way i was coding it and do not know how to fix it.

[ we decided to use case #'s as we saw an example that used this system]

i realized after a bit of coding that for me to go to the 59.99 seconds place it would take an absurd amount of cases to get to that number. Please help me fix/find another way to do this.

note there are currently no errors with my code

Main_Code.ino (12.4 KB)

I think you need to learn about arrays - see the Reference section.

You also need to realize that you only need 10 cases - 0 to 9.

...R

Don't need cases at all.
Define a fontArray, and use that as the mapping from digits to segments:

byte fontArray[] = {
0b00111111, // 0  1 = segment on, DG-g-f-e-d-c-b-a
0b00000110, // 1             
:                              
:                                   
0b01101111, // 9      
0b00000000, // blank     
};
//    a
// f     b
//    g
// e     c
//    d     DP

Then send the data out, either to a port /digit, a shift register/digit, etc.

PORTF = fontArray[digitToDisplay1];
PORTG = fontArray[digitToDisplay2];
PORTH = fontArray[digitToDisplay3];
PORTK = fontArray[digitToDisplay4];

// or shift register with time elements in an array for example
digitalWrite (latchPin, LOW);
SPI.transfer(fontArray[digits[0]]); // or shiftOut(dataPin, clockPin, MSBFIRST, fontArray[digits[0]]); 
SPI.transfer(fontArray[digits[1]]);
SPI.transfer(fontArray[digits[2]]);
SPI.transfer(fontArray[digits[3]]);
digitalWrite (latchPin, HIGH);

Could you give me an example of how i would get the LED's to light up so that the first display changes ever 10 milliseconds [ cycles through the 9 number ] and then add a number to the next display? thank you so much for your help!

Here's an example of a simple count up timer.
Comment out the serial prints at the end and add the font array and shift register code from earlier replies

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes = 0;
byte oldsecondsOnes;
byte secondsTens = 0;
byte minutesOnes = 0;
byte minutesTens = 0;
byte hoursOnes= 0;
byte hoursTens = 1;

void setup(){

Serial.begin(115200); // make serial monitor match
Serial.println (Setup Done");
}

void loop(){

currentMicros = micros();

// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
previousMicros  = previousMicros + 10000UL;
hundredths = hundredths+1;
if (hundredths == 10){
    hundredths = 0;
    tenths = tenths +1;
    if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
            secondsOnes = 0;
            secondsTens = secondsTens +1;
            if (secondsTens == 6){ 
                secondsTens = 0;
                minutesOnes =  minutesOnes + 1;
                if (minutesOnes == 10){
                    minutesOnes = 0;
                    minutesTens = minutesTens +1;
                    if (minutesTens == 6){
                        minutesTens = 0;
                        hoursOnes = hoursOns + 1;
                          if (hoursOnes == 10){
                              hoursOnes = 0;
                              hoursTens = hoursTens +1;
                                if ( (hoursTens == 2) && (hoursOnes == 4){
                                      hoursOnes = 0;
                                      hoursTens = 0;
                                      if (days>1){
                                          days = days-1;
                                           }
                                      else {
                                         days = 365;
                                         years = years - 1;
                                         }
                                    
                                      } // 24 hr rollover check
                                   } //hoursTens rollover check
                              } // hoursOnes rollover check
                        } // minutesTens rollover check
                     } // minutesOnes rollover check
                 } // secondsTens rollover check
              } // secondsOnes rollover check
          } // tenths rollover check
       } // hundredths rollover check
} // hundredths passing check



if (oldSecondsOnes != secondsOnes){  // show the elapsed time once a second 
oldSecondsOnes = secondsOnes;
Serial.print (years);
Serial.print(":");
Serial.print(days);
Serial.print(":");
Serial.print(hoursTens);
Serial.print(hoursOnes);
Serial.print(":");
Serial.print(minutesTens);
Serial.print(minutesOnes);
Serial.print(":");
Serial.print(secondsTens);
Serial.println(secondsOnes);


} // end one second check


} // end loop

Change this part
if (oldSecondsOnes != secondsOnes){ // show the elapsed time once a second
oldSecondsOnes = secondsOnes;

to look for tenths or hundredths changing if you want faster updates (which will look like the digit being dimly lit all the time until stopped)

@CrossRoads

Here's an example of a simple count up timer.

                                      if (days>1){
                                          days = days-1;
                                           }
                                      else {
                                         days = 365;
                                         years = years - 1;
                                         }

That part looks like it is for a countdown timer.

                        hoursOnes = hoursOns + 1;

Looks like you have a typo there.

But besides that, that's pretty much the approach I would use.

Powerhit22:
Could you give me an example of how i would get the LED's to light up so that the first display changes ever 10 milliseconds [ cycles through the 9 number ] and then add a number to the next display? thank you so much for your help!

What you need to do is separate the number into digits before you display it. There are a few ways to do this. Here is one of my favorites:

int number = 1234; // or whatever number

// variables for digits
int thou, hund, tens, ones;
// variable to help with calculation
int leftover;

// prepare to convert the number into digits
thou = 0; hund = 0; tens = 0;
leftover = number;
// find out how many thousands
while (leftover >= 1000) {
  leftover -= 1000;
  thou++;
}
// find out how many hundreds
while (leftover >= 100) {
  leftover -= 100;
  hund++;
}
// find out how many tens
while (leftover >= 10) {
  leftover -= 10;
  tens++;
}
// whatever is left must be the ones
ones = leftover;

I tried to make this code easy to understand. Please study it carefully so that you understand it. If you have any questions, please ask.

I have not tested this code, so it might have bugs. If you find a bug, please let me know.

Note: The variables thou, hund, tens, and ones are for the individual digits you wish to display. Once you set the number variable to what you want to display, my code will (or should) calculate the actual numerical values of these digits and put them into the correct variables. So rather than displaying the value of number, just display the values of thou, hund, etc., in the appropriate places on the display.

I'm fairly new to coding so Im not quite sure what to do next. This is the coding we have so far.

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes = 0;
byte oldsecondsOnes;
byte secondsTens = 0;
byte minutesOnes = 0;
byte minutesTens = 0;
byte hoursOnes= 0;
byte hoursTens = 1;

void setup(){

Serial.begin(115200); // make serial monitor match
Serial.println (Setup Done");
}

void loop(){

currentMicros = micros();

// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
previousMicros  = previousMicros + 10000UL;
hundredths = hundredths+1;
if (hundredths == 10){
    hundredths = 0;
    tenths = tenths +1;
    if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
            secondsOnes = 0;
            secondsTens = secondsTens +1;
            if (secondsTens == 6){ 
                secondsTens = 0;
                minutesOnes =  minutesOnes + 1;
                if (minutesOnes == 10){
                    minutesOnes = 0;
                    minutesTens = minutesTens +1;
                    if (minutesTens == 6){
                        minutesTens = 0;
                        hoursOnes = hoursOnes + 1;
                          if (hoursOnes == 10){
                              hoursOnes = 0;
                              hoursTens = hoursTens +1;
                                if ( (hoursTens == 2) && (hoursOnes == 4){
                                      hoursOnes = 0;
                                      hoursTens = 0;
                                      if (days>1){
                                          days = days-1;
                                           }
                                      else {
                                         days = 365;
                                         years = years - 1;
                                         }
                                    
                                      } // 24 hr rollover check
                                   } //hoursTens rollover check
                              } // hoursOnes rollover check
                        } // minutesTens rollover check
                     } // minutesOnes rollover check
                 } // secondsTens rollover check
              } // secondsOnes rollover check
          } // tenths rollover check
       } // hundredths rollover check
} // hundredths passing check



if (oldSecondsOnes != secondsOnes){  // show the elapsed time once a second 
oldSecondsOnes = secondsOnes;

byte fontArray[] = {
0b00111111, // 0  1 = segment on, DP-g-f-e-d-c-b-a
0b00000110, // 1             
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111100, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9      
0b00000000, // blank  
0b10000000, // DP
};
//    a
// f     b
//    g
// e     c
//    d     DP


PORTF = fontArray[digitToDisplay1];
PORTG = fontArray[digitToDisplay2];
PORTH = fontArray[digitToDisplay3];
PORTK = fontArray[digitToDisplay4];

// or shift register with time elements in an array for example
digitalWrite (latchPin, LOW);
SPI.transfer(fontArray[digits[0]]); // or shiftOut(dataPin, clockPin, MSBFIRST, fontArray[digits[0]]); 
SPI.transfer(fontArray[digits[1]]);
SPI.transfer(fontArray[digits[2]]);
SPI.transfer(fontArray[digits[3]]);
digitalWrite (latchPin, HIGH);


} // end one second check


} // end loop

We are getting many errors with compiling the code, and I am just too new to coding to quite understand how to fix it.

Also my partner had already wired the Arduino board with the LED's to work for the previous code, but we can easily change the wiring for the new code. It needs to be able to connect to 4 seven segment displays.

You've not set up the code sections properly. This should compile.

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes = 0;
byte oldsecondsOnes;
byte secondsTens = 0;
byte minutesOnes = 0;
byte minutesTens = 0;
byte hoursOnes= 0;
byte hoursTens = 1;

byte fontArray[] = {
0b00111111, // 0  1 = segment on, DP-g-f-e-d-c-b-a
0b00000110, // 1             
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111100, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9      
0b00000000, // blank  
0b10000000, // DP
};
//    a
// f     b
//    g
// e     c
//    d     DP

void setup(){

Serial.begin(115200); // make serial monitor match
Serial.println ("Setup Done");                                    // " was missing
}

void loop(){

currentMicros = micros();

// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
previousMicros  = previousMicros + 10000UL;
hundredths = hundredths+1;
if (hundredths == 10){
    hundredths = 0;
    tenths = tenths +1;
    if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
            secondsOnes = 0;
            secondsTens = secondsTens +1;
            if (secondsTens == 6){ 
                secondsTens = 0;
                minutesOnes =  minutesOnes + 1;
                if (minutesOnes == 10){
                    minutesOnes = 0;
                    minutesTens = minutesTens +1;
                    if (minutesTens == 6){
                        minutesTens = 0;
                        hoursOnes = hoursOnes + 1;
                          if (hoursOnes == 10){
                              hoursOnes = 0;
                              hoursTens = hoursTens +1;
                                if ( (hoursTens == 2) && (hoursOnes == 4){
                                      hoursOnes = 0;
                                      hoursTens = 0;
                                      if (days>1){
                                          days = days-1;
                                           }
                                      else {
                                         days = 365;
                                         years = years - 1;
                                         }
                                    
                                      } // 24 hr rollover check
                                   } //hoursTens rollover check
                              } // hoursOnes rollover check
                        } // minutesTens rollover check
                     } // minutesOnes rollover check
                 } // secondsTens rollover check
              } // secondsOnes rollover check
          } // tenths rollover check
       } // hundredths rollover check
} // hundredths passing check

if (oldSecondsOnes != secondsOnes){  // show the elapsed time once a second 
oldSecondsOnes = secondsOnes;

} // end one second check

// code to drive 7 segment display will go here.
} // end loop

I tool out the display code for the 7 segment display.
What are you using, and how are they wired up?

I know it's not your main concern since you're just working out how to code this. But perhaps it's worth mentioning that a stock Mega will not be very accurate. You'll likely gain or lose something around 1ms every second, depending on your particular board and the temperature.

CrossRoads:
You've not set up the code sections properly. This should compile.

unsigned long currentMicros;

unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes = 0;
byte oldsecondsOnes;
byte secondsTens = 0;
byte minutesOnes = 0;
byte minutesTens = 0;
byte hoursOnes= 0;
byte hoursTens = 1;

byte fontArray[] = {
0b00111111, // 0  1 = segment on, DP-g-f-e-d-c-b-a
0b00000110, // 1           
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111100, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9     
0b00000000, // blank 
0b10000000, // DP
};
//    a
// f    b
//    g
// e    c
//    d    DP

void setup(){

Serial.begin(115200); // make serial monitor match
Serial.println ("Setup Done");                                    // " was missing
}

void loop(){

currentMicros = micros();

// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
previousMicros  = previousMicros + 10000UL;
hundredths = hundredths+1;
if (hundredths == 10){
    hundredths = 0;
    tenths = tenths +1;
    if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
            secondsOnes = 0;
            secondsTens = secondsTens +1;
            if (secondsTens == 6){
                secondsTens = 0;
                minutesOnes =  minutesOnes + 1;
                if (minutesOnes == 10){
                    minutesOnes = 0;
                    minutesTens = minutesTens +1;
                    if (minutesTens == 6){
                        minutesTens = 0;
                        hoursOnes = hoursOnes + 1;
                          if (hoursOnes == 10){
                              hoursOnes = 0;
                              hoursTens = hoursTens +1;
                                if ( (hoursTens == 2) && (hoursOnes == 4){
                                      hoursOnes = 0;
                                      hoursTens = 0;
                                      if (days>1){
                                          days = days-1;
                                          }
                                      else {
                                        days = 365;
                                        years = years - 1;
                                        }
                                   
                                      } // 24 hr rollover check
                                  } //hoursTens rollover check
                              } // hoursOnes rollover check
                        } // minutesTens rollover check
                    } // minutesOnes rollover check
                } // secondsTens rollover check
              } // secondsOnes rollover check
          } // tenths rollover check
      } // hundredths rollover check
} // hundredths passing check

if (oldSecondsOnes != secondsOnes){  // show the elapsed time once a second
oldSecondsOnes = secondsOnes;

} // end one second check

// code to drive 7 segment display will go here.
} // end loop



I tool out the display code for the 7 segment display.
What are you using, and how are they wired up?

we are using the Arduino Mega, and the wiring is this.

#define A 22 // the wires go from the respective pin [in this case pin 22] to the led
#define B 23             //pin 23 to 1st 7 segment display, light B
#define C 24            //pin 24 1st seven segment display, light C
#define D 25            //pin 25
#define E 26            //pin 26
#define F1 27
#define G 28
#define AA 29
#define B2 30
#define C2 31
#define D2 32
#define E2 33
#define F2 34
#define G2 35
#define AB 36
#define B3 37
#define C3 38
#define D3 39
#define E3 40
#define F3 41
#define G3 42
#define AC 43
#define B4 44
#define C4 45
#define D4 46
#define E4 47
#define F4 48
#define G4 49
#define DP 50       //pin 50

is there a way to do the rest of the coding so that it works with this wiring? or do we need to do a different wiring system, and if so what is it?

here are two pictures of the setup as well

Image 1
Image 2

the code also needs to be started by a button [connected to port 13]. this button needs to start the code with the first press, stop it with the second, and reset it with the third. then cycle through it again. thank you so much for helping with the code.

i am not a programmer, and need this code for part of a bigger project that is due soon. thank you for all the help.

the code that you gave me above had many errors. i believe i fixed it but when i try to add in the ports and shifts, i get errors. (we are using 22-53 on the arduino Mega board)

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes = 0;
byte oldsecondsOnes;
byte secondsTens = 0;
byte minutesOnes = 0;
byte minutesTens = 0;
byte hoursOnes= 0;
byte hoursTens = 1;
byte days;
byte years;
byte oldhundredthsOnes;
byte hundredthsOnes;



byte fontArray[] = {
0b00111111, // 0  1 = segment on, DP-g-f-e-d-c-b-a
0b00000110, // 1             
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111100, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9      
0b00000000, // blank  
0b10000000, // DP
};
//    a
// f     b
//    g
// e     c
//    d     DP

void setup(){

Serial.begin(115200); // make serial monitor match
Serial.println ("Setup Done");                                    // " was missing
}

void loop(){

currentMicros = micros();

// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
previousMicros  = previousMicros + 10000UL;
hundredths = hundredths+1;
if (hundredths == 10){
    hundredths = 0;
    tenths = tenths +1;
    if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
            secondsOnes = 0;
            secondsTens = secondsTens +1;
            if (secondsTens == 6){ 
                secondsTens = 0;
                 } // secondsTens rollover check
              } // secondsOnes rollover check
          } // tenths rollover check
       } // hundredths rollover check
 // hundredths passing check

if (oldhundredthsOnes != hundredthsOnes){  // show the elapsed time once every hundredths seconds
oldhundredthsOnes = hundredthsOnes;
}
}


PORTF = fontArray[digitToDisplay1];
PORTG = fontArray[digitToDisplay2];
PORTH = fontArray[digitToDisplay3];
PORTK = fontArray[digitToDisplay4];

// or shift register with time elements in an array for example
digitalWrite (latchPin, LOW);
SPI.transfer(fontArray[digits[0]]); // or shiftOut(dataPin, clockPin, MSBFIRST, fontArray[digits[0]]); 
SPI.transfer(fontArray[digits[1]]);
SPI.transfer(fontArray[digits[2]]);
SPI.transfer(fontArray[digits[3]]);
digitalWrite (latchPin, HIGH);

}