Interfacing TM1637 4-Digit 7-Segment Display with Arduino

A 4-digit 7-segment display is a must-have for any project involving a clock, timer, or counter, but connecting a bare display to an Arduino requires a dozen-or-so pins, leaving little room for other sensors and modules.

Wouldn’t it be wonderful if you could control a 4-digit 7-segment display with fewer pins? This is where the TM1637 module enters the picture. It requires only four connections in total – two for power and two for controlling the display.

7-Segment Display Basics

The 7-segment display, also written as “seven segment display”, consists of seven LEDs arranged in a ‘8’-shaped pattern. Each LED is referred to as a segment, because when illuminated, it forms part of a digit.

7 segment internal led formation

Each segment LED has one of its connection pins brought directly out of the rectangular plastic package. These pins are labeled with the letters ‘a’ through ‘g’. The remaining LED pins are wired together to form a single common pin.

Each segment can be individually turned on or off by setting the corresponding pin to HIGH or LOW, just like a regular LED. By lighting up individual segments, you can create any numerical character and even some basic representations of letters.

7 segment character generation

Check out our in-depth tutorial on 7-segment displays for more information.

TM1637 Module Hardware Overview

The TM1637 module combines a classic 0.36″ 4-digit 7-segment display and the TM1637 LED driver from Titan MicroElectronics, allowing you to control all digits, and the colon using only two I/O pins.

TM1637 Hardware Overview LED Display

The TM1637 module is ideal for displaying sensor data or temperature. It also includes a “colon” for use in clock and time-related projects.

The TM1637 handles all the work of refreshing the display after it has been updated by the microcontroller, which is a nice bonus. This frees up the microcontroller to do other important things.

TM1637 Hardware Overview Chip

Another plus is that the TM1637 has many useful features, such as the ability to adjust the display’s brightness and control each segment independently.

The TM1637 module operates on a 3.3 to 5 volt supply voltage and communicates via a two-wire bus, requiring only two data pins, VCC and ground. The TM1637 has its own proprietary data transfer protocol, but there are Arduino libraries available that hide the complexities and make communication with the display easier.

Technical Specifications

Here are the specifications:

Operating voltage3.3 – 5 VDC
Maximum Current Draw80mA
Reverse polarity protectionYes
Display Size42 mm x 24 mm (1.65″ x .95″)
Display Height12 mm (0.47″) (typical)
Character Height9.14 mm (0.36″)

For more information on the TM1637 driver, please refer to the datasheet below.

TM1637 Module Pinout

The TM1637 Module has only four pins. The following is the pinout:

TM1637 4 Digit 7 Segment Display Module Pinout

CLK is the clock input pin.

DIO is the Data I/O pin.

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

GND is the ground pin.

Wiring TM1637 Module with Arduino UNO

Connecting the TM1637 to an Arduino is very easy. There are only four wires to connect: two for power and two for controlling the display.

Begin by connecting the VCC pin to the Arduino’s 5V output and the GND pin to ground. Connect the CLK and DIO pins to the Arduino’s digital pins 3 and 4, respectively.

The diagram below shows how to connect everything.

Wiring TM1637 Module with Arduino

Since the module does not rely on any pin-specific features, it is safe to use alternative pins. Just make sure to update the pin numbers in the code to reflect any wiring changes.

Library Installation

To communicate with the TM1637 chip, you’ll need to use a library. The TM1637Display library by Avishay Orpaz is an excellent library. This library includes a number of built-in functions that make controlling the display a breeze.

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

Manage Libraries

Filter your search by entering ‘tm1637’. Look for TM1637 library by Avishay Orpaz. Click on that entry and then choose Install.

TM1637 Display Library Installation

Basic Arduino Code

The following is a simple test program that goes through a bunch of different routines.

// 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 by including the library and defining the TM1637 display’s connection pins.

#include <TM1637Display.h>

#define CLK 3
#define DIO 4

The next step is to create an object of TM1637Display class. The TM1637Display constructor accepts two inputs: the CLK pin and the DIO pin.

