connecting an arduino to a seven segment display

Connecting an Arduino to a 7 segment display – part 2: reducing microcontroller pins

In my previous post, I showed how to connect seven segment displays to your Arduino microcontroller and how to drive them through multiplexing to display numerical values from your program.
In this post, I will build on that circuit and reduce the number of pins used on your microcontroller, as promised.
The circuit so far had 12 microcontroller pins used up to drive the seven segments (and decimal point) and select each individual digit display. What if you can reduce the number of pins to just 3? Easy! We can do this using shift registers.

What is a shift register?

A shift register is a device that stores and then output data it receives. It is called a shift register because generally data is shifted into or out of the device serially one bit at a time. You generally have two types: serial-in-parallel-out and parallel-in-serial-out. The first type allows you to clock in a series of bits (usually 8 bits, a byte) on its data and clock pins and output the bits in parallel on 8 of its pins. This saves I/O pins on a microcontroller where only 2 or 3 pins control 8 pins of data. Even more, shift registers can generally be daisy-chained allowing more than just 8 bits without needing more pins on your microcontroller.
Some serial-in-parallel-out devices come with a latch. The register is internal allowing you to shift in data without immediately affecting the output while doing so. Once all the data is shifted in, the latch is engaged copying the internal register state to the output pins. Shift registers without a latch sees the output pins update with each clock cycle.

Parallel-in-serial-out shift registers capture data on its input pins into an internal register which then can be shifted out one bit at a time. Once again only 3 pins on the microcontroller is required to read in many bits of data.

The 74HCT595 shift register

M74HC595B1 Shift Registers with Latch

74HC595 Pin Layout
74HC595 Pin Layout
The 74HCT595 is an 8-bit serial-in-parallel-out shift register with a latch and three-state outputs. One is able to daisy-chain more than one together to increase the number of bits to output.
tri state pin as a three way switch
A tri-state pin can be seen as a three way switch
So what does three-state output mean? It means that pins can have the normal two states, high and low, but also a third state called high-impedance, or Hi-Z. the third state makes it seem like the pins aren’t connected to the data lines. This is useful in a data bus where more than one device can try to access a shared bus of data lines. When a device on the bus is in Hi-Z mode, another device can be allowed to output its own data over the shared data lines.

74HC(T)595 Pin Descriptions
Pin Pin Name Description
1-7, 15 Q0..7 The 8 output bits
8 GND Connected to ground
9 Q7S The first bit shifted in will after 8 clocks shift out here, that is the previous value of register position Q7
10 ¬MR Master Reset: If this is made LOW, the shift register’s data and outputs will be reset to zero.
11 SHCP Shift register clock input: A low-to-high transition on this pin will shift in the data bit into the shift register.
12 STCP Storage register clock input: A low-to-high transition on this pin will transfer the internal shift register data to the output register. Data in the storage register
appears at the output whenever the output enable input (¬OE) is LOW
13 ¬OE Output enable: When pulled low, the outputs are enabled and carry their latched value. If pulled high, the outputs are put in Hi-Z mode.
14 DS The data pin: Data from this pin is shifted into the register on each clock pulse.
16 Vcc Connected to 5V

Updated circuit

arduino seven segment 74hct595
For our seven segment display circuit, we’ll add two 74HCT595 ICs. One will drive the seven individual segments and the decimal point. The other will drive each individual display. We remove all the connections from the Arduino and connect the wires to the two shift registers. we connect the data, clock, and latch wires between the Arduino and the shift registers. The clock and latch wires are shared in parallel between the two shift registers. This allows us to clock and latch both registers at the same time. The data line from the Arduino is input to only one shift register (the one for the segments). To daisy-chain the two devices, a wire connects the serial data out of the one shift register to the data input of the next. Finally, we make sure that the power pins are connected. Connect the Output Enable pin to ground (it’s an active low pin) and the Master Reset pin to 5V (Vcc).

Updated Arduino code

First we define the pins in the header of our code:

#define DATAPIN 24
#define DATACLOCK 25
#define DATALATCH 26

In void setup() we start off by defining the three pins as outputs.


In void loop() we first pull the Latch pin low:

digitalWrite(DATALATCH, LOW);

As in the previous post, we get the next digit’s number and the pattern for the display:

nextDigitTime = millis() + digitInterval;
digit = (digit + 1) % numDigits;

unsigned char pattern;
if ((value < 0) && (digit == numDigits - 1))   {
  pattern = 0b10111111;
} else {
  pattern = pgm_read_byte_near(sevensegment + (abs(int(value / pow(10, digit))) % 10));

if (digit == decimalPoint) {
  pattern &= 0b01111111;

The magic in using an Arduino with shift registers is that there's a function made just for that type of application! It's called shiftOut and here is how it is used in this application:

shiftOut(DATAPIN, DATACLOCK, LSBFIRST, 1 << digit);

This will deal with the shifting and clocking of data into the shift registers for us so we don't have to worry about the details of doing that.
Now the two bytes of data is clocked into the two shift registers, we can latch the data to the shift register outputs:

digitalWrite(DATALATCH, HIGH);

The data is latched only on the low-to-high transition.

That should be it for this tutorial. Hope everything is understandable and clear enough. Feel free to leave comments or questions below and I'll try to answer them.

Start building now

Get about 10 now. They can be very versatile. Product - 10 x M74HC595B1R 74HC595 8 Bit Shift Register 74HC595N DIP 16


2 thoughts on “Connecting an Arduino to a 7 segment display – part 2: reducing microcontroller pins

  1. hey,
    when I try this, it says that “nextDigitTime” was not declared in this scope 🙁
    What can I do?

    Thanks for answer

  2. Hi.
    I notice that I didn’t include the declarations for the various variables.
    Here is what I used. I placed it right before the setup() function:

    long value;
    double aValue;
    unsigned char digit;
    unsigned char decimalPoint = 3;
    char s_buf[20];
    unsigned long nextValueTime;
    const unsigned long valueInterval = 100;
    unsigned long nextDigitTime;
    unsigned long digitInterval = 3;
    bool minus = false;

    You may have a look at the .ino file at:

Leave a Comment