Build a Mini Stopwatch Using Arduino
Build a beginner-friendly mini stopwatch with an Arduino Uno, two push buttons, and an LCD1602 display. One button starts and stops the timer, the other resets it, and the LCD shows elapsed seconds with a simple tenths-of-a-second display.

Live project track
Interactive hardware & logic preview
A stopwatch is easy to understand before we even talk about electronics. Press start, time begins moving. Press stop, the number freezes. Press reset, everything goes back to zero. That familiar behavior makes this a friendly project for learning how buttons can control a program.
In this project, you will build a mini stopwatch with an Arduino Uno, two push buttons, and an LCD1602 display. The main concept is simple: the Arduino can remember a running or stopped state, then update the displayed time based on that state.
A Stopwatch Is a Memory Problem, Not Just a Clock
Think about a real stopwatch in your hand. It does not forget what it was doing between button presses. If it is running, it keeps counting. If it is stopped, it keeps showing the last time. If you reset it, it returns to zero and waits.
The Arduino needs the same small memory. In the code, that memory is a variable called
running. When running is true, the stopwatch adds time. When running is false, the stopwatch does not add time. The LCD still updates so the reader can see whether the tool is running or stopped.
Mini stopwatch start stop and reset behavior flow
| User action | Arduino memory | LCD result |
|---|---|---|
| Press start/stop while stopped | running becomes true | Time starts increasing |
| Press start/stop while running | running becomes false | Time freezes |
| Press reset | running becomes false and time becomes zero | LCD shows 0.0 seconds |
This is the first important lesson: the button does not directly make the LCD count. The button changes the program's memory, and the program uses that memory to decide what to do next.
INPUT_PULLUP Makes the Button Read Backwards
Each button uses
INPUT_PULLUP. That setting turns on a small resistor inside the Arduino so the input pin normally stays HIGH. HIGH means the pin is near 5V, so the Arduino reads it as on. When the button is pressed, it connects the pin to GND. GND is the return path for electricity, like the negative terminal of a battery, so the pin reads LOW.This feels backwards at first: not pressed is HIGH, pressed is LOW. The advantage is that the wiring stays simple. Each button only needs one Arduino input pin and one GND connection.

