One of the nice things about the Arduino is that it has a fair amount of I/O pins to work with. You can wire up a few buttons, sensors, servos, and so on, but as the list grows, you will quickly run out of pins.
The solution is to use a ‘shift register,’ which allows you to add more I/O pins to the Arduino (or any microcontroller). By far the most widely used shift register is the 74HC595, also known as just “595”.
The 74HC595 controls eight different output pins with only three input pins. If you need more than 8 I/O pins, you can daisychain as many shift registers as necessary to generate a large number of I/O pins.
The 74HC595 achieves this through a technique known as bit-shifting. If you are interested in learning more about bit-shifting, you will find this Wikipedia article extremely useful.
When Should You Use a Shift Register?
Shift registers are often used to increase the number of I/O pins on a microcontroller.
For example, If your project needs to control 16 individual LEDs, you will, of course, require 16 pins of an Arduino, which is not possible. This is where the shift register comes in handy.
With two shift registers connected in series, you can control 16 LEDs with only three I/O pins. That is quite a difference, and the more shift registers you chain together, the more pins you’ll add. In theory, by daisy-chaining shift registers, an infinite number of I/O pins can be added.
The Original Nintendo Controller, released in 1985, is a practical application of a shift register. The main microcontroller of the Nintendo Entertainment System, used shift registers to gather button presses from the controller.
SIPO vs PISO Shift Registers
There are two types of shift registers, SIPO (serial-in-parallel-out) and PISO (parallel-in-serial-out).
SIPO is useful for controlling a large number of outputs, such as LEDs. While PISO is useful for gathering a large number of inputs, such as buttons, similar to the original Nintendo controller discussed above.
The most popular SIPO chip is 74HC595, and the most popular PISO chip is 74HC165.
How does the 74HC595 Shift Register work?
The 74HC595 has two 8-bit registers (which can be thought of as “memory containers”). The first is referred to as the Shift Register, and the second as the Storage/Latch Register.
Every time the 74HC595 receives a clock pulse, two things happen:
- The bits contained in the shift register are shifted to the left by one position. Bit 0’s value is pushed into bit 1, while bit 1’s value is pushed into bit 2, and so on.
- Bit 0 in the shift register accepts the current value on the DATA pin. On the rising edge of the clock pulse, if the DATA pin is high, 1 is pushed into the shift register, otherwise 0.
This process will continue as long as 74HC595 is clocked.
When the latch pin is enabled, the contents of the shift register are copied to the storage/latch register. Each bit of the storage register is linked to one of the IC’s output pins QA-QH. As a result, whenever the value in the storage register changes, the output changes.
The animation below will help you understand it better.
74HC595 Shift Register Pinout
It is important to note that several companies manufacture the same 74HC595 chip. In this article, we will discuss the ubiquitous SN74HC595N from Texas Instruments. If you happen to have a different one, carefully read the datasheet and make note of any differences.
Let’s take a look at its pinout.
GND is the ground pin.
VCC is the power supply for the 74HC595 shift register, which must be connected to 5V.
SER (Serial Input) pin is used to send data into the shift register one bit at a time.
SRCLK (Shift Register Clock) is the clock for the shift-register and is positive-edge triggered. This means that the bits are pushed in on the rising edge of the clock.
RCLK (Register Clock / Latch) is a very important pin. When this pin is pulled HIGH, the contents of the Shift Register are copied into the Storage/Latch Register, which eventually appears at the output. So, the latch pin can be seen as the last step before we see our results at the output.
SRCLR (Shift Register Clear) pin allows us to reset the entire Shift Register, setting all the bits to zero. Because this is an active-low pin, we must pull the SRCLR pin LOW to perform the reset.
OE (Output Enable) is also an active-low pin: when pulled HIGH, the output pins are disabled (set to high impedance state). When it is pulled LOW, the output pins function normally.
QA–QH (Output Enable) are the output pins.
QH’ pin outputs bit 7 of the shift register. This allows you to daisy-chain the 74HC595s. If you connect this pin to the SER pin of another 74HC595, and feed both ICs the same clock signal, they will behave as if they were a single IC with 16 outputs. Of course, with this technique, you can daisy-chain as many ICs as you want.
Wiring a 74HC595 Shift Register to an Arduino
Now that we know the basics of how 74HC595 works, we can start connecting it to our Arduino!
Start by putting the shift register on your breadboard. Make sure that each side of the IC is on a different side of the breadboard. With the little U-shaped notch facing up, pin 1 of the chip is to the left of this notch.
Connect pins 16 (VCC) and 10 (SRCLR) to the Arduino’s 5V output, and pins 8 (GND) and 13 (OE) to the ground. This should keep the IC in the normal working mode.
Next, connect the three pins that will be used to control the shift register. Connect pin 11 (SRCLK), pin 12 (RCLK), and pin 14 (SER) of the shift register to the Arduino’s pins 6, 5, and 4, respectively.
All that remains is to connect the LEDs to the output pins. Connect the cathode (short pin) of each LED to a common ground, and the anode (long pin) of each LED to its respective shift register output pin.
Don’t forget to add a 220Ω resistor in series to protect the LEDs from being overloaded.
When connecting the LEDs, ensure that QA is connected to the first LED and QH is connected to the last; otherwise, the LEDs will not light up in the correct order!
The following diagram shows you how to wire everything up.
Using the shift register to supply power in this manner is called sourcing current. Some shift registers can’t source current, they can only do what is called sinking current. If you have one of those, you will need to reverse the direction of the LEDs, connecting the anodes directly to power and the cathodes to the shift register outputs.
Arduino Example Code
Here is an example sketch that turns on each LED in turn until they are all on, then turns them all off and the cycle repeats.
First, try out the sketch, and then we’ll go over it in detail.
int latchPin = 5; // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 6; // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 4; // Data pin of 74HC595 is connected to Digital pin 4
byte leds = 0; // Variable to hold the pattern of which LEDs are currently turned on or off
/*
* setup() - this function runs once when you turn your Arduino on
* We initialize the serial connection with the computer
*/
void setup()
{
// Set all the pins of 74HC595 as OUTPUT
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
/*
* loop() - this function runs over and over again
*/
void loop()
{
leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0
updateShiftRegister();
delay(500);
for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one.
{
bitSet(leds, i); // Set the bit that controls that LED in the variable 'leds'
updateShiftRegister();
delay(500);
}
}
/*
* updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again.
*/
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
After uploading the code to the Arduino, you should see the following output:
Code Explanation:
The first step is to define the three control pins of the 74HC595, namely the latch, clock, and data pin, which are connected to the Arduino’s digital pins #5, #6, and #4, respectively.
int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
Next, a variable called leds
of datatype byte
is defined. The byte datatype can store eight bits, which is ideal for tracking the on/off status of eight LEDs.
// Variable to hold the pattern of which LEDs are currently turned on or off
byte leds = 0;
In the ‘setup’ function, we simply configure the three pins to be digital output.
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
The loop function first turns off all the LEDs by setting all the bits of the variable leds
to 0 and calling a custom function updateShiftRegister()
. We’ll talk about how updateShiftRegister()
works later.
The program pauses for half a second before counting from 0 to 7 using the for
loop and the variable i
.
During each iteration, the built-in function bitSet()
is called to set the bit in the variable leds
that controls a particular LED, and the function updateShiftRegister()
is called to change the status of LEDs. Then there is a half-second delay before incrementing i
and turning on the next LED.
void loop()
{
leds = 0;
updateShiftRegister();
delay(500);
for (int i = 0; i < 8; i++)
{
bitSet(leds, i);
updateShiftRegister();
delay(500);
}
}
The function updateShiftRegister()
first sets the latch pin to LOW and then calls the built-in function shiftOut()
before setting the latch pin to HIGH again.
The Arduino IDE includes a shiftOut() function that is designed specifically for shift registers. This function allows us to shift out a byte of data one bit at a time.
The shiftOut()
function accepts four inputs, the first two of which are Data and Clock pins. The third parameter specifies whether the bits should be shifted out in MSBFIRST or LSBFIRST order (Most Significant Bit First, or, Least Significant Bit First). The final parameter is the actual data to be shifted out, in this case leds
.
Setting the latch pin to HIGH copies the contents of the Shift Register into the Storage/Latch Register. Notice that we set the latch pin LOW before shifting bits because, if we don’t, the wrong LEDs would flicker while data is being loaded into the shift register.
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
Arduino Example 2: Controlling Brightness Using PWM
Here’s another project based on the same setup but with a slight variation: we manipulate the OE pin on the IC to control the brightness of the output LEDs!
We already know that the OE (Output Enable) pin functions as a switch. When this pin is set to HIGH, the output pins are disabled (remember, it is active-low). When OE is set to LOW, the output pins function normally.
In our previous example, we connected OE to ground, allowing the output to be active at all times. If we connect this pin to any of the Arduino’s digital pins and program it to toggle its state, we can get the following result.
However, by connecting OE to any of the Arduino’s PWM-enabled pins, we can control the brightness of the LEDs, as shown below.
Wiring
All you have to do is change the connection to 74HC595’s pin 13 (OE). Instead of connecting OE to ground, connect it to Arduino pin 3.
Example Code
This sketch works similarly to the previous one, with the exception that once all of the LEDs are lit, they will gradually fade back to off.
int latchPin = 5; // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 6; // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 4; // Data pin of 74HC595 is connected to Digital pin 4
int outputEnablePin = 3; // OE pin of 74HC595 is connected to PWM pin 3
byte leds = 0; // Variable to hold the pattern of which LEDs are currently turned on or off
/*
* setup() - this function runs once when you turn your Arduino on
* We initialize the serial connection with the computer
*/
void setup()
{
// Set all the pins of 74HC595 as OUTPUT
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(outputEnablePin, OUTPUT);
}
/*
* loop() - this function runs over and over again
*/
void loop()
{
setBrightness(255);
leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0
updateShiftRegister();
delay(500);
for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one.
{
bitSet(leds, i); // Set the bit that controls that LED in the variable 'leds'
updateShiftRegister();
delay(500);
}
for (byte b = 255; b > 0; b--) // Gradually fade all the LEDs back to off
{
setBrightness(b);
delay(50);
}
}
/*
* updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again.
*/
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
/*
* setBrightness() - Generates PWM signal and writes it to OE pin.
*/
void setBrightness(byte brightness) // 0 to 255
{
analogWrite(outputEnablePin, 255-brightness);
}
When you upload the code to the Arduino, you should see the following output: