16. Chapter 74HC595 & 7-Segment Display
In this chapter, we will introduce the 7-Segment Display.
16.1. Project 7-Segment Display.
We will use 74HC595 to control 7-segment display and make it display hexadecimal character “0-F”.
16.1.1. Component List
ESP32-S3 WROOM x1
|
GPIO Extension Board x1
|
||
Breadboard x1
|
|||
74HC595 x1
|
Resistor 220Ω x8
|
7-segment display x1
|
|
Jumper M/M |
|||
16.1.2. Component knowledge
16.1.2.1. 7-segment display
A 7-segment display is a digital electronic display device. There is a figure “8” and a decimal point represented, which consists of 8 LEDs. The LEDs have a common anode and individual cathodes. Its internal structure and pin designation diagram is shown below:
As we can see in the above circuit diagram, we can control the state of each LED separately. Also, by combining LEDs with different states of ON and OFF, we can display different characters (Numbers and Letters). For example, to display a “0”: we need to turn ON LED segments A, B, C, D, E and F, and turn OFF LED segments G and DP.
In this project, we will use a 7-Segment Display with a common anode. Therefore, when there is an input low level to a LED segment the LED will turn ON. Defining segment “A” as the lowest level and segment “DP” as the highest level, from high to low would look like this: “DP”, “G”, “F”, “E”, “D”, “C”, “B”, “A”. Character “0” corresponds to the code: 1100 0000b=0xc0.
For detailed code values, please refer to the following table (common anode).
CHAR |
DP |
G |
F |
E |
D |
C |
B |
A |
Hex |
ASCII |
|---|---|---|---|---|---|---|---|---|---|---|
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0xc0 |
1100 0000 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0xf9 |
1111 1001 |
2 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0xa4 |
1010 0100 |
3 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0xb0 |
1011 0000 |
4 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0x99 |
1001 1001 |
5 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0x92 |
1001 0010 |
6 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0x82 |
1000 0010 |
7 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0xf8 |
1111 1000 |
8 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0x80 |
1000 0000 |
9 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0x90 |
1001 0000 |
A |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0x88 |
1000 1000 |
B |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0x83 |
1000 0011 |
C |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0xc6 |
1100 0110 |
D |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
0xa1 |
1010 0001 |
E |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0x86 |
1000 0110 |
F |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0x8e |
1000 1110 |
16.1.3. Circuit
Schematic diagram |
|---|
|
Hardware connection. If you need any support, please contact us via: support@freenove.com |
|
16.1.4. Sketch
In this section, the 74HC595 is used in the same way as in the previous section, but with different values transferred. We can learn how to master the digital display by sending the coded value of “0” - “F”.
16.1.4.1. Sketch_7_Segment_Display
Verify and upload the code, and you’ll see a 1-bit, 7-segment display displaying 0-f in a loop.
The following is the program code:
1/**********************************************************************
2 Filename : 1 Digital 7 Segment Display
3 Description : Use 74HC595 to drive the digital display
4 Auther : www.freenove.com
5 Modification: 2022/10/24
6**********************************************************************/
7int dataPin = 12; // Pin connected to DS of 74HC595(Pin14)
8int latchPin = 13; // Pin connected to ST_CP of 74HC595(Pin12)
9int clockPin = 14; // Pin connected to SH_CP of 74HC595(Pin11)
10
11// Define the encoding of characters 0-F for the common-anode 7-Segment Display
12byte num[] = {
13 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
14 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e
15};
16
17void setup() {
18 // set pins to output
19 pinMode(latchPin, OUTPUT);
20 pinMode(clockPin, OUTPUT);
21 pinMode(dataPin, OUTPUT);
22}
23
24void loop() {
25 // display 0-F on digital tube
26 for (int i = 0; i < 16; i++) {
27 writeData(num[i]);// Send data to 74HC595
28 delay(1000); // delay 1 second
29 writeData(0xff); // Clear the display content
30 }
31}
32
33void writeData(int value) {
34 // Make latchPin output low level
35 digitalWrite(latchPin, LOW);
36 // Send serial data to 74HC595
37 shiftOut(dataPin, clockPin, LSBFIRST, value);
38 // Make latchPin output high level, then 74HC595 will update the data to parallel output
39 digitalWrite(latchPin, HIGH);
40}
First, put encoding of “0”- “F” into the array.
Then, in the loop, we transfer the member of the “num” to 74HC595 by calling the writeData function, so that the digital tube displays what we want. After each display, “0xff” is used to eliminate the previous effect and prepare for the next display.
1void loop() {
2 // display 0-F on digital tube
3 for (int i = 0; i < 16; i++) {
4 writeData(num[i]);// Send data to 74HC595
5 delay(1000); // delay 1 second
6 writeData(0xff); // Clear the display content
7 }
8}
In the shiftOut() function, whether to use LSBFIRST or MSBFIRST as the parameter depends on the physical situation.
1void writeData(int value) {
2 // Make latchPin output low level
3 digitalWrite(latchPin, LOW);
4 // Send serial data to 74HC595
5 shiftOut(dataPin, clockPin, LSBFIRST, value);
6 // Make latchPin output high level, then 74HC595 will update the data to parallel output
7 digitalWrite(latchPin, HIGH);
8}
If you want to display the decimal point, make the highest bit of each array become 0, which can be implemented easily by num[i]&0x7f.
1shiftOut(dataPin, clockPin, LSBFIRST, value);
16.2. Project 4-Digit 7-Segment Display
Now, let’s try to control more digit 7-segment display
16.2.1. Component List
ESP32-S3 WROOM x1
|
GPIO Extension Board x1
|
||
Breadboard x1
|
|||
74HC595 x1
|
Resistor 220Ω x8
|
7-segment display x1
|
|
Jumper M/M |
|||
16.2.2. Component knowledge
16.2.2.1. 4 Digit 7-Segment Display
A 4 Digit 7-segment display integrates four 7-segment displays into one module, therefore it can display more characters. All of the LEDs contained have a common anode and individual cathodes. Its internal structure and pin designation diagram is shown below:
The internal electronic circuit is shown below, and all 8 LED cathode pins of each 7-segment display are connected together.
Display method of 4 digit 7-segment display is similar to 1 digit 7-segment display. The difference between them is that the 4-digit displays each Digit is visible in turn, one by one and not together. We need to first send high level to the common end of the first digit display, and send low level to the remaining three common ends, and then send content to 8 LED cathode pins of the first Digit Display. At this time, the first 7-segment display will show visible content and the remaining three will be OFF.
Similarly, the second, third and fourth 7-segment displays will show visible content in turn by scanning the display. Although the four number characters are displayed in turn separately, this process is so fast that it is imperceptible to the naked eye. This is due to the principle of optical afterglow effect and the vision persistence effect in human sight. This is how we can see all 4 number characters at the same time. However, if each number character is displayed for a longer period, you will be able to see that the number characters are displayed separately.
16.2.3. Circuit
Schematic diagram |
|---|
|
Hardware connection. If you need any support, please contact us via: support@freenove.com |
|
16.2.4. Sketch
In this code, we use the 74HC595 IC chip to control the 4-digit 7-segment display, and use the dynamic scanning method to show the changing number characters.
16.2.4.1. Sketch_4_Dight_7-Segment_Display
Compile and upload code to ESP32-S3 WROOM, then the digital tube displays as shown.
The following is the program code:
1/**********************************************************************
2 Filename : 4 Digital 7 Segment Display
3 Description : Use 74HC595 to drive the digital display
4 Auther : www.freenove.com
5 Modification: 2024/07/01
6**********************************************************************/
7int latchPin = 39; // Pin connected to ST_CP of 74HC595(Pin12)
8int clockPin = 40; // Pin connected to SH_CP of 74HC595(Pin11)
9int dataPin = 38; // Pin connected to DS of 74HC595(Pin14)
10int comPin[] = {21,47,35,36};// Common pin (anode) of 4 digit 7-segment display
11
12// Define the encoding of characters 0-F of the common-anode 7-Segment Display
13byte num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
14 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
15
16void setup() {
17 // set pins to output
18 pinMode(latchPin, OUTPUT);
19 pinMode(clockPin, OUTPUT);
20 pinMode(dataPin, OUTPUT);
21 for (int i = 0; i < 4; i++) {
22 pinMode(comPin[i], OUTPUT);
23 }
24}
25
26void loop() {
27 for (int i = 0; i < 4; i++) {
28 // Select a single 7-segment display
29 selectDigitalDisplay (i);
30 // Send data to 74HC595
31 writeData(num[i]);
32 delay(5);
33 // Clear the display content
34 writeData(0xff);
35 }
36}
37
38void selectDigitalDisplay(byte com) {
39 // Close all single 7-segment display
40 for (int i = 0; i < 4; i++) {
41 digitalWrite(comPin[i], LOW);
42 }
43 // Open the selected single 7-segment display
44 digitalWrite(comPin[com], HIGH);
45}
46
47void writeData(int value) {
48 // Make latchPin output low level
49 digitalWrite(latchPin, LOW);
50 // Send serial data to 74HC595
51 shiftOut(dataPin, clockPin, LSBFIRST, value); // Make latchPin output high level
52// Make latchPin output high level, then 74HC595 will update data to parallel output
53 digitalWrite(latchPin, HIGH);
54}
First, define the pin of 74HC595 and 7-segment display common end, character encoding.
1int latchPin = 39; // Pin connected to ST_CP of 74HC595(Pin12)
2int clockPin = 40; // Pin connected to SH_CP of 74HC595(Pin11)
3int dataPin = 38; // Pin connected to DS of 74HC595(Pin14)
4int comPin[] = {21,47,35,36};// Common pin (anode) of 4 digit 7-segment display
5
6// Define the encoding of characters 0-F of the common-anode 7-Segment Display
7byte num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
8 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
Second, initialize all the pins to output mode.
1void setup() {
2 // set pins to output
3 pinMode(latchPin, OUTPUT);
4 pinMode(clockPin, OUTPUT);
5 pinMode(dataPin, OUTPUT);
6 for (int i = 0; i < 4; i++) {
7 pinMode(comPin[i], OUTPUT);
8 }
9}
Then, since there are four digital tubes, we need to write a subfunction to control it to turn ON any digital tube. In order not to affect a new display, each time we want to turn ON a digital tube, we need to set the other digital tube OFF.
1void selectDigitalDisplay(byte com) {
2 // Close all single 7-segment display
3 for (int i = 0; i < 4; i++) {
4 digitalWrite(comPin[i], LOW);
5 }
6 // Open the selected single 7-segment display
7 digitalWrite(comPin[com], HIGH);
8}
The usage of the writeData function is the same as in the previous two sections, so it won’t be covered again here.
1void writeData(int value) {
2 // Make latchPin output low level
3 digitalWrite(latchPin, LOW);
4 // Send serial data to 74HC595
5 shiftOut(dataPin, clockPin, LSBFIRST, value); // Make latchPin output high level
6// Make latchPin output high level, then 74HC595 will update data to parallel output
7 digitalWrite(latchPin, HIGH);
8}
In the loop function, because there are four digital tubes, a “for loop” is used to display the values of each one in turn. For example, when i =0, turn ON the first digital tube to display the first value, then turn ON the second digital tube to display the second value, until all four digital tubes display their own values. Because the displaying time from the first number to the fourth number is so short, it may display many times in one second, but our eyes can’t keep up with the speed of the digital tube, so we look as if the digital tube is displaying different Numbers at the same time.
1void loop() {
2 for (int i = 0; i < 4; i++) {
3 // Select a single 7-segment display
4 selectDigitalDisplay (i);
5 // Send data to 74HC595
6 writeData(num[i]);
7 delay(5);
8 // Clear the display content
9 writeData(0xff);
10 }
11}
If you want to display the decimal point, make the highest bit of each array become 0, which can be implemented easily by num[i]&0x7f.
1shiftOut(dataPin, clockPin, LSBFIRST, value); // Make latchPin output high level











