Interfacing TM1637 4-Digit 7-Segment Display with Arduino

If you want to design a clock, timer or counter in your next project, you will need a 4-digit seven-segment display. But a bare 4-digit 7-segment display usually requires 12 connection pins. That’s quite a lot and leaves no room for other modules and sensors.

After all, wouldn’t it be awesome if you could control a 4-digit seven-segment display without tons of wiring? That’s where the TM1637 module comes in. The TM1637 module reduces pin connections to just four. Two pins are used for power connections and the other two pins are for controlling segments.

7-Segment Display Basics

The 7-segment displays are actually just seven LEDs lined up in a particular pattern (the shape of ‘8’). Each of the seven LEDs is called a segment, because when illuminated, the segment forms part of a numeric digit (both decimal and hex).

7 segment internal led formation

These individual segments are labeled from ‘A’ to ‘G’ representing each individual LED. By setting the particular segment HIGH or LOW, a desired character pattern is generated.

7 segment character generation

For more information about 7-segment display check out this comprehensive tutorial of ours.

TM1637 Module Hardware Overview

At the heart of the module is an inexpensive serial LED driver from Titan MicroElectronics – TM1637.

tm1637 hardware overview chip

The TM1637 supports many functions – including ON/OFF and brightness control of the LEDs as well as accessing each of the segments. It also allows you to adjust the brightness of the LEDs at software level.

And another good thing is that once the display is updated by the microcontroller, the TM1637 then takes care of all the work of refreshing the display. Thereby removing the overhead from the microcontroller, which can be off doing other important things.

tm1637 hardware overview led display

The TM1637 module includes four 0.36 segment 7-segment displays to display sensor data or temperature. In addition to the four 7-segments, the module has a ‘colon’ at the center which makes it very easy to create clock or time-based projects.

The TM1637 module operates on a supply voltage of 3.3 to 5 volts and communicates via a two-wire bus, so it only requires two data pins plus VCC and ground. The bus is specific to this device, but there are libraries available for Arduino that hide the complexities and make it easier to communicate with the display.

TM1637 Module Pinout

There is a 4-pin right angle male header on the module for making connections.

tm1637 4 digit 7 segment display module pinout

CLK is a clock input pin. Connect to any digital pin on Arduino.

DIO is a Data I/O pin. Connect to any digital pin on Arduino.

VCC pin supplies power to the module. Connect it to the 3.3V to 5V power supply.

GND is a ground pin.

Wiring TM1637 Module with Arduino UNO

Hooking up the TM1637 to an Arduino is super simple. You only need to connect four wires: two for power and other the two for controlling the display.

The module is powered safely from the 5-volt output of the Arduino. The CLK and DIO pins are connected to the Arduino’s digital pins 2 and 3 resp.

Below is the hookup for the experiments with the TM1637:

wiring tm1637 module with arduino

None of the pins used on the Arduino are critical because the module does not require any pin-specific features, so if you want to use different pins you can do so safely. Just be sure to change the pin numbers in the code to reflect any changes to the wiring.

Library Installation

To talk to the TM1637 chip you’ll need to use a library. Avishay Orpaz has written an excellent library for TM1637 displays, the TM1637Display library. This library has several built-in functions that make controlling the display fairly easy. You just specify which number to display and it is handled for you.

To install the library navigate to the Sketch > Include Library > Manage Libraries… Wait for Library Manager to download libraries index and update list of installed libraries.

Arduino Library Installation - Selecting Manage Libraries in Arduino IDE

Filter your search by typing ‘tm1637‘. Look for the library by Avishay Orpaz. Click on that entry, and then select Install.

tm1637 display library installation

Basic Arduino Code

Below is a basic test program that goes through a bunch of different routines. Go ahead and upload it to your Arduino.

// Include the library
#include <TM1637Display.h>

// Define the connections pins
#define CLK 3
#define DIO 4

// Create a display object of type TM1637Display
TM1637Display display = TM1637Display(CLK, DIO);

// Create an array that turns all segments ON
const uint8_t allON[] = {0xff, 0xff, 0xff, 0xff};

// Create an array that turns all segments OFF
const uint8_t allOFF[] = {0x00, 0x00, 0x00, 0x00};

// Create 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
};

// Create degree celsius 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() {

}

void loop() {
	// Set the brightness to 5 (0=dimmest 7=brightest)
	display.setBrightness(5);

	// Set all segments ON
	display.setSegments(allON);

	delay(2000);
	display.clear();

	// Show counter 0-9
	int i;
	for (i = 0; i < 10; i++) {
		display.showNumberDec(i);
		delay(50);
	}

	delay(2000);
	display.clear();

	display.showNumberDec(-12);			// Prints _-12
	delay(2000);
	display.clear();
	
	display.showNumberDec(-999);		// Prints -999
	delay(2000);
	display.clear();
	
	display.showNumberDec(31, false);	// Prints __31
	delay(2000);
	display.clear();
	
	display.showNumberDec(31, true);	// Prints 0031
	delay(2000);
	display.clear();
	
	display.showNumberDec(14, false, 2, 1);	// Prints _14_
	delay(2000);
	display.clear();
	
	display.showNumberDec(-5, false, 3, 0);	// Prints _-5_
	delay(2000);
	display.clear();

	// Prints 12:34
	display.showNumberDecEx(1234, 0b11100000, false, 4, 0);

	delay(2000);
	display.clear();

	// Prints 15°C
	int temperature = 15;
	display.showNumberDec(temperature, false, 2, 0);
	display.setSegments(celsius, 2, 2);

	delay(2000);
	display.clear();
	
	// Prints dOnE
	display.setSegments(done);

	while(1);
}

