4-digit stopwatch

Build a stopwatch on the 4-digit 7-segment display that counts in tenths of a second, with start/stop and reset buttons.
  • Level:Intermediate
  • Duration: 1 h 15 min
  • Ages 12+
  • Platform: Arduino
Community project EEMENTOR team
4-digit stopwatch – EEMENTOR STEM™ project

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

Breadboard wiring diagram: 4-digit stopwatch
Breadboard view. Check each connection against the wiring table below.
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

  1. Place the display across the centre gap, decimal points down.
  2. Add the four 220 Ω resistors for the digit pins (12, 9, 8 and 6).
  3. Connect the eight segment pins to UNO pins 2 to 9.
  4. Connect the digit resistors to pins 10 to 13.
  5. Add the two buttons to A0 and A1, with their other side to GND.
  6. 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

Leave a comment

Please note, comments need to be approved before they are published.

Build it yourself

Get the parts used in this project, tested by our engineers.

UNO R3 Starter Kit | Arduino IDE Compatible | Free Tutorials $56.00

Shop the parts

More projects

  • Pulse visualiser

    • Level:Intermediate
    • Duration: 45 min
    • Platform: Arduino

    by EEMENTOR team

  • Flame alarm

    • Level:Beginner
    • Duration: 40 min
    • Platform: Arduino

    by EEMENTOR team

Community projects

Built something awesome? Share it.

Send us your project and we'll feature it in the hub, credited to you, so other makers can learn from it.

  1. Sign in and tell us about your build
  2. Our team reviews your submission
  3. We publish it in the hub, credited to you