A real stopwatch you can use to time races, puzzles or experiments. It counts up to 999.9 seconds in tenths of a second. One button starts and stops it, the other resets it to zero. You'll learn multiplexing, the trick behind almost every LED display.
What you need
- UNO R3 board and USB cable
- 4-digit 7-segment display (common cathode)
- 4 resistors, 220 Ω
- 2 push buttons
- Breadboard and jumper wires (all from the UNO R3 Starter Kit)
Display pins
Place the display across the middle gap with the decimal points at the bottom. Most 12-pin 4-digit displays use the pin order below, with pin 1 at the bottom-left, counting anticlockwise. If yours is different, check the code on its side and look up its pinout.
Wiring

| Display pin | Function | UNO pin |
|---|---|---|
| 11 | Segment a | 2 |
| 7 | Segment b | 3 |
| 4 | Segment c | 4 |
| 2 | Segment d | 5 |
| 1 | Segment e | 6 |
| 10 | Segment f | 7 |
| 5 | Segment g | 8 |
| 3 | Decimal point | 9 |
| 12 | Digit 1 | 10 (through 220 Ω) |
| 9 | Digit 2 | 11 (through 220 Ω) |
| 8 | Digit 3 | 12 (through 220 Ω) |
| 6 | Digit 4 | 13 (through 220 Ω) |
| Button | Connect to |
|---|---|
| Start / stop | UNO A0 and GND |
| Reset | UNO A1 and GND |
Build it step by step
- Place the display across the centre gap, decimal points down.
- Add the four 220 Ω resistors for the digit pins (12, 9, 8 and 6).
- Connect the eight segment pins to UNO pins 2 to 9.
- Connect the digit resistors to pins 10 to 13.
- Add the two buttons to A0 and A1, with their other side to GND.
- Upload the code. Press start/stop to run and pause, and reset to clear.
The code
const int SEG_PINS[8] = {2, 3, 4, 5, 6, 7, 8, 9}; // a, b, c, d, e, f, g, dp
const int DIGIT_PINS[4] = {10, 11, 12, 13}; // digits 1 to 4
const int START_BUTTON = A0;
const int RESET_BUTTON = A1;
// Segment patterns for 0-9 (bit 0 = a ... bit 6 = g)
const byte NUMBERS[10] = {
0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110,
0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111
};
bool running = false;
unsigned long startTime = 0;
unsigned long elapsed = 0;
bool lastStart = HIGH;
bool lastReset = HIGH;
void showDigit(int position, byte pattern) {
for (int s = 0; s < 8; s++) digitalWrite(SEG_PINS[s], bitRead(pattern, s));
digitalWrite(DIGIT_PINS[position], LOW); // common cathode: LOW turns the digit on
delayMicroseconds(2500);
digitalWrite(DIGIT_PINS[position], HIGH);
}
void showTenths(unsigned long tenths) {
tenths = tenths % 10000; // 0 to 9999 = 000.0 to 999.9 s
showDigit(0, NUMBERS[tenths / 1000 % 10]);
showDigit(1, NUMBERS[tenths / 100 % 10]);
showDigit(2, NUMBERS[tenths / 10 % 10] | 0b10000000); // decimal point
showDigit(3, NUMBERS[tenths % 10]);
}
void setup() {
for (int s = 0; s < 8; s++) pinMode(SEG_PINS[s], OUTPUT);
for (int d = 0; d < 4; d++) {
pinMode(DIGIT_PINS[d], OUTPUT);
digitalWrite(DIGIT_PINS[d], HIGH); // all digits off
}
pinMode(START_BUTTON, INPUT_PULLUP);
pinMode(RESET_BUTTON, INPUT_PULLUP);
}
void loop() {
bool startNow = digitalRead(START_BUTTON);
if (lastStart == HIGH && startNow == LOW) {
if (running) {
elapsed += millis() - startTime; // pause
running = false;
} else {
startTime = millis(); // start or continue
running = true;
}
}
lastStart = startNow;
bool resetNow = digitalRead(RESET_BUTTON);
if (lastReset == HIGH && resetNow == LOW) {
running = false;
elapsed = 0;
}
lastReset = resetNow;
unsigned long total = elapsed + (running ? millis() - startTime : 0);
showTenths(total / 100); // milliseconds to tenths
}
How it works
The display has 32 LEDs but only 12 pins: the eight segment lines are shared by all four digits. Multiplexing lights one digit at a time, for 2.5 ms each, and repeats so fast that your eyes see all four at once. The resistors sit on the digit pins, so each UNO pin only ever carries a small current. The stopwatch itself uses millis(), the time since the board started, so it stays accurate even while the display is busy.
Make it your own
- Hide leading zeros so it shows " 5.3" instead of "005.3".
- Add a lap button that freezes the display while the time keeps running.
- Turn it into a countdown timer that beeps with the active buzzer at zero.
Troubleshooting
- Wrong segments light up: your display may use a different pinout. Check the code on its side and swap the segment wires to match.
- Nothing lights up: your display may be common anode. Swap HIGH and LOW for the digit pins and invert the segment patterns.
-
A button starts and stops several times: add
delay(50)after detecting a press to ignore contact bounce.
Learn the basics first
New to these parts? These lessons explain them step by step: Set up the Arduino IDE and blink an LED and Make a tilt alarm with a buzzer (pull-up inputs).
0 comments