More Outputs with a Shift Register

Draft. This tutorial has not been checked against the physical product yet. Confirm wiring, pin assignments and voltage limits against the product documentation before building it.
DifficultyIntermediate
CategoryDisplays
Supported boardsArduino Uno R3 and compatible ATmega328P boards
Time needed55 minutes
PrerequisitesDigital and Analog, and When Each Applies
Tested boardNot yet verified
Tested onNot yet verified
Arduino IDE versionNot yet verified
LibraryNot yet verified

What it does

A 74HC595 turns three Arduino pins into eight outputs. Chain two and three pins give you sixteen. Chain four and you have thirty-two, still on three pins.

It does this by taking the eight bits one at a time down a single wire, holding them in a row of internal latches, and then presenting all eight at once when you tell it to. That is what “shift register” means: the bits shift along inside the chip like people moving up a queue.

It is the cheapest answer to running out of pins, and once you have used one the trick appears everywhere: LED bars, seven-segment displays, relay banks, anything that needs more outputs than the board has.

Before you begin

Required parts and tools

  • An Arduino Uno or compatible board.
  • One 74HC595. Siratek product 2402 supplies these as bare 16-pin DIP chips, not on a module.
  • Eight LEDs and eight 220 ohm resistors, to see the output.
  • A breadboard and a good handful of jumper wires.

Handling a bare chip

This is probably the first bare integrated circuit in the library, so three things.

Find pin 1. There is a notch at one end of the package, and sometimes a dot beside pin 1. With the notch at the top, pin 1 is the top left, and the numbers run down the left side and back up the right. Pin 16 is the top right.

Straddle the breadboard’s centre channel. The gap down the middle of a breadboard exists for exactly this. Each row of eight holes on one side is a separate connection from the row opposite, so a chip sitting across the gap has every pin in its own row. Push it in on one side, then the other, gently, and expect the legs to need a slight squeeze inwards first.

Power it properly. Pin 16 to 5 V, pin 8 to ground. A chip with no supply does nothing and gives you no clue why.

The pins that matter

Chip pin Name What it does
14 DS or SER Data in, one bit at a time
11 SHCP or SRCLK Shift clock: one pulse moves one bit in
12 STCP or RCLK Latch clock: one pulse shows all eight at once
10 MR or SRCLR Clear, active low. Tie to 5 V
13 OE Output enable, active low. Tie to ground
9 Q7S Serial out, for chaining to the next chip
15, 1 to 7 Q0 to Q7 The eight outputs
16 VCC 5 V
8 GND Ground

Two of those catch people every single time.

Pin 10 must go to 5 V, not ground. It clears the register when low, so tying it low keeps the chip permanently blank.

Pin 13 must go to ground, not 5 V. It disables the outputs when high.

Leave either floating and you get behaviour that changes when you move your hand near the breadboard.

Note also that Q0 is pin 15, on its own at the top of one side, while Q1 to Q7 are pins 1 to 7 down the other. That is not a mistake in the table.

Why the latch pin exists

The data arrives one bit at a time, so for eight clock pulses the register’s contents are part-old and part-new. If the outputs followed the register directly you would see the bits scrolling across your LEDs on every update.

The latch is a second set of storage. The outputs show whatever was last latched, and only change when you pulse pin 12. So the sequence is always: latch low, send eight bits, latch high. The change appears in one clean step.

Pin reference

Chip pin Connect to Purpose
16 VCC Uno 5V Power
8 GND Uno GND Ground
14 DS Uno D11 Data
11 SHCP Uno D12 Shift clock
12 STCP Uno D8 Latch clock
10 MR Uno 5V Not clearing
13 OE Uno GND Outputs enabled
15, 1 to 7 An LED and a 220 ohm resistor each The eight outputs
A 74HC595 on a breadboard with three control lines from the Uno, pin 10 to 5V, pin 13 to ground, and eight LEDs on the outputs
Three pins in, eight out. Pin 10 goes high and pin 13 goes low, and both are easy to get backwards.

Wiring steps

  1. Unplug the USB cable.
  2. Seat the chip across the breadboard’s centre channel, notch to the left, and note where pin 1 is.
  3. Pin 16 to the 5V rail, pin 8 to the GND rail.
  4. Pin 10 to 5V. Pin 13 to GND.
  5. Pin 14 to D11, pin 11 to D12, pin 12 to D8.
  6. Put an LED and a 220 ohm resistor from each output to ground. Start with two, prove it works, then add the rest.
  7. Plug the USB cable back in.

Step 6 matters. Wiring eight LEDs before testing anything means that when nothing lights you have sixteen new connections to suspect as well as the chip.

Software and libraries