INPUT_PULLUP button logic showing HIGH when open and LOW when pressed
With INPUT_PULLUP, the question is not "is the button HIGH?" The beginner-friendly question is "did the button pull the pin LOW?"The sketch uses that rule for both buttons. If the start/stop button reads LOW, the stopwatch switches between running and stopped. If the reset button reads LOW, the stopwatch stops and the counter returns to zero.
Tenths Make Time Visible With Simple Code
A polished stopwatch can use more precise timing with
millis(), but this beginner version uses a simpler idea. When the stopwatch is running, the code waits 100 milliseconds and adds one to elapsedTenths. One tenth of a second is 0.1 seconds, so ten counts become one full second.The LCD should not show the raw counter directly. If
elapsedTenths is 37, that means 3.7 seconds. The code splits the counter into whole seconds and tenths, then prints them with a decimal point.
Elapsed tenths counter converted into seconds and tenths on LCD
elapsedTenthsstores the total number of 0.1 second steps.secondsstores the whole seconds part.tenthsstores the single digit after the decimal point.
This is not a laboratory-grade stopwatch, and that is okay. It is designed to teach the control idea clearly: button input changes the stopwatch state, and the state decides whether time should advance.
Two Buttons and One LCD Create the Stopwatch Controls
The circuit has three jobs. The start/stop button controls whether time should move. The reset button clears the saved time. The LCD shows the current time and the current mode.
5V is the positive power supply from the Arduino. The LCD uses it for its logic and backlight. GND is the shared return path. The buttons also connect to GND because the sketch uses INPUT_PULLUP, where a press pulls the input pin LOW. Pin Connection Map
Start/Stop Button
Pin 1
→
Arduino Uno
D6
Explanation
Carries the start/stop button signal into the Arduino.
Start/Stop Button
Pin 2
→
Arduino Uno
GND
Explanation
Pulls D6 LOW when the button is pressed.
Pin Connection Map
Reset Button
Pin 1
→
Arduino Uno
D7
Explanation
Carries the reset button signal into the Arduino.
Reset Button
Pin 2
→
Arduino Uno
GND
Explanation
Pulls D7 LOW when the button is pressed.
Pin Connection Map
LCD1602
VSS
→
Arduino Uno
GND
Explanation
Ground for the LCD logic.
LCD1602
VDD
→
Arduino Uno
5V
Explanation
Power for the LCD logic.
LCD1602
V0
→
Arduino Uno
GND
Explanation
Sets a simple readable contrast level in this simulator circuit.
LCD1602
RW
→
Arduino Uno
GND
Explanation
Keeps the LCD in write mode so Arduino sends text to it.
LCD1602
RS
→
Arduino Uno
D12
Explanation
Chooses whether the LCD receives a command or display text.
LCD1602
E
→
Arduino Uno
D11
Explanation
Tells the LCD to accept the current data.
LCD1602
D4
→
Arduino Uno
D5
Explanation
First data line used by the LCD in 4-bit mode.
LCD1602
D5
→
Arduino Uno
D4
Explanation
Second data line used by the LCD in 4-bit mode.
LCD1602
D6
→
Arduino Uno
D3
Explanation
Third data line used by the LCD in 4-bit mode.
LCD1602
D7
→
Arduino Uno
D2
Explanation
Fourth data line used by the LCD in 4-bit mode.
LCD1602
A
→
Arduino Uno
5V
Explanation
Power for the LCD backlight.
LCD1602
K
→
Arduino Uno
GND
Explanation
Ground for the LCD backlight.
If a button seems to work backwards, that is normal with INPUT_PULLUP. Pressed reads LOW, not HIGH.The Complete Mini Stopwatch Sketch
This sketch keeps the code intentionally simple. It uses
delay() for timing, two button inputs, one running flag, and one counter that stores tenths of a second. The result is easy to read and easy to modify.A more accurate stopwatch would use
millis(), but this beginner version focuses on the control pattern first: start, stop, reset, and display. The small button pause is a simple beginner-friendly way to avoid one quick tap being read many times.C++ Source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <LiquidCrystal.h>
const int startStopButtonPin = 6;
const int resetButtonPin = 7;
const int rs = 12;
const int en = 11;
const int d4 = 5;
const int d5 = 4;
const int d6 = 3;
const int d7 = 2;
const int countDelayMs = 100;
const int buttonPauseMs = 300;
const int idleDelayMs = 50;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
bool running = false;
int elapsedTenths = 0;
void setup() {
pinMode(startStopButtonPin, INPUT_PULLUP);
pinMode(resetButtonPin, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.print("Mini Stopwatch");
lcd.setCursor(0, 1);
lcd.print("Ready");
delay(1000);
}
void loop() {
if (digitalRead(startStopButtonPin) == LOW) {
if (running) {
running = false;
} else {
running = true;
}
delay(buttonPauseMs);
}
if (digitalRead(resetButtonPin) == LOW) {
running = false;
elapsedTenths = 0;
delay(buttonPauseMs);
}
if (running) {
delay(countDelayMs);
elapsedTenths = elapsedTenths + 1;
} else {
delay(idleDelayMs);
}
int seconds = elapsedTenths / 10;
int tenths = elapsedTenths - seconds * 10;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(seconds);
lcd.print(".");
lcd.print(tenths);
lcd.print("s");
lcd.setCursor(0, 1);
if (running) {
lcd.print("Running");
} else {
lcd.print("Stopped");
}
}How the Mini Stopwatch Code Works, Part By Part
Now let us break the sketch into smaller pieces. Each piece has one job: name the pins, prepare the LCD and buttons, respond to button presses, count time, and print the result.
▸ Mini Stopwatch Pins Name the Two Controls
The sketch starts by naming the two button pins and the six LCD pins. Pin numbers are the physical Arduino connectors used by the wires. Naming them at the top makes the wiring and code easier to compare.
C++ Source
1
2
3
4
5
6
7
8
9
const int startStopButtonPin = 6;
const int resetButtonPin = 7;
const int rs = 12;
const int en = 11;
const int d4 = 5;
const int d5 = 4;
const int d6 = 3;
const int d7 = 2;▸ Stopwatch Variables Remember Time and Mode
running stores whether the stopwatch should count. elapsedTenths stores the elapsed time as tenths of a second. Keeping these values separate makes the logic easier: one variable answers "should I count?" and the other answers "how much time has passed?"C++ Source
1
2
bool running = false;
int elapsedTenths = 0;▸ Setup Turns On Pullup Buttons
In
setup(), both button pins use INPUT_PULLUP. INPUT means the Arduino listens to the pin. The pullup part keeps the input stable without adding external resistors. The LCD also starts here with lcd.begin(16, 2), which tells the library the display has 16 columns and 2 rows.C++ Source
1
2
3
4
5
6
7
8
9
10
void setup() {
pinMode(startStopButtonPin, INPUT_PULLUP);
pinMode(resetButtonPin, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.print("Mini Stopwatch");
lcd.setCursor(0, 1);
lcd.print("Ready");
delay(1000);
}▸ Start Button Flips the Running Flag
When the start/stop button reads LOW, the code changes
running. If it was false, it becomes true. If it was true, it becomes false. The short button pause gives your finger time to lift so one quick tap does not get read many times.C++ Source
1
2
3
4
5
6
7
8
9
if (digitalRead(startStopButtonPin) == LOW) {
if (running) {
running = false;
} else {
running = true;
}
delay(buttonPauseMs);
}▸ Reset Button Clears the Count
The reset button is more direct. It stops the stopwatch and sets
elapsedTenths back to zero. That matches the behavior people expect: reset should not leave the timer running in the background.C++ Source
1
2
3
4
5
if (digitalRead(resetButtonPin) == LOW) {
running = false;
elapsedTenths = 0;
delay(buttonPauseMs);
}▸ Running Mode Adds One Tenth
If
running is true, the sketch waits 100 milliseconds and adds one to the counter. If the stopwatch is stopped, the sketch waits only a short idle delay before checking the buttons again.C++ Source
1
2
3
4
5
6
if (running) {
delay(countDelayMs);
elapsedTenths = elapsedTenths + 1;
} else {
delay(idleDelayMs);
}▸ Counter Splits Into LCD Time
The counter is stored as tenths, but the LCD should show seconds and tenths. Integer division gives the whole seconds. Then the code subtracts those whole seconds from the original counter to get the one tenths digit.
C++ Source
1
2
3
4
5
6
7
8
9
10
int seconds = elapsedTenths / 10;
int tenths = elapsedTenths - seconds * 10;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(seconds);
lcd.print(".");
lcd.print(tenths);
lcd.print("s");▸ Second Row Shows the Current Mode
The second LCD row tells the learner whether the stopwatch is running or stopped. This tiny label is helpful because it confirms that the button press changed the program's memory, not just the number on the screen.
C++ Source
1
2
3
4
5
6
lcd.setCursor(0, 1);
if (running) {
lcd.print("Running");
} else {
lcd.print("Stopped");
}Making the Stopwatch Feel More Responsive
This beginner stopwatch is intentionally simple, so it counts in visible 0.1 second steps. After a button press, the code pauses briefly before reading again. That makes quick taps easier to handle, but it also means this version is more educational than ultra-precise.
When you are ready to go deeper, the next version should use
millis(). That would let the Arduino check buttons and update time without pausing the whole sketch. For this first version, the simpler delay-based timing keeps the main idea easy to see.Taking It Further
Once the basic stopwatch works, you can add a lap button that stores the current time without stopping the counter. You can also add a buzzer click when the start/stop button is pressed so the stopwatch gives both visual and audio feedback.
Another natural upgrade is a countdown timer. Instead of counting up from zero, the Arduino could start from a chosen number and count down until the LCD shows zero.
Project Category
Keywords
#Arduino #Stopwatch #Timer #Push Button #LCD #Beginner #Input
Total word count: 1363 words
More in Arduino Uno
Continue exploring this hardware category
More in Pushbutton
Continue exploring this hardware category
More in LCD Display
Continue exploring this hardware category
Project discussion
Questions, feedback, and community insights
No discussions yet. Be the first to start!