Code Explanation:

The sketch begins with including the library and defining the pins used to connect the TM1637 display.

#include <TM1637Display.h>

#define CLK 3
#define DIO 4

Next, a new instance of the TM1637Display class is created with the function TM1637Display(). This function requires two parameters, first the CLK pin and the second the DIO pin.

TM1637Display display = TM1637Display(CLK, DIO);

There are two ways to set individual segments of the display. Several arrays are defined before the setup section of the code that sets the individual segments of the display. We will use the function setSegments() to write them to the display later.

The first option to set individual segments is to use hexadecimal numbers. Hexadecimal 0xFF translates to 11111111 in binary, and it turns all segments ON. For example 0xEF translates to 11101111, and turn ON all segments except segment E, while 0x00 will turn OFF all segments.

Note that the counting goes from right to left, so the 11111111 segment corresponds to (dot)GFEDCBA.

// Create an array that turns all segments ON
const uint8_t allON[] = {0xff, 0xff, 0xff, 0xff};

// Create an array that turns all segments OFF
const uint8_t allOFF[] = {0x00, 0x00, 0x00, 0x00};

Another option to set individual segments is to specify the segments you want to turn on. This option is slightly easier. See the code below. The first snippet will help print the word “dOnE” on the display while the second snippet will help print “°C” on the display.

// Create 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
};

// Create °C symbol
const uint8_t celsius[] = {
  SEG_A | SEG_B | SEG_F | SEG_G,	// °
  SEG_A | SEG_D | SEG_E | SEG_F		// C
};

There is nothing to set so the setup section is kept empty.

void setup() {
}

In the loop section of the code we have used many library functions. Let’s learn about them one by one.

setBrightness(brightness,on)

This function is used to set the brightness of the display. You can specify a brightness level from 0 (lowest brightness) to 7 (highest brightness). The second argument is optional and can be used to turn the display ON or OFF. You can pass it true (display ON) or false (display OFF).

For example, display.setBrightness(5) sets the brightness to 5, while display.setBrightness(5, false) turns the display off.

setSegments(segments[],length,position)

This function can be used to set individual segments of a display. The first argument is the array that contains the segment information. The second argument specifies the number of digits to be updated (0–4). If you want to print the word “dOnE”, it will be 4, for the “°C” symbol, it will be 2. The third argument determines the position from which you want to print (0-leftmost, 3-rightmost).

Note that the second and third argument of the function are optional. So, if you want to update all the digits of the display, you can skip them. For example, the following snippet will first turn on all segments of the display and then print “dOnE”.

// Set all segments ON
display.setSegments(allON);

// Prints dOnE
display.setSegments(done);

However, if you want to update only the last two digits of the display to print the “°C” symbol, you would use:

// Prints __°C
display.setSegments(celsius, 2, 2);

showNumberDec(number,leading_zeros,length,position)

This is the function you will use the most. The first argument is a number that you want to display on the screen. The rest of the arguments are optional.

For example, the following code snippet will count from 0 to 9 and then print -12 and -999 on the display.

// Show counter 0-9
int i;
for (i = 0; i < 10; i++) {
	display.showNumberDec(i);
	delay(50);
}

display.showNumberDec(-12);			// Prints _-12

display.showNumberDec(-999);		// Prints -999

The second argument can be used to pad a number with leading zeros. Setting this to true will add leading zeros to a number, and setting it to false will print the number as it is. For example,

display.showNumberDec(31, false);	// Prints __31

display.showNumberDec(31, true);	// Prints 0031

The third and fourth argument are the same as in the previous function. length specifies the number of digits to be updated (0–4) and position determines the position from which you want to print (0-leftmost, 3-rightmost).

So, if you want to show the number in the middle of the display, you would write:

display.showNumberDec(14, false, 2, 1);	// Prints _14_

display.showNumberDec(-5, false, 3, 0);	// Prints _-5_

showNumberDecEx(number,dots,leading_zeros,length,position)

This is an extended version of the showNumberDec() function. You can see that only the second argument is different. This argument allows you to control the dots of the display. You can use the following values.

For TM1637 displays with dots between each digit:

ArgumentDotsExample
0b10000000 .   1.234
0b01000000  .  12.34
0b00100000   . 123.4
0b11100000 . . . 1.2.3.4

For TM1637 displays with just a colon:

ArgumentDotsExample
0b01000000  :  12:34

For TM1637 displays with dots and colons colon:

