/* Arduino program to make a stopwatch. The circuit consists of three pushbuttons
with the following functions: start, pause and stop. It then counts the time up
with up to 1/1000th of a second accuracy. The stopwatch can be paused and resumed
with the pause button and stopped with the stop button.
The push buttons are connected to the pins as declared in the below constants: */
// pushbutton pins:
const int startButtonPin = 2;
const int pauseButtonPin = 3;
const int stopButtonPin = 4;
/* declaration of variables that store the time the start button, pause button was pressed
as well as the currently elapsed time during pause, the total elapsed time, as well as the
total pause time:*/
unsigned long startTime;
unsigned long pauseTime;
unsigned long pausedTime;
unsigned long elapsedTime;
unsigned long totalPausedTime;
// data type for these is unsigned long, as this is what millis() returns, i.e. the elapsed ms since start
// declarations of variables that store the stopwatch state and pause state
int stopwatchState;
int pauseState;
// declaration of variables that store the states of each button as well as the previous states (for toggling)
int startButtonState;
int prevStartButtonState;
int stopButtonState;
int prevStopButtonState;
int pauseButtonState;
int prevPauseButtonState;
// integer variables to store the hours, minutes, seconds and milliseconds
int hours;
int minutes;
int seconds;
int milliseconds;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // opens serial port for console print
pinMode(startButtonPin, INPUT); // sets up start button as input
pinMode(pauseButtonPin, INPUT); // sets up pause button as input
pinMode(stopButtonPin, INPUT); // sets up stop button as input
}
void loop() {
// put your main code here, to run repeatedly:
startButtonState = digitalRead(startButtonPin); // reads the value of the start button
if (startButtonState == HIGH && prevStartButtonState == LOW) { // if start button was toggled
if (stopwatchState == LOW) { // if the stopwatch is not running
stopwatchState = HIGH; // set the stopwatch to running
}
else { // else do nothing
}
startTime = millis(); // saves the start time point in the variable
}
prevStartButtonState = startButtonState; // sets previous state to current state
stopButtonState = digitalRead(stopButtonPin); // reads the value of the stop button
if (stopButtonState == HIGH && prevStopButtonState == LOW) { // if stop button was toggled
if (stopwatchState == LOW) { // if stopwatch is not running and the stop button is pressed again, reset the times
pausedTime = 0;
elapsedTime = 0;
}
else { // else stop the stopwatch
stopwatchState = LOW;
}
}
prevStopButtonState = stopButtonState; // sets previous state to current state
pauseButtonState = digitalRead(pauseButtonPin); // reads the value of the pause button
if (pauseButtonState == HIGH && prevPauseButtonState == LOW) { // if the pause button was off and is pressed then
if (pauseState == LOW) { // if the watch is not paused, set the watch to paused and store the pause time point
pauseState = HIGH;
pauseTime = millis();
}
else { // else resume the watch and calculate the total pause time
pauseState = LOW;
totalPausedTime = totalPausedTime + pausedTime;
}
}
prevPauseButtonState = pauseButtonState; // sets previous state to current state
if (stopwatchState == HIGH && pauseState == LOW){ // if the stopwatch is on and not paused:
elapsedTime = millis() - startTime - totalPausedTime; // calculate the total elapsed time with total paused time
} else if (stopwatchState == HIGH && pauseState == HIGH) { // if it is paused:
pausedTime = millis() - pauseTime; // calculate total elapsed time using the current pause time
}
// Calculate hours, minutes, seconds, and milliseconds
hours = elapsedTime / 3600000;
elapsedTime %= 3600000; // store remainder for minutes
minutes = elapsedTime / 60000;
elapsedTime %= 60000; // store remainder for seconds
seconds = elapsedTime / 1000;
milliseconds = elapsedTime % 1000; // rest is milliseconds
// Display the time on the Serial Monitor in the specified format
Serial.print(hours < 10 ? "0" : ""); // only display leading zero if hours is less than 10
Serial.print(hours);
Serial.print(":");
Serial.print(minutes < 10 ? "0" : ""); // only display leading zero if minutes is less than 10
Serial.print(minutes);
Serial.print(":");
Serial.print(seconds < 10 ? "0" : ""); // only display leading zero if seconds is less than 10
Serial.print(seconds);
Serial.print(":");
Serial.println(milliseconds);
}