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