ArgumentDotsExample
0b11100000 . : . 1.2:3.4

So if you want to display a clock with center colon activated, you would use something like:

// Prints 12:34
display.showNumberDecEx(1234, 0b11100000, false, 4, 0);

Arduino Project – Creating a Thermometer with TM1637 and DHT11/DHT22

The best use of the TM1637 display is to display sensor readings such as temperature, humidity, voltage, or speed. The following project displays temperature readings from DHT11 / DHT22 on the TM1637 display.

If you are not familiar with the DHT11 / DHT22 module, consider reading (at least skimming) this tutorial.

Tutorial Interfacing DHT11 DHT22 AM2302 with Arduino Uno and 16x2 character LCD
How DHT11 DHT22 Sensors Work & Interface With Arduino
Give your next Arduino project the ability to sense the world around it with the inexpensive DHT11 or DHT22 Digital Temperature & Humidity Sensor from...

The following wiring diagram shows you how you can connect the DHT11 / DHT22 sensor to Arduino in combination with the TM1637 display.

digital thermometer wiring tm1637 and dht11 module with arduino

The following sketch communicates with the DHT11 / DHT22 sensor and displays the temperature readings on the display. The temperature is displayed in Celius and Fahrenheit at an interval of 2 seconds. The code uses the Adafruit DHT sensor and the Adafruit Unified Sensor libraries, so please install them as well.

// Include the libraries
#include <TM1637Display.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

// Define the connections pins
#define CLK 3
#define DIO 4
#define DHTPIN 5

// Create variable
int temperature_celsius;
int temperature_fahrenheit;

// Create °C symbol
const uint8_t celsius[] = {
	SEG_A | SEG_B | SEG_F | SEG_G,  // Circle
	SEG_A | SEG_D | SEG_E | SEG_F   // C
};

// Create °F symbol
const uint8_t fahrenheit[] = {
	SEG_A | SEG_B | SEG_F | SEG_G,  // Circle
	SEG_A | SEG_E | SEG_F | SEG_G   // F
};

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)

// Create display object of type TM1637Display
TM1637Display display = TM1637Display(CLK, DIO);

// Create dht object of type DHT:
DHT dht = DHT(DHTPIN, DHTTYPE);

void setup() {
	// Set the display brightness (0-7)
	display.setBrightness(5);
	
	// Clear the display
	display.clear();
	
	// Setup sensor
	dht.begin();
}

void loop() {
	// Read the temperature as Celsius and Fahrenheit
	temperature_celsius = dht.readTemperature();
	temperature_fahrenheit = dht.readTemperature(true);

	// Display the temperature in celsius format
	display.showNumberDec(temperature_celsius, false, 2, 0);
	display.setSegments(celsius, 2, 2);
	delay(1000);

	// Display the temperature in fahrenheit format
	display.showNumberDec(temperature_fahrenheit, false, 2, 0);
	display.setSegments(fahrenheit, 2, 2);
	delay(1000);
}

Arduino Project – Creating a clock with TM1637 and DS3231

Another typical use of the TM1637 display is to pair it with the DS3231 RTC module and create a 24-hour clock.

If you are not familiar with the DS3231 RTC module, consider reading the tutorial.

Tutorial for Interfacing DS3231 RTC module with Arduino
Interface DS3231 Precision RTC Module with Arduino
We all know that most MCUs we use for our projects are time-agnostic; simply put they are unaware of the time around them. It's OK...

Next, we need to make a connection to the DS3231 as shown below. Note that the TM1637 display is connected in the same way as before.

digital 24 hour clock wiring tm1637 and ds3231 module with arduino

The following sketch display the time in a 24-hour time format. The code uses the Adafruit RTC library, which you can install via the Library Manager in the Arduino IDE by searching for ‘RTClib‘.

// Include the libraries
#include "RTClib.h"
#include <TM1637Display.h>

// Define the connections pins
#define CLK 3
#define DIO 4

// Create rtc and display object
RTC_DS3231 rtc;
TM1637Display display = TM1637Display(CLK, DIO);

void setup() {
	// Begin serial communication
	Serial.begin(9600);

	// Check if RTC is connected correctly
	if (! rtc.begin()) {
		Serial.println("Couldn't find RTC");
		while (1);
	}
	// Check if the RTC lost power and if so, set the time
	if (rtc.lostPower()) {
		Serial.println("RTC lost power, lets set the time!");
		// The following line sets the RTC to the date & time this sketch was compiled:
		rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
		// This line sets the RTC with an explicit date & time, for example to set
		// January 21, 2014 at 3am you would call:
		//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
	}

	// Set the display brightness (0-7)
	display.setBrightness(5);
	
	// Clear the display
	display.clear();
}

void loop() {
	// Get current date and time
	DateTime now = rtc.now();

	// Create time format to display
	int displaytime = (now.hour() * 100) + now.minute();

	// Display the current time in 24 hour format with leading zeros and a center colon enabled
	display.showNumberDecEx(displaytime, 0b11100000, true);

	delay(1000);
}