BeginnerArduinoArduino UnoTM16377-Segment Display

4-Digit 7-Segment Counter with TM1637 & Arduino

Drive a TM1637-based 4-digit 7-segment display with Arduino Uno to show a real-time up/down counter, elapsed timer, and scrolling text. Covers library setup, brightness control, and custom segment mapping.

Circuit Hub16 min read2 views

Overview

The TM1637 is a dedicated LED driver IC that controls a 4-digit 7-segment display over a simple 2-wire protocol (CLK + DIO). It handles all the segment multiplexing internally, which means your Arduino only needs two GPIO pins and a tiny library to display any number from 0000 to 9999, show a colon separator, or write raw segments.

In this project we'll build three modes:

  1. Stopwatch — counts elapsed seconds since boot
  2. Up/Down counter — two buttons increment and decrement
  3. Countdown timer — 60-second countdown with buzzer at zero

💡 Tip

Install the **TM1637Display** library by Avishkar (search 'TM1637' in Arduino Library Manager). The `display.showNumberDecEx()` method handles the colon and leading-zero padding in a single call.

Components required

Arduino Uno R3
×1Buy
TM1637 4-Digit 7-Segment Display Module
×1Buy
Tactile Push Button (6 mm)
×2
10 kΩ Resistors (pull-down)
×2
5V Active Buzzer
×1
Breadboard + Jumper Wires
×1

Wiring

The TM1637 module already includes current-limiting resistors on each segment, so direct wiring is safe:

| TM1637 Pin | Arduino Pin | |-----------|-------------| | CLK | D2 | | DIO | D3 | | VCC | 5V | | GND | GND |

Button A (increment) → D5 with 10 kΩ pull-down to GND.
Button B (decrement) → D6 with 10 kΩ pull-down to GND.
Buzzer + → D7.

C++
// ── TM1637 Multi-Mode Counter ─────────────────────────────────────────────────
// Modes: 0=Stopwatch  1=Up/Down Counter  2=60s Countdown
// ─────────────────────────────────────────────────────────────────────────────
#include <TM1637Display.h>

#define CLK          2
#define DIO          3
#define BTN_UP       5
#define BTN_DOWN     6
#define BUZZER       7

TM1637Display display(CLK, DIO);

// ── State ────────────────────────────────────────────────────────────────────
int  mode         = 0;      // 0=stopwatch 1=counter 2=countdown
int  counter      = 0;      // up/down counter value
int  countdown    = 60;     // countdown seconds remaining
bool colonOn      = true;   // colon blink state (stopwatch)

unsigned long lastSecond  = 0;
unsigned long lastDebounce = 0;
const unsigned long DEBOUNCE_MS = 200;

bool btnPressed(int pin) {
  if (millis() - lastDebounce < DEBOUNCE_MS) return false;
  if (digitalRead(pin) == HIGH) {
    lastDebounce = millis();
    return true;
  }
  return false;
}

void buzz(int ms = 80) {
  digitalWrite(BUZZER, HIGH);
  delay(ms);
  digitalWrite(BUZZER, LOW);
}

void setup() {
  pinMode(BTN_UP,  INPUT);
  pinMode(BTN_DOWN, INPUT);
  pinMode(BUZZER,  OUTPUT);
  display.setBrightness(4);  // 0–7
  display.showNumberDec(0, true);
}

void loop() {
  unsigned long now = millis();

  // ── Mode 0: Stopwatch ────────────────────────────────────────────────────
  if (mode == 0) {
    if (now - lastSecond >= 1000) {
      lastSecond = now;
      counter++;
      colonOn = !colonOn;
      // Show MM:SS
      int mins = (counter / 60) % 100;
      int secs = counter % 60;
      int mmss = mins * 100 + secs;
      // 0x40 = colon bit for showNumberDecEx
      display.showNumberDecEx(mmss, colonOn ? 0x40 : 0x00, true);
    }
    if (btnPressed(BTN_UP))   { mode = 1; counter = 0; }
    if (btnPressed(BTN_DOWN)) { mode = 2; counter = 0; countdown = 60; }
  }

  // ── Mode 1: Up/Down Counter ──────────────────────────────────────────────
  else if (mode == 1) {
    if (btnPressed(BTN_UP))   { counter = min(counter + 1, 9999); buzz(); }
    if (btnPressed(BTN_DOWN)) { counter = max(counter - 1, -999); buzz(); }
    display.showNumberDec(counter, false);
  }

  // ── Mode 2: Countdown Timer ──────────────────────────────────────────────
  else if (mode == 2) {
    if (now - lastSecond >= 1000 && countdown > 0) {
      lastSecond = now;
      countdown--;
      display.showNumberDecEx(countdown, 0x00, true);
      if (countdown == 0) {
        // 3 loud beeps at zero
        for (int i = 0; i < 3; i++) { buzz(200); delay(200); }
        mode = 0; counter = 0;
      }
    }
    // Hold both buttons to restart countdown
    if (digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) {
      countdown = 60;
      display.showNumberDec(60, true);
      delay(500);
    }
  }
}

Live simulation

Steps

  1. 1Install 'TM1637Display' via Arduino Library Manager (search: TM1637)
  2. 2Wire the display and buttons per the table above
  3. 3Upload the sketch — the display should show '0000' on boot
  4. 4Mode 0 starts automatically as a MM:SS stopwatch
  5. 5Press BTN_UP to switch to Up/Down Counter mode
  6. 6Press BTN_DOWN to switch to 60-second Countdown mode
  7. 7In Countdown mode, hold both buttons simultaneously to reset to 60s

Related projects