# Driving 7-segment Displays with 74HC595

![](/files/uyWaLcAa7tS8tPChevuS)

A [seven-segment display](https://en.wikipedia.org/wiki/Seven-segment_display) is a LED module composed of 8 LEDs. 7 of the LEDs are for segments of one digit (shown as **A** to **G** below) and the other LED is for the decimal point (shown as **DP** below).

![](/files/zAwrGMnbmV47eplAzOFu)

Depending on it's a common-anode or a common-cathode module, its schematic can be represented as:

**A common-anode seven-segment display**

![](/files/VzdQqPHcZCiaBF93NtTX)

or

**A common-cathode seven-segment display**

![](/files/yTLUdFklNNX9kRKg7gbl)

As a consequence, an intuitive way to control a seven-segment display is to use 8 GPIOs to connect to **A**, **B**, **C**, **D**, **E**, **F**, **G** and **DP** signal pins and control each pin as turning on/off an ordinary LED. Therefore the display can show any desired pattern composed of all those 8 segments.

**Use P7 to P14 to control a common-anode seven-segment display**

![](/files/wNlBROrHy8DRowspsvt8)

**Different combinations of possible displayed segments**

![](/files/2jzrRbWeZpWNztZ3Drcg)

### Using a shift register to reduce pin usage <a href="#driving7-segmentdisplayswith74hc595-usingashiftregistertoreducepinusage" id="driving7-segmentdisplayswith74hc595-usingashiftregistertoreducepinusage"></a>

In the above example, 8 GPIO pins are needed to drive a single seven-segment display. Though it's intuitive, this circuit setup is very pin-consuming. Assuming the case where a four-digit display is needed, this setup means a total 32 (8 pins x 4 digits) pins are required to control the display. It's usually not feasible for a development board to provide so many GPIOs and it also introduces huge complexity in the circuit setup. To solve this issue, a shift register chip can be used to reduce the necessary pin numbers for controlling a seven-segment display. In the following sections, the [74HC595](https://assets.nexperia.com/documents/data-sheet/74HC_HCT595.pdf) shift register chip would be used as an example. In the first part, we'll show how to simply use 3 GPIOs to control one seven-segment display by using a shift register. And based on this configuration, an example for how to extend it to control 4 seven-segment displays, by still using one shift register, is also introduced.

#### 74HC595 shift register <a href="#driving7-segmentdisplayswith74hc595-74hc595shiftregister" id="driving7-segmentdisplayswith74hc595-74hc595shiftregister"></a>

For saving the pin number for controlling a seven-segment display, a shift register is used as a serial-to-parallel converter to send signals to the display. That is, we serially send 8 bits of data, which represents the way we want to turn on the display, by one signal pin into the shift register and the register can output the corresponding data pattern to its 8 output pins at once (parallel).

Signal pins we need to take care about when using a 74HC595 are (please refer to its [datasheet](https://assets.nexperia.com/documents/data-sheet/74HC_HCT595.pdf) for pin names):

**Input pins**

* 1 input data pin (DS)
* 1 clock pin for input data (SHCP)
* 1 clock pin for output data (STCP)

**Output pins**

* 8 data pins (Q0 \~ Q7)

**Control pins**

* 1 output enable pin (OE)
* 1 data reset pin (MR)

And next we'll show the circuit connection for using it.

#### Driving one seven-segment display with 74HC595 <a href="#driving7-segmentdisplayswith74hc595-drivingoneseven-segmentdisplaywith74hc595" id="driving7-segmentdisplayswith74hc595-drivingoneseven-segmentdisplaywith74hc595"></a>

In the circuit below, LinkIt 7697 connects to the input pins of 74HC595 with **orange** wires and the output pins of 74HC595 are with **blue** wires.

![](/files/FpcvR84TIw4bFrR8twnU)

We use this sketch file to show hexadecimal digits (0 \~ 9 and a \~ f) repeatedly on a common-anode seven-segment display:

```
//
// Use one 74HC595 to control a common-anode seven-segment display
//

// pin 11 of 74HC595 (SHCP)
const int bit_clock_pin = 16;
// pin 12 of 74HC595 (STCP)
const int digit_clock_pin = 15;
// pin 14 of 74HC595 (DS)
const int data_pin = 14;

// digit pattern for a 7-segment display
const byte digit_pattern[16] =
{
  B00111111,  // 0
  B00000110,  // 1
  B01011011,  // 2
  B01001111,  // 3
  B01100110,  // 4
  B01101101,  // 5
  B01111101,  // 6
  B00000111,  // 7
  B01111111,  // 8
  B01101111,  // 9
  B01110111,  // A
  B01111100,  // b
  B00111001,  // C
  B01011110,  // d
  B01111001,  // E
  B01110001   // F
};

unsigned int counter = 0;

void setup()
{
  pinMode(data_pin, OUTPUT);
  pinMode(bit_clock_pin, OUTPUT);
  pinMode(digit_clock_pin, OUTPUT);  
}
 
void update_one_digit(int data)
{
  int i;
  byte pattern;
  
  // get the digit pattern to be updated
  pattern = digit_pattern[data];

  // turn off the output of 74HC595
  digitalWrite(digit_clock_pin, LOW);
  
  // update data pattern to be outputed from 74HC595
  // because it's a common anode LED, the pattern needs to be inverted
  shiftOut(data_pin, bit_clock_pin, MSBFIRST, ~pattern);
  
  // turn on the output of 74HC595
  digitalWrite(digit_clock_pin, HIGH);
}

void loop()
{ 
  int i;
  unsigned int digit_base;
  
  counter++;
  
  digit_base = 16;

  // get the value to be displayed and update one digit
  update_one_digit(counter % digit_base);
  
  delay(500);
}
```

**Explanation**

* Digit patterns are pre-defined in the *digit\_pattern* array, which indicates what segment needs to be turned on for composing one digit.
* [*shiftOut()*](https://www.arduino.cc/en/Reference/ShiftOut) API is called to serially send the data pattern to the shift register. **Note**: because a common-anode seven-segment display is used here, the data pattern needs to be inverted (*\~pattern*) for correctly showing the digit. If you're using a common-cathode display, the pattern doesn't need to be inverted (and of course, the circuit needs to be adjusted accordingly).
* *digit\_clock\_pin* is the signal we use to control the **STCP** pin of the 74HC595. It enables / disables the output of the shift register.

This example shows how to use 3 (instead of 8) pins on LinkIt 7697 to drive one seven-segment display with a shift register. In general, if there are *N* digits needed to be driven, *3N* signal pins and *N* shift registers are necessary. In the next section, we'll show another technique to simply use one shift register to drive a four-digit seven-segment display module.

### Driving four seven-segment display with one 74HC595 <a href="#driving7-segmentdisplayswith74hc595-drivingfourseven-segmentdisplaywithone74hc595" id="driving7-segmentdisplayswith74hc595-drivingfourseven-segmentdisplaywithone74hc595"></a>

When it comes to display more than one digit, more seven-segment displays are needed. According to the example above, *N*-digit display needs *N* shift registers and *3N* control pins from a development board. Here we use a commonly seen [four-digit seven-segment display module](http://www.icshop.com.tw/product_info.php/products_id/19357) to demonstrate how to drive four digits by still using one shift register.

The schematic of the display module is shown as below:

![](/files/RnoTbrNbnvo85D3Kygaa)

It's a common-anode four-digit seven-segment display. And we connect it with a 74HC595 and LinkIt 7697 as:

![](/files/9uYYVR1igmcx1GcV82Wo)

Similar to the previous example, LinkIt 7697 connects to the input pins of 74HC595 with **orange** wires and the output pins of 74HC595 are with **blue** wires. Moreover, four control pins (yellow wires) are needed from LinkIt 7697 to turn on / off each digit in the module. We use the sketch below to drive the display and it will show numbers counting increasingly as in the video:

{% embed url="<https://youtu.be/syLq1rJIpw4>" %}

**Sketch file**

```
//
// Use one 74HC595 to control a 12-pin common-anode 4-digit seven-segment display with fast scanning
// the display: http://www.icshop.com.tw/product_info.php/products_id/19357
//

#define DELAY_FACTOR  (100)
#define NUM_OF_DIGITS (4)

// 4 display on/off pin (for the common anode/cathode)
const int control_pins[NUM_OF_DIGITS] = {17, 5, 4, 3};
// pin 11 of 74HC595 (SHCP)
const int bit_clock_pin = 16;
// pin 12 of 74HC595 (STCP)
const int digit_clock_pin = 15;
// pin 14 of 74HC595 (DS)
const int data_pin = 14;

// digit pattern for a 7-segment display
const byte digit_pattern[16] =
{
  B00111111,  // 0
  B00000110,  // 1
  B01011011,  // 2
  B01001111,  // 3
  B01100110,  // 4
  B01101101,  // 5
  B01111101,  // 6
  B00000111,  // 7
  B01111111,  // 8
  B01101111,  // 9
  B01110111,  // A
  B01111100,  // b
  B00111001,  // C
  B01011110,  // d
  B01111001,  // E
  B01110001   // F
};

int digit_data[NUM_OF_DIGITS] = {0};
int scan_position = 0;

unsigned int counter = 0;

void setup()
{
  int i;

  // set related pins as output pins
  for (i = 0; i < NUM_OF_DIGITS; i++)
  {
    pinMode(control_pins[i], OUTPUT);
  }

  pinMode(data_pin, OUTPUT);
  pinMode(bit_clock_pin, OUTPUT);
  pinMode(digit_clock_pin, OUTPUT);  
}
 
void update_one_digit()
{
  int i;
  byte pattern;
  
  // turn off all digit
  for (i = 0; i < NUM_OF_DIGITS; i++)
  {
    digitalWrite(control_pins[i], LOW);
  }

  // get the digit pattern of the position to be updated
  pattern = digit_pattern[digit_data[scan_position]];

  // turn off the output of 74HC595
  digitalWrite(digit_clock_pin, LOW);
  
  // update data pattern to be outputed from 74HC595
  // because it's a common anode LED, the pattern needs to be inverted
  shiftOut(data_pin, bit_clock_pin, MSBFIRST, ~pattern);
  
  // turn on the output of 74HC595
  digitalWrite(digit_clock_pin, HIGH);

  // turn on the digit to be updated in this round
  digitalWrite(control_pins[scan_position], HIGH);

  // go to next update position
  scan_position++;
  
  if (scan_position >= NUM_OF_DIGITS)
  {
    scan_position = 0; 
  }
}

void loop()
{ 
  int i;
  unsigned int number;
  unsigned int digit_base;
  
  counter++;
  
  // get the value to be displayed
  number = counter / DELAY_FACTOR;

  digit_base = 10;

  // get every values in each position of those 4 digits based on "digit_base"
  //
  // digit_base should be <= 16
  //
  // for example, if digit_base := 2, binary values will be shown. If digit_base := 16, hexidecimal values will be shown
  //
  for (i = 0; i < NUM_OF_DIGITS; i++)
  {
    digit_data[i] = number % digit_base;
    number /= digit_base;
  }

  // update one digit
  update_one_digit();
  
  delay(4);
}
```

**Explanation**

* How to drive 4 displays with still one shift register? [Persistence of vision](https://en.wikipedia.org/wiki/Persistence_of_vision) is utilized and this sketch rapidly updates one digit in every *loop()* routine.
* The on / off switch of each digit is controlled through the *control\_pins* array.
* When the pattern is correctly set through the shift register, the sketch then turn on that digit by setting *control\_pins\[scan\_position]* to *HIGH*.
* Each *loop()* routine only updates one digit. In order to make the persistence of vision take effects, the *loop()* routine needs to be executed frequently.

As a result, you can simply use one shift register to drive 4 digits. Comparing to the original 8-GPIO-for-one-digit method, now only 7 control pins (instead of 32) from LinkIt 7697 are needed for driving 4 digits. This saves lots of control pins needed and reduces the circuit layout complexity.

### Summary <a href="#driving7-segmentdisplayswith74hc595-summary" id="driving7-segmentdisplayswith74hc595-summary"></a>

Seven-segment displays are commonly used in different areas to display numerical information for user interaction. So it's worth understanding how to drive them correctly and efficiently. In this tutorial, we introduced three ways to drive the seven-segment display:

1. Intuitive LED on / off mechanism.
2. Using one shift register to drive one digit.
3. Utilizing the effect of persistence of vision to drive a 4-digit display with one shift register.

This gives the fundamental concept about how to drive a seven-segment display and the idea about using a shift register as a serial-to-parallel converter. Also, the technique to utilize persistence of vision is introduced. In another tutorial, we will show how to control a 8-digit seven-segment display module with LinkIt 7697, by using a dedicated seven-segment display driving IC MAX7219.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cavedu.gitbook.io/linkit-7697/linkit-7697-development-guide-for-arduino-ide/tutorial/driving-7-segment-displays-with-74hc595.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
