Homework - Stopwatch w/ 3 Push Buttons

Hello,

I'm fairly new to Arduino and I need to write a program for a class that creates a stopwatch using three push buttons. The first pushbutton starts the timer, the second pushbutton pauses the timer, and the third pushbutton resets the timer to zero. If the timer is started and paused and then started again, the program needs to be able to resume the timer from where it was paused. The output is to the serial monitor and must be in the format of HH:MM:SS:MS (all the way to 1/100th of a second). I don't need to actually run this program on an Arduino board, I just need to write the program. I began working on the portion for the timer pausing, but I get lost at that point. I don't know how to have the program hold a value as the loop continues to run (when it's paused) and have time the timer resume from the paused value, since from what I understand millis() will continue to run. What I have so far is below:

const int buttonPin1 = 2;     // define variables
const int buttonPin2 = 3;
const int buttonPin3 = 4;
int buttonState1 = LOW;
int previousButtonState1 = LOW;
int buttonState2 = LOW;
int previousButtonState2 = LOW;
int buttonState3 = LOW;
int previousButtonState3 = LOW;
int starttime = 0;
int currenttime = 0;
int pausedtime = 0;
int H = 0;
int Hr = 0;
int M = 0;
int Mr = 0;
int S = 0;
int Sr = 0;
int MS = 0;


void setup()       //void setup() runs once to initialize variables
{
 Serial.begin(9600); 
 pinMode(buttonPin1, INPUT);
 pinMode(buttonPin2, INPUT);
 pinMode(buttonPin3, INPUT);
 digitalWrite(buttonPin1, LOW);
 digitalWrite(buttonPin2, LOW);
 digitalWrite(buttonPin3, LOW);
}

void loop()            //void loop() runs continuously
{
 starttime = millis();     // start timer
 buttonState1 = digitalRead(buttonPin1);   // read button states
 buttonState2 = digitalRead(buttonPin2);
 buttonState3 = digitalRead(buttonPin3);
 
 if (buttonState1 == LOW && previousButtonState1 == LOW || buttonState1 == HIGH && previousButtonState1 == LOW && buttonState3 == HIGH && previousButtonState3 == LOW)
 // start button not pressed
 {
 H = 0;
 M = 0;
 S = 0;
 MS = 0;

 H = sprintf("%02d",H);
 M = sprintf("%02d",M);
 S = sprintf("%02d",S);
 MS = sprintf("%02d",MS);
 Serial.print(H);
 Serial.print(":");
 Serial.print(M);
 Serial.print(":");
 Serial.print(S);
 Serial.print(".");
 Serial.println(MS);
 delay(1000);
 }
 
 else if(buttonState1 == HIGH && previousButtonState1 == LOW)
 // timer started
 {
 currenttime = millis()-starttime;
 H = round((currenttime / 3600000)-0.5);
 Hr = currenttime % 3600000;
 M = round((Hr / 60000)-0.5);
 Mr = Hr % 60000;
 S = round((Mr / 1000)-0.5);
 Sr = Mr % 3600000;
 MS = round((Sr / 10)-0.5);

 H = sprintf("%02d",H);
 M = sprintf("%02d",M);
 S = sprintf("%02d",S);
 MS = sprintf("%02d",MS);
 Serial.print(H);
 Serial.print(":");
 Serial.print(M);
 Serial.print(":");
 Serial.print(S);
 Serial.print(".");
 Serial.println(MS);
 delay(1000);
}
else if(buttonState1 == HIGH && previousButtonState1 == LOW && buttonState2 == HIGH && previousButtonState2 == LOW)
 // timer paused
 {
  pausedtime = millis()-starttime;
 }

You seriously can't find any examples on Google? That'd be my first step.

Then the program (kudos for posting with code tags in your first post, doesn't happen much): what does it do, and how is this different from what you want it to do?

Your use of sprintf to get leading zeroes is a bit of a sledgehammer to crack a nut.
A single function testing to see if its single parameter is less than ten, and if it is, printing a zero, would be much simpler, and would reduce the memory footprint of your code.

There should be no calls to delay in a stopwatch, IMO.

AWOL:
Your use of sprintf to get leading zeroes is a bit of a sledgehammer to crack a nut.

Handled gently, it does the job just fine.

Spreading it out over a lot of lines though - that's poor use of sprintf. That can all be in a single line, followed by a single Serial.println() call, and then you get actually quite nicely readable code.

just write the pause and resume bit so there is little else going on to confuse you.

as I see it.
if the timer is running
if button3 is pressed
then you need to store the elapsed time

if button3 is pressed again,
you need to start counting again
you need to add the old count to the new count.

if runningFlag=0 then start_time = millis() // this locks in your start time or blocks from reloading

if the start is pressed // system is running
runningFlag = 1 then count = millis()-start_time

if button3 is pressed,
and count3Flag== 0 then count3 = millis()-start_time // stores the elapsed time
count3Flag=1 // prevent this bit from being run again

if button3 is pressed and count3Flag == 1
oldElapsed time = count3
startTime=millis()
count3Flg=0

since the only time oldElaposed time will have a value is after you press button3
you might be able to use
total_time = oldElapsedtime + count
that is not behind any If statments. that way, before you start to display times, your total is ready for use.
if you never touched button3, it would just add 0 and not alter the time.

by using a few flags to indicate what is happening, you know if to add that first time or not.
re-set needs to re-set everything. and make oldElapsedTime = 0

it seems you could use count3Flag ,
if 0 then you load the elapsed time
if 1, then you add the stored elapsed time

sorry if this is more confusing than it needs to be, on my first cup of coffee and rushing to get to work.

it seems to me that your
starttime = millis();
should be behind a flag that locks it in whenever you are actually counting.