Segment LED Display Tutorial for Arduino, ESP8266 and ESP32
In this tutorial you learn how the three most important segment LED displays work. We cover every segment display with examples and the correct wiring. The 3 different displays are:
- 7 Segment Display
- 4 7 Segment Display
- 8×8 Dot Matrix Display
Also this article cover the Shift Register which reduces the number of used pin on your microcontroller.
Table of Contents
The following table gives you an overview of all components and parts that I used for this tutorial. I get commissions for purchases made through links in this table.
Arduino Uno | Amazon | Banggood | AliExpress | |
OR | ESP8266 NodeMCU | Amazon | Banggood | AliExpress |
OR | ESP32 NodeMCU | Amazon | Banggood | AliExpress |
AND | 7 Segment Display and 4x7 Segment Display in Sensor Pack | Amazon | AliExpress | |
AND | 8x8 Dot Matrix Display | Amazon | Banggood | AliExpress |
7 Segment Display
Seven segment displays are most used to display decimal numbers (0…9) in electronic displays like microwave ovens, calculators or washing machines. These kind of displays use light emitting diodes (LEDs) for every of the 7 segments. Therefore it is possible to display decimal numbers if the LEDs of the right segments are turned on.
The following picture shows the pinout of a 7 segment display to get a better understanding how it works.
The different segments are connected with the corresponding pins on the edge or backside of the display. The 2 middle pins are the common pins and connected to a common cathode or common anode. This depends of the kind of 7 segment display you have. In most cases you will have a common cathode display so that an LED turns on when the signal to the LED is HIGH and to common is connected to ground. If you have an anode segment display the LED turns on when the signal is LOW.
Note that your display might have a dot point on the right side so that in total you have 10 pins to connect to your microcontroller.
- 1 pin for the dot pin
- 7 pins for the different segments to display numbers
- 2 pins to connect the anode or cathode
The following fritzing sketches show the connection of the 7 segment LED display to an Arduino ESP8266 or ESP32 microcontroller.
The 220 Ohm resistor between the common pin and ground restricts the current to less than 20mA for the Arduino microcontroller.
To display different kinds of numbers on the segment display it is useful to have a table for all numbers. Therefore the following table shows you the Bit and HEX Code for the anode and cathode configuration.
Anode configuration of display numbers
on a 7 segment display
Number | g f e d c b a | Hex Code |
0 | 1000000 | C0 |
1 | 1111001 | F9 |
2 | 0100100 | A4 |
3 | 0110000 | B0 |
4 | 0011001 | 99 |
5 | 0010010 | 92 |
6 | 0000010 | 82 |
7 | 1111000 | F8 |
8 | 0000000 | 80 |
9 | 0010000 | 90 |
Cathode configuration of display numbers
on a 7 segment display
Number | g f e d c b a | Hex Code |
0 | 0111111 | 3F |
1 | 0000110 | 06 |
2 | 1011011 | 5B |
3 | 1001111 | 4F |
4 | 1100110 | 66 |
5 | 1101101 | 6D |
6 | 1111101 | 7D |
7 | 0000111 | 07 |
8 | 1111111 | 7F |
9 | 1001111 | 4F |
In the example we want to display some values. I used to display the numbers 1 and 8 in a loop. With the provided table you can easily change the following sketch to display other digital numbers.
int LEDs[] = {8,9,7,6,4,3,2}; // for Arduino microcontroller
//int LEDs[] = {D2,D1,D3,D4,D6,D7,D8}; // for ESP8266 microcontroller
//int LEDs[] = {22,23,1,3,19,18,5}; // for ESP32 microcontroller
int one[] = {0, 0, 0, 0, 1, 1, 0}; // LED states to display number one
int eight[] = {1, 1, 1, 1, 1, 1, 1}; // LED states to display number eight
void setup() {
for (int i = 0; i<7; i++) pinMode(LEDs[i], OUTPUT);
}
void loop() {
for (int i = 0; i<7; i++) digitalWrite(LEDs[i], one[i]);
delay(1000);
for (int i = 0; i<7; i++) digitalWrite(LEDs[i], eight[i]);
delay(1000);
}
The script is a bit tricky if you did not use arrays before. Therefore I explain the Arduino script in detail.
At the beginning of the script we create an array, called LEDs that stores all the connection pins to the 7 segment display. Later we can access every element in the array to make our lives a little easier. Depending on your microcontroller, you only have to select one of the first three lines. You can either comment the other lines or delete them, if you do not need them.
Because we want to display the numbers 1 and 8, we have to define how to control all digital I/O pins to get the desired numbers. You can use the table for the anode or cathode configuration to see which of the 7 pins has to be 0 (LOW) or 1 (HIGH). Because my 7 segment display has a cathode configuration, the 1 is displayed with 0000110 and 8 with 1111111. We save the combination of values also in an array.
In the setup function we define each pin that connects the microcontroller and the display as output, because we want to control the display from the view of the microcontroller. You could define each pin as output separat line after line, but we have our array that makes the definition as output very easy. We only have to loop through the LEDs array with a for loop and set the pinMode of the desired element in the array as output.
In the loop function, we now have to control the digital output pins with LOW and HIGH signals so that a 1 and 8 shows up in the 7 segment display.
Therefore we loop again over the previous created arrays in a for loop. We use the digitalWrite function to go step by step over the arrays and change the first element, that is the first pin to the first status of the array that creates the number. For example for Arduino microcontrollers:
- i=0: set LEDs[0] = pin8 to one[0] = LOW
- …
- i=5: set LEDs[5] = pin3 to one[1] = HIGH
After we created the digit in the segment display, we use a delay of one second before we create the next digit or restart the loop function.
The following video shows the digits 1 and 8 that are created in the 7 segment display.
4x7 Segment Display
The 4 times 7 Segment Display is easy explained. It is 4 times the 7 segment display in a row. Therefore a lot of wiring is necessary. For me personally if the wiring gets to complicated, I try to find an other way to get to my goal. And for me I prefer an LCD display which is easy to wire with I2C instead of the complicated use and blocking pins of the 4 7 segment display. If you want to learn how to use the LCD display, I also have a tutorial for LCD displays.
Reduce the number of pins with Shift Registers
Also there is a possibility to reduce the number of pins you need to connect the segment displays to your microcontroller. With the use of shift registers like the 74HC595 it is possible to declare the status of each LED with one 8-bit number rather than use one bit for every LED. With the use of a shift register you can reduce the number of pins from 8 to only 3.
You can view the datasheet of the 74HC595. The operating voltage is between 2V and 6V. Therefore the 74HC595 can be used with all Arduino, ESP8266 and ESP32 micocontroller. Also the power consumption is low with 80 micro A and the shift register can directly clear the complete output.
The following table and pictures show the connection between the 74HC595, the 7 segment display and the Arduino, ESP8266 or ESP32 microcontroller.
Symbol |
Description |
Connection Arduino |
Connection ESP8266 |
Connection ESP32 |
QB |
Shift register output LED b |
7 SD: Pin b |
7 SD: Pin b |
7 SD: Pin b |
QC |
Shift register output LED c |
7 SD: Pin c |
7 SD: Pin c |
7 SD: Pin c |
QD |
Shift register output LED d |
7 SD: Pin d |
7 SD: Pin d |
7 SD: Pin d |
QE |
Shift register output LED e |
7 SD: Pin e |
7 SD: Pin e |
7 SD: Pin e |
QF |
Shift register output LED f |
7 SD: Pin f |
7 SD: Pin f |
7 SD: Pin f |
QG |
Shift register output LED g |
7 SD: Pin g |
7 SD: Pin g |
7 SD: Pin g |
QH |
Shift register output LED P |
|||
GND |
Ground |
GND |
GND |
GND |
QH |
Output if more |
|||
SRCLR |
Clear the register when LOW |
5V | 3.3V | 3.3V |
SRCLK |
Storage register clock |
Clock: Pin 2 |
Clock: Pin D8 |
Clock: Pin 4 |
RCLK |
Shift register clock |
Latch: Pin 3 |
Latch: Pin D7 |
Latch: Pin 0 |
OE |
Output enable when ground |
GND |
GND |
GND |
SER |
Serial input for next pin |
Data: Pin 4 |
Data: Pin D6 |
Data: Pin 2 |
QA |
Shift register output LED a |
7 SD: Pin a |
7 SD: Pin a |
7 SD: Pin a |
VCC |
5V supply |
5V |
3.3V |
3.3V |
If you want to know more about the pinout of different microcontroller, I wrote an article about the different pinouts of EPS8266 boards, Arduino Nano, Arduino Uno, Arduino Mega. But if you are actually interested in the different microcontroller, you take a look at the Microcontroller Datasheet eBook.
The function of a shift register is the following:
- The shift register loads the state (HIGH or LOW) of each LED one by one with the data pin (DATA) as long as the clock (LATCH) is set to LOW.
- The loading of each LED is controlled by the storage register clock (CLOCK).
- After all 8 LEDs states are loaded, the shift register clock (LATCH) is set from LOW to HIGH.
For the following sketch we have one thing left to define. The shift register has to know if want to load the most significant bit first (MSBFIRST) or last (LSBFRIST). The following tables explain the difference. We want to load the number 3 into the shift register:
MSBFIRST the number 3 in binary is 01001111
QA | QB | QC | QD | QE | QF | QG | QH | |
Clear | ||||||||
Shift 1 → 0 | ||||||||
Shift 2 → 1 | 1 | |||||||
Shift 3 → 0 | 1 | |||||||
Shift 4 → 0 | 1 | |||||||
Shift 5 → 1 | 1 | 1 | ||||||
Shift 6 → 1 | 1 | 1 | 1 | |||||
Shift 7 → 1 | 1 | 1 | 1 | 1 | ||||
Shift 8 → 1 | 1 | 1 | 1 | 1 | 1 |
LSBFRIST the number 3 in binary is 11110010
QA | QB | QC | QD | QE | QF | QG | QH | |
Clear | ||||||||
Shift 1 → 1 | 1 | |||||||
Shift 2 → 1 | 1 | 1 | ||||||
Shift 3 → 1 | 1 | 1 | 1 | |||||
Shift 4 → 1 | 1 | 1 | 1 | 1 | ||||
Shift 5 → 0 | 1 | 1 | 1 | 1 | ||||
Shift 6 → 0 | 1 | 1 | 1 | 1 | ||||
Shift 7 → 1 | 1 | 1 | 1 | 1 | 1 | |||
Shift 8 → 0 | 1 | 1 | 1 | 1 | 1 |
We use the MSBFIRST in the following example to display the values 0 to 4. Note that you can either define the decimal number in binary or HEX format. I use the HEX format in the following script.
// for Arduino microcontroller
int clockPin = 2;
int latchPin = 3;
int dataPin = 4;
// for ESP8266 microcontroller
//int clockPin = D8;
//int latchPin = D7;
//int dataPin = D6;
// for ESP32 microcontroller
//int clockPin = 4;
//int latchPin = 0;
//int dataPin = 2;
int num[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66};
void setup() {
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
for (int i = 0; i<5; i++) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, num[i]);
digitalWrite(latchPin, HIGH);
delay(1000);
}
}
In the first part of the script, we have to define which pins are connected between the 74HC595 shift register and the microcontroller. Therefore the first lines are duplicated for Arduino, ESP8266 and ESP32 microcontroller. You simply have to select your microcontroller and delete the other lines or comment the lines, like I did.
To display the values 0 to 4 I store the HEX values of the digits in a array called num.
In the setup function we set all connected digital I/O pins as output.
In the loop function we have to iterate through the num array to display all digits before the loop function starts again. For each element in the num array we set the latch pin low to load the different states of the shift register. Now we use the shiftOut function, shiftOut(dataPin, clockPin, bitOrder, value), to shift out a byte of data one bit at a time (reference):
- dataPin: the pin on which to output each bit. Allowed data types: int.
- clockPin: the pin to toggle once the dataPin has been set to the correct value. Allowed data types: int.
- bitOrder: which order to shift out the bits; either MSBFIRST or LSBFIRST
- value: the data to shift out. Allowed data types: byte.
After all states for the LED are loaded to the shift register, the shift register clock (LATCH) is set from LOW to HIGH to forward all values to the 7 segment display for the visualization.
The following video shows how the values 0 to 4 are displayed in the segment display with the use of an Arduino Uno and the 74HC595 shift register.
8x8 Dot Matrix Display
The 8×8 Dot Matrix Display has in total 64 LEDs and normally 16 pins. But I bought the module version of the dot matrix display, so that the dot matrix itself is connected to a shift register. Therefore we only have to connect 5 pins to our microcontroller. On the other side of the dot matrix display, the module has the same connection because you are able to connect multiple 8×8 Dot Matrix Display modules in a row, called daisy chain.
The following pictures shows the connection between 8×8 dot matrix display in the module version and the Arduino, ESP8266 or ESP32 microcontroller.
The easiest way to control the display is with the LedControl library. If you do not know how to install an external library to your Arduino IDE, here is a step by step tutorial.
In the following example we display a sad, a neural and a happy smiley.
#include "LedControl.h"
#include "binary.h"
LedControl lc=LedControl(8,10,9,1); // for Arduino microcontroller
//LedControl lc=LedControl(D7,D5,D8,1); // for ESP8266 microcontroller
//LedControl lc=LedControl(2,4,0,1); // for ESP32 microcontroller
byte hf[8]= {B00111100,B01000010,B10100101,B10000001,B10100101,B10011001,B01000010,B00111100};
byte nf[8]={B00111100, B01000010,B10100101,B10000001,B10111101,B10000001,B01000010,B00111100};
byte sf[8]= {B00111100,B01000010,B10100101,B10000001,B10011001,B10100101,B01000010,B00111100};
void setup() {
lc.shutdown(0,false);
lc.setIntensity(0,5);
lc.clearDisplay(0);
}
void loop() {
for (int i = 0; i<8; i++) lc.setRow(0,i,sf[i]); // Display sad face
delay(1000);
for (int i = 0; i<8; i++) lc.setRow(0,i,nf[i]); // Display neutral face
delay(1000);
for (int i = 0; i<8; i++) lc.setRow(0,i,hf[i]); // Display happy face
delay(1000);
}
At the beginning of the script we include the library LedControl to use functions for controlling the 8×8 dot matrix display and binary to use binary codes values in the script.
Now we create an object LedControl and define the connection pins between the dot matrix display and the microcontroller. Because this script can be used with Arduino, ESP8266 or ESP32 microcontrollers, you have to uncomment the line that suits for your microcontroller and delete or comment the other lines of code. The last parameter defines how many displays are connected. In our case just the one and therefore is the last parameter 1.
In the next part of the script we define the arrays that contain the binary codes which LED dots should turn on to create a happy face (hf), a neural face (nf) and a sad face (sf). Each array has 8 elements for a 8×8 dot matrix display.
In the setup function we set the power saving mode to false that can be called with the shutdown function. Also the brightness can be controlled with the setIndensity function between 0 and 15. We set the brightness to a medium value of 5. In the last step of the setup function we make sure that alle LEDs are turned off with the clearDisplay function.
In the loop function we start to draw the three faces. Like in the first example, we only have to loop over the 8 rows of the dot matrix display and define which LEDs should turn on. This is done by the setRow function, that has the row and the corresponding element of the smiley array as argument. Between each smiley we wait for 1 second.
The following videos shows the three different faces that appear in the 8×8 dot matrix display.
Do you think that the way to choose the LEDs which should turn on is complicated? Yes you are right, but there is an easier way to make the program sketch. On this website you can select each LED and insert different patterns into a recorder.
The following video shows how to select different patterns. After you created one pattern you can press the button insert to save this pattern to the list. Now you create a second one and insert this also in the list. After you are done, press the update button to update the Arduino code from the right side.
If you scroll down the page you find different examples for the whole program code. You simply have to change the image array IMAGES.
The following program code shows how I created another example for the 8×8 dot matrix display.
#include "LedControl.h"
#include "binary.h"
LedControl lc=LedControl(8,10,9,1); // for Arduino microcontroller
//LedControl lc=LedControl(D7,D5,D8,1); // for ESP8266 microcontroller
//LedControl lc=LedControl(2,4,0,1); // for ESP32 microcontroller
const uint64_t IMAGES[] = {
0x0000000000000000,
0xff000000000000ff,
0x8142241818244281
};
const int IMAGES_LEN = sizeof(IMAGES)/8;
void setup() {
lc.clearDisplay(0);
lc.shutdown(0, false);
lc.setIntensity(0, 10);
}
void displayImage(uint64_t image) {
for (int i = 0; i < 8; i++) {
byte row = (image >> i * 8) & 0xFF;
for (int j = 0; j < 8; j++) {
lc.setLed(0, i, j, bitRead(row, j));
}
}
}
int i = 0;
void loop() {
displayImage(IMAGES[i]);
if (++i >= IMAGES_LEN ) {
i = 0;
}
delay(200);
}
Conclusion
In this article you learned how to use the 7 Segment Display as well as the 8×8 Dot Matrix Display. We discovered how to use the Shift Register to reduce the number of pins on your microcontroller and why you should not use the 4 7 Segment Display.
If you have any questions regarding segment displays or the sketches in this article, feel free to ask your question in the comment section below. I will answer all questions as soon as possible.
Hi, I think your site might be having browser compatibility issues. When I look at your website in Safari, it looks fine but when opening in Internet Explorer, it has some overlapping. I just wanted to give you a quick heads up! Other then that, very good blog!
https://maps.google.nu/url?q=https://latestbtcnews.com/video-marketing-agency-in-las-vegas-vegasseobitch-com/