No library is required. shiftOut() is part of the Arduino core.

Minimal working example

// Siratek: eight outputs from three pins.

const int dataPin = 11;   // DS,   chip pin 14
const int clockPin = 12;  // SHCP, chip pin 11
const int latchPin = 8;   // STCP, chip pin 12

void writeOutputs(byte value) {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, value);
  digitalWrite(latchPin, HIGH);
}

void setup() {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  Serial.begin(9600);
  Serial.println("Siratek: counting in binary on eight LEDs.");
}

void loop() {
  for (int i = 0; i < 256; i++) {
    writeOutputs(i);
    delay(200);
  }
}

That counts from 0 to 255 in binary across the LEDs, which is the clearest possible demonstration that one byte is eight outputs.

MSBFIRST sends the most significant bit first, so bit 7 lands on Q7. Use LSBFIRST and the pattern appears mirrored. Neither is wrong; pick one and stay with it.

Controlling outputs by number

Counting in binary is a nice demonstration and an awkward way to say “turn on the third LED”. Bitwise operations fix that.

// Siratek: addressing the outputs individually.

const int dataPin = 11;
const int clockPin = 12;
const int latchPin = 8;

byte outputs = 0;   // our own copy of the eight states

void writeOutputs() {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, outputs);
  digitalWrite(latchPin, HIGH);
}

void setOutput(int which, bool on) {
  if (on) {
    outputs |= (1 << which);     // set that bit
  } else {
    outputs &= ~(1 << which);    // clear that bit
  }
  writeOutputs();
}

void setup() {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
}

void loop() {
  // a dot running back and forth
  for (int i = 0; i < 8; i++) {
    setOutput(i, true);
    delay(80);
    setOutput(i, false);
  }
  for (int i = 6; i > 0; i--) {
    setOutput(i, true);
    delay(80);
    setOutput(i, false);
  }
}

The important idea is the outputs variable. The chip cannot be read back, so you have to remember what you last sent. Changing one output means changing one bit in your own copy and sending the whole byte again.

1 << which builds a byte with a single bit set. |= turns that bit on, &= ~ turns it off, and the rest are untouched. This is worth learning once; it appears in every library that drives hardware.

Chaining two chips

// Siratek: sixteen outputs, still three pins.

void writeSixteen(byte high, byte low) {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, high);  // ends up in the far chip
  shiftOut(dataPin, clockPin, MSBFIRST, low);   // stays in the near one
  digitalWrite(latchPin, HIGH);
}

The wiring is: pin 9 of the first chip to pin 14 of the second, and the clock and latch lines shared by both. Bits sent first get pushed through the first chip and into the second, which is why the far chip’s byte goes first.

Power both from the same rails, and give each chip a 0.1 microfarad capacitor between its pin 16 and pin 8 if you see flicker.

Expected result

Eight LEDs counting in binary, changing cleanly together with no visible scrolling. If you can see the bits shift across before settling, the latch line is not connected to pin 12.

Troubleshooting

Symptom Likely cause Check or fix
Nothing at all Pin 10 tied low It must go to 5V
Nothing at all, pin 10 fine Pin 13 tied high It must go to GND
Nothing, chip cool No supply Pin 16 to 5V, pin 8 to GND
Bits visibly scroll across Latch not wired, or wrong pin Pin 12 to the latch pin
Pattern mirrored Bit order Swap MSBFIRST and LSBFIRST
One output dead LED backwards, or a bad row Q0 is pin 15, not pin 1
Outputs change when you touch the board A control pin floating Check pins 10 and 13
Works, then random after adding a second chip No decoupling 0.1 uF across each chip’s supply
LEDs dim with many lit Total output current Roughly 70 mA per chip is the ceiling
Chip warm Too much current drawn Fewer LEDs, or larger resistors

Next steps

  • Easier first: Your First Circuit, an LED and a Resistor.
  • Related: Driving a 4-Digit 7-Segment Display, which is the obvious thing to put on these outputs.
  • Next project: an LED bar that shows a sensor reading, with no pins used up.

Sources and attribution

All text, wiring guidance and code in this tutorial are original Siratek work.

  • 74HC595 datasheet for the pin functions, the active-low clear and output-enable behaviour and the output current limits.
  • Arduino core documentation for shiftOut().

Siratek product 2402 supplies the 74HC595 as a bare DIP chip rather than a module, read from the product photographs, which is why this tutorial covers pin numbering and seating a chip on a breadboard. No third-party tutorial text, diagrams, photographs or code has been reproduced here.

Product used in this tutorial: 74HC595 SHIFT REGISTERS
Shop
Sidebar
0 Wishlist
0 Cart