Whether you are making a digital clock, a timer, a counter, or a simple sensor project, you need an easy way to show numbers clearly. That is where the TM1637 display module becomes very useful. It gives you a bright 4-digit 7-segment display that can work nicely with the ESP32, while keeping the wiring and coding simple.
In this tutorial, you will learn how to connect the TM1637 module to an ESP32, install the required library, and write code to display numbers and simple symbols.
Let’s dive in!
TM1637 Module Hardware Overview
The TM1637 module combines two parts in one package: a 0.36-inch 4-digit 7-segment display with the TM1637 LED driver chip made by Titan MicroElectronics. This cool combination lets you control all four digits using just two pins from your microcontroller.

This module is great for projects where you want to display numbers clearly, such as clocks, timers, counters, scoreboards, temperature displays, or sensor readings. Many TM1637 modules also include a colon in the middle, which is especially helpful when making a digital clock.
One reason the TM1637 module is so popular is that it takes care of the hard work of refreshing the display by itself. That means the ESP32 does not need to constantly update every segment again and again. As a result, your program stays simpler and the ESP32 can spend more time doing other important tasks.

Another nice thing is that the TM1637 module can work with both 3.3V and 5V. This makes it compatible with both 3.3V microcontrollers like the ESP32 and 5V microcontrollers like the regular Arduino.
The amount of power the module uses depends on how many segments are lit and the brightness level you set. When all segments are lit at maximum brightness, the module uses about 80 mA of current. You can save power by adjusting the display’s brightness to a lower level.
The module uses its own special two-wire communication protocol. While this isn’t a standard protocol like I2C, there are easy-to-use Arduino libraries available that hide all the complicated stuff and make it simple to communicate with the display.
Technical Specifications
Here are the specifications:
| Operating voltage | 3.3 – 5 VDC |
| Maximum Current Draw | 80mA |
| Reverse polarity protection | Yes |
| Display Size | 42 mm x 24 mm (1.65″ x .95″) |
| Display Height | 12 mm (0.47″) (typical) |
| Character Height | 9.14 mm (0.36″) |
For more detailed information about the TM1637 driver chip, please refer to the datasheet below.
TM1637 Module Pinout
The TM1637 module has only four pins, making it very simple to use. Here is the pinout:

CLK is the clock input pin.
DIO is the data input/output (I/O) pin.
VCC is the power supply pin. Connect it to a 3.3V to 5V power source.
GND is the ground pin.
Wiring the TM1637 Module to an ESP32
Connecting the TM1637 module to an ESP32 is simple because the module only has four pins. Two pins are used for power, and the other two are used for communication.
Start by connecting the VCC pin of the TM1637 module to the VIN pin of the ESP32. Then connect the GND pin of the module to a GND pin on the ESP32. After that, connect the CLK pin of the module to GPIO 26 on the ESP32, and connect the DIO pin of the module to GPIO 25.
Here’s a quick reference table for the pin connections:
| TM1637 Module | ESP32 | |
| VCC | VIN | |
| GND | GND | |
| DIO | 25 | |
| CLK | 26 |
This diagram shows you exactly how to connect everything:

Setting Up the Arduino IDE
We will be using the Arduino IDE to program the ESP32, so please ensure you have the ESP32 add-on installed before you proceed:
Library Installation
To communicate with the TM1637 chip, you will need to use a library. A great option is the TM1637Display library created by Avishay Orpaz. This library has many built-in functions that make controlling the display simple and straightforward.
To install the library,
- First open your Arduino IDE program. Then click on the Library Manager icon on the left sidebar.
- Type “tm1637” in the search box to filter your results.
- Look for the TM1637 library by Avishay Orpaz.
- Click the Install button to add it to your Arduino IDE.