TM1637Display display = TM1637Display(CLK, DIO);

Each segment of each digit in the TM1637 display can be individually turned on or off by setting the corresponding pin to HIGH or LOW, just like a regular LED. By lighting up individual segments, you can create any numerical character and even some basic representations of letters.

To demonstrate this, four arrays are defined before the setup section of the code. The first array turns all segments ON, the second turns all segments OFF, the third displays the word ‘dOnE’, and the fourth displays the ‘°C’ symbol. We pass these arrays to the setSegments() function in order to display them.

There are two methods for defining these arrays. The first method is to use hexadecimal numbers. Let’s look at the first two arrays.

Hexadecimal 0xFF translates to binary 11111111, which turns all segments ON, while 0x00 turns all segments OFF. Similarly, if you want to turn all segments on except segment E, you can write 0xEF (11101111 in binary).

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 way to set individual segments is to specify which segments you want to turn on. This one is easier than the previous one. Look at the code below. The first array displays “dOnE”, while the second displays “°C”.

// 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 configure, so the setup section is left blank.

void setup() {
}

In the loop section, many library functions are used. Let us go through them one by one.

setBrightness(brightness,on)

This function is used to adjust the display’s brightness. You can choose a brightness level ranging from 0 (lowest brightness) to 7 (highest brightness).

The second argument is optional and can be used to turn on or off the display. You can either pass true (display ON) or false (display OFF). For example, display.setBrightness(5) sets the brightness to 5, whereas display.setBrightness(5, false) turns off the display.

setSegments(segments[],length,position)

This function can be used to set individual segments of a display. The first argument specifies the array containing the segment information. The second argument specifies how many digits should be updated (0–4). If you want to print the word “dOnE” it will be 4, and 2 if you want to print the “°C”. The third argument specifies the position from which you want to print (0-leftmost, 3-rightmost).

The function’s second and third arguments are optional. So, if you want to update all of the display’s digits, 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);

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

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

showNumberDec(number,leading_zeros,length,position)

This is the most frequently used function. The first argument specifies a number to be displayed. For example, the following code snippet will count from 0 to 9 and then display -12 and -999.

// 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 add leading zeros to a number. Setting this to true will add leading zeros to a number, and setting it to false will print the number as-is.

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

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

The third and fourth arguments are identical to those used in the previous function. The length specifies the number of digits to be updated (0-4) and the position specifies where you want to print from (0-leftmost, 3-rightmost).

So, if you want the number to appear in the center 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 tell that only the second argument is different. This argument allows you to control the display’s dots. 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 a colon:

ArgumentDotsExample
0b11100000 . : . 1.2:3.4

So, if you want to show a clock with the center colon enabled, you’d write:

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

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

The TM1637 display is best suited for displaying sensor readings such as temperature, humidity, voltage, or speed. The project below shows temperature readings from DHT11 on the TM1637 display.

If you are unfamiliar with the DHT11 module, consider reading this tutorial.

Wiring

The wiring diagram below shows how to connect the DHT11 sensor and the TM1637 display to Arduino.

Digital Thermometer Wiring TM1637 and DHT11 Module with Arduino

Arduino Code

The sketch below communicates with the DHT11 sensor and displays temperature readings on the display. The temperature is displayed in both Celsius and Fahrenheit every 2 seconds.

The code uses the Adafruit DHT sensor and the Adafruit Unified Sensor libraries, so please install those 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 2 – Creating a clock with TM1637 and DS3231

The TM1637 display is often used with the DS3231 RTC module to make a 24-hour clock.

If you are unfamiliar with the DS3231 RTC module, consider reading this tutorial.

Wiring

The wiring diagram below shows how to connect the DS3231 and the TM1637 display to Arduino.

Digital 24 Hour Clock Wiring TM1637 and DS3231 Module with Arduino

Arduino Code

The following sketch shows the time in a 24-hour format. The code uses the Adafruit RTC library, so please install it as well.

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