Once the library is installed, you’re all set and ready for programming!
Example – Basic Display Test
Now let’s try a simple test program. This example helps you check that your TM1637 display is wired correctly and working with the ESP32.
The program will show different patterns and numbers on the display, such as turning all segments on, counting from 0 to 9, showing negative numbers, lighting the colon, and finally displaying the word “dOnE.”
#include <TM1637Display.h>
// TM1637 connections to ESP32
#define CLK 26
#define DIO 25
// Create display object
TM1637Display display(CLK, DIO);
// An array that turns every segments ON
const uint8_t allON[] = { 0xff, 0xff, 0xff, 0xff };
// An array that sets individual segments per digit to display the word "dOnE"
const uint8_t done[] = {
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O
SEG_C | SEG_E | SEG_G, // n
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G // E
};
// An array that displays the °C symbol
const uint8_t celsius[] = {
SEG_A | SEG_B | SEG_F | SEG_G, // degree symbol
SEG_A | SEG_D | SEG_E | SEG_F // C
};
void setup() {
// Start with a medium brightness
// Brightness range is 0 (dimmest) to 7 (brightest)
display.setBrightness(5);
// Set every segments ON
display.setSegments(allON);
delay(2000);
// Clear the display
display.clear();
// Count from 0 to 9
for (int i = 0; i < 10; i++) {
display.showNumberDec(i);
delay(200);
}
delay(1000);
display.clear();
// Show negative numbers
display.showNumberDec(-12); // shows " -12"
delay(2000);
display.clear();
display.showNumberDec(-999); // shows "-999"
delay(2000);
display.clear();
// Show number without leading zeros
display.showNumberDec(31, false); // shows " 31"
delay(2000);
display.clear();
// Show number with leading zeros
display.showNumberDec(31, true); // shows "0031"
delay(2000);
display.clear();
// Show number in the middle
display.showNumberDec(14, false, 2, 1); // shows " 14 "
delay(2000);
display.clear();
// Show a negative number in the middle
display.showNumberDec(-5, false, 2, 1); // shows " -5 "
delay(2000);
display.clear();
// Show 12:34 using the colon
display.showNumberDecEx(1234, 0b01000000, false, 4, 0);
delay(2000);
display.clear();
// Show 15°C
int temperature = 15;
display.showNumberDec(temperature, false, 2, 0);
display.setSegments(celsius, 2, 2);
delay(2000);
display.clear();
// Show dOnE
display.setSegments(done);
}
void loop() {
}Upload this code to your ESP32. If everything is connected properly, the display should go through a short test sequence and end by showing dOnE.

Code Explanation:
We begin by including the TM1637 library, and telling the program which two ESP32 pins are connected to the display module — one for the clock (CLK) and the other for the data input/output (DIO).
#include <TM1637Display.h>
// TM1637 connections to ESP32
#define CLK 26
#define DIO 25Next, we create a display object from the TM1637Display class. This object lets us send commands to the TM1637. When we create the object, we have to tell it which two pins we are using.
// Create display object
TM1637Display display(CLK, DIO);The TM1637 library lets us control each segment of the display individually. This is how we can show numbers, letters, and even a few simple symbols on the screen.
To demonstrate this, we prepare three arrays. These arrays store the segment patterns that tell the display which LEDs should turn on.
The first array turns on all the segments. The second array creates the word “dOnE”, and the third creates the “°C” symbol. We use a function called setSegments() to send these arrays to the display and show them.
There are two ways to define these arrays.
1. Using hexadecimal numbers: When you use this method, you create the hex number following a specific order for the segments: (dot) G F E D C B A. Each letter stands for one segment on the display, and each segment can either be on (1) or off (0).
For example, the hex number 0xFF (which is 11111111 in binary) turns on all the segments, including the dot. On the other hand, 0x00 (which is 00000000 in binary) turns off all the segments.
If you want to display the letter “C,” you would use the hex number 0x39. In binary, that’s 00111001. This pattern turns on segments A, D, E, and F, while leaving the others off.
// An array that turns every segments ON
const uint8_t allON[] = { 0xff, 0xff, 0xff, 0xff };2. Using segment names: The second way to create these arrays is even simpler. We can just list the segment names we want to turn on, using names like SEG_A, SEG_B, SEG_C, and so on.
// An array that sets individual segments per digit to display the word "dOnE"
const uint8_t done[] = {
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O
SEG_C | SEG_E | SEG_G, // n
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G // E
};
// An array that displays the °C symbol
const uint8_t celsius[] = {
SEG_A | SEG_B | SEG_F | SEG_G, // degree symbol
SEG_A | SEG_D | SEG_E | SEG_F // C
};In the setup() section of the code, we use several functions from the TM1637 library:
setBrightness(brightness,on)
This function controls the brightness of the display. You can choose any value between 0 (very dim) and 7 (very bright).
There’s also an optional second part you can add: if you pass false, it will turn off the display; if you pass true or leave it out, the display stays on. So when you write display.setBrightness(5), you are setting the brightness to a medium level. If you write display.setBrightness(5, false), you are actually turning the display off, even though you chose a brightness level.
setSegments(segments[],length,position)
This function lets you control individual segments of the display. We give it three pieces of information: the array that holds the information about which segments to light up, how many digits we want to update (from 0 to 4), and where the number should start on the display (position 0 is the leftmost digit, and position 3 is the rightmost).
Note that the second and third arguments are optional. If you want to update the entire display without worrying about length or position, you can just skip them. For example, when we want to display the word “dOnE,” we are lighting up all 4 digits starting from the leftmost position (position 0). So, we simply call the function like this:
// Prints dOnE
display.setSegments(done);But sometimes we don’t want to update all four digits. For example, when we want to show the “°C” symbol, we only want to update the last two digits. In that case, we also tell the function how many digits (2) and from which position (2) to start.
// Prints __°C
display.setSegments(celsius, 2, 2);showNumberDec(number,leading_zeros,length,position)
Another very important function we use is showNumberDec(). This function is great for quickly displaying numbers. We just tell it which number we want to show, and it figures out which segments to light up. For example, if you want to count from 0 to 9, you can use a loop with showNumberDec() like this:
// Show counter 0-9
int i;
for (i = 0; i < 10; i++) {
display.showNumberDec(i);
delay(50);
}You can also use this function to display negative numbers. It will automatically add the minus sign in the right place:
display.showNumberDec(-12); // Prints _-12
display.showNumberDec(-999); // Prints -999The second argument controls whether or not you want to add leading zeros. If you set this to true, the display will add zeros in front to make the number fit all four digits. If you set it to false, it will just show the number as-is.
display.showNumberDec(31, false); // Prints __31
display.showNumberDec(31, true); // Prints 0031The third and fourth arguments work the same way as before. They let you decide how many digits you want to update and where the number should start on the display. So, if you want the number to appear centered in the display, you would write:
display.showNumberDec(14, false, 2, 1); // Prints _14_
display.showNumberDec(-5, false, 2, 1); // Prints _-5_showNumberDecEx(number,dots,leading_zeros,length,position)
This function is an extended version of showNumberDec(). The main difference is that the second argument now controls the dots or colons on the display, which is perfect for showing times or decimal numbers. To control these dots, you use a binary number that tells the display exactly which dots to turn on. Each position in the binary number corresponds to a specific dot on your display. For example:
If you have a display with dots between each digit, here’s how it works:
| Argument | Dots | Example |
| 0b10000000 | . | 1.234 |
| 0b01000000 | . | 12.34 |
| 0b00100000 | . | 123.4 |
| 0b11100000 | . . . | 1.2.3.4 |
Some TM1637 displays have a colon instead of dots. In this case:
| Argument | Dots | Example |
| 0b01000000 | : | 12:34 |
There are even displays that have both dots and a colon. On these displays:
| Argument | Dots | Example |
| 0b11100000 | . : . | 1.2:3.4 |
Let’s say you want to make a digital clock that shows “12:34”. You would use the function like this:
// Prints 12:34
display.showNumberDecEx(1234, 0b01000000, false, 4, 0);First, you’d tell it to display the number 1234. Then, you’d use the binary code 0b01000000 to turn on the colon in the middle. The last few arguments tell the function not to add leading zeros, to update all four digits, and to start at the first position.
Since there’s nothing that needs to run repeatedly in this example, we leave the loop() function empty.
void loop() {
}#include <TM1637Display.h>
// ESP32 pins connected to the TM1637 module
#define CLK 26
#define DIO 25
// Create the display object
TM1637Display display(CLK, DIO);
// An array that turns every segments ON
const uint8_t SEG_ALL_ON[] = {0xFF, 0xFF, 0xFF, 0xFF};
// An array that sets individual segments per digit to display the word "dOnE"
const uint8_t WORD_DONE[] = {
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O
SEG_C | SEG_E | SEG_G, // n
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G // E
};
// An array that displays the degree celsius symbol
const uint8_t SYMBOL_CELSIUS[] = {
SEG_A | SEG_B | SEG_F | SEG_G, // degree symbol
SEG_A | SEG_D | SEG_E | SEG_F // C
};
void setup() {
// Start with a medium brightness and display enabled.
// Brightness range is 0 (dimmest) to 7 (brightest)
display.setBrightness(5, true);
}
void loop() {
// Set every segments ON
display.setSegments(SEG_ALL_ON);
delay(1500);
// Clear the display
display.clear();
// Show decimal numbers
// Demonstrates positive, negative, leading zeros, length and position
display.showNumberDec(42, false); // " 42"
delay(1500);
display.showNumberDec(42, true); // "0042"
delay(1500);
display.showNumberDec(-18, false); // " -18"
delay(1500);
display.clear();
display.showNumberDec(14, false, 2, 1); // "_14_"
delay(1500);
display.clear();
display.showNumberDec(4, true, 2, 0); // "04__"
delay(1500);
display.clear();
display.showNumberDec(-5, false, 3, 0); // "_-5_"
delay(1500);
// Show hexadecimal numbers
display.showNumberHexEx(0x1A2F); // "1A2F"
delay(1500);
display.showNumberHexEx(0x2c); // "__2C"
delay(1500);
display.showNumberHexEx(0xd1, 0, true); // "00d1"
delay(1500);
display.clear();
display.showNumberHexEx(0xd1, 0, true, 2); // "d1__"
delay(1500);
// Show decimal number with colon control
display.showNumberDecEx(1234, 0b01000000, true); // "12:34"
delay(1500);
// Show temperature
display.setSegments(SYMBOL_CELSIUS, 2, 2); // put "°C" on the right
display.showNumberDec(25, false, 2, 0); // "25°C"
delay(1500);
// Brightness Test
for (int i = 0; i < 7; i++) {
display.setBrightness(i);
display.setSegments(SEG_ALL_ON);
delay(1000);
}
// Final screen
display.setSegments(WORD_DONE);
while (true) {
// Stop here
}
}Going further
Now that you know how to connect and control a TM1637 display with the ESP32, you can start building more useful real-world projects with it. One great next step is to make a Wi-Fi digital clock that automatically gets the correct time from the internet using NTP. If you want to try that project next, check out the tutorial below.



