170pt Projects Part 3: The Humble Shift Register

In part 1 and 2 of this series, I introduced you to the 170pt breadboard, the LED, the Resistor, and some basic principles for combining these together into a simple circuit.

You might recall from in part 2 that connecting LEDs directly to the GPIO pins of your Raspberry Pi isn’t exactly the best way to do it. While it will work for one or two LEDs, you’ll quickly exhaust the feeble 51mA current available on these pins.

But there’s a saviour in the 5v pin of the Raspberry Pi. It’ll deliver plenty of current from which you can run a whole host of LEDs at, as the PiGlow demonstrates, frankly blinding levels of brightness!

Using the 5v pin isn’t quite as simple as just using a GPIO pin, however. You can easily connect a single LED from it, through a resistor, to Ground and the LED will light up. But the 5v pin can’t be toggled on and off like the GPIO pins on the Raspberry Pi, and there’s no fun in that!

Toggling the 5v pin from an IO pin

The easiest way to toggle a 5v supply from an of your 3.3v GPIO pins is a Transistor. Transistors are the most humble and essential of electrical components, and are the fundamental building blocks from which logic gates, and subsequently all modern processors are created.

A transistor is basically a switch, but instead of having a physical toggle it uses a second electrical signal to control whether it is on or off. This means you can safely use your 5v power supply to light an LED, while toggling the electrical “switch” with a 3.3v signal from your Raspberry Pi.

There are unfortunately two problems with using transistors to toggle LEDs. The first is complexity- a separate transistor, resistor and LED is fine if you just want one LED. But when you start to get two, three, 8 or more LEDs you’ll quickly be faced with not only a wiring nightmare but a circuit that won’t fit within our cute 170pt form-factor.

The second is IO usage. With a transistor for each LED, you’ll also need a GPIO pin for each LED. This means the number of available GPIO pins places upper limit on the number of LEDs you can drive, and once all the IO is consumed by LEDs we’ll have none left for buttons or other more exciting things.

Enter the Shift Register

A Shift Register, in our case the 74HC595 is a complex configuration of very tiny transistors ( around 200 of them at a very rough guess ) which are conveniently packaged into a thumbnail-sized Integrated Circuit package which you can push onto a breadboard and wire up very easily. It can drive a lot of LEDs with very few GPIO pins and can, by virtue of its “shifting” nature, also be “daisy chained” so that one Shift Register feeds the next and so on until you’ve got more outputs than you know what to do with.

Practically speaking the connection between one Shift Register and the next is no different to the connection between one bit inside a Shift Register and its neighbour. But what on earth is actually going on inside there?

How shifting works

The Shift Register is basically a chain of 8 Latching Flip Flops. A Flip Flop is a handy little arrangement of transistors which can be flipped from one state to the other; 1 or 0 ( high or low ) and will hold that state while it is powered. Think of it like a physical lever- the lever only changes when you move it, and then remains in place. A latching flip flop is similar, but conceptually involves two levers, one which you toggle yourself, and the other which mirrors the state of that lever until it is “latched” in place.

This behaviour is extremely useful in electronics because it is, at a very fundamental level, memory. By telling the lever to switch to 1, you’ve stored the number 1 until your circuit loses power.

A Shift Register connects multiple instances of these 1-bit memories together, so that the output state of one can be passed along as the input state of the next one. If you set the first one to 1 ( high ) and then toggle the latch, it will pass that 1 down the line to the next lever, and the next and so on.

Now, passing bits along a chain of Flip Flops doesn’t sound very useful, but when you take the output of each individual Flip Flop and use that to drive some LEDs you’ve effectively got a way of driving a theoretically ( but certainly not practically ) infinite number of LEDs from just two GPIO pins.

The 74HC595 Shift Register

Before you get excited at the prospect of driving a trillion LEDs from two GPIO pins, you should know that the physics of electrical signals won’t let you get quite so ambitious ( and neither will your wallet, I suspect ). The most common Shift Register used today is known as the 74HC595 series, and you probably won’t connect more than a few of these together in a row. There are much more effective ways for driving tens and hundreds of LEDs, and overcoming the various problems with such long chains.

The 74HC595 takes the basic concept of 8 daisy-chained Flip Flops and wraps it up with some convenient additional features. The most useful of these is an 8-bit memory which lets you keep your LEDs lit up in one state while you shift out a new set of signals.

It also has an Output Enable pin, which allows you to turn on or off the 8 outputs separately. This sounds useless, but can be cleverly toggled on and off at high frequencies to dim your LEDs- WiringPi’s SoftPwm will do this nicely!

Wiring up the Shift Register

Wiring up the 7HC595 Shift Register on a 170pt breadboard is a little tricky, but it’ll just fit alongside 8 LEDs and a monumental mess of resistors. The best solution to this problem is the brilliant SIL ( single in-line ) resistor package, which contains 8 resistors wired in line with a 9th pin that makes a single common connection between them- this can plug in alongside the LEDs and sort out the resistors in one single package. Alternatively, If you’ve got some soldering skills you could solder the resistors inline with the LEDs, but otherwise you might want to either:

  • Very carefully position the resistors so they don’t cross over

or

  • Cover the resistor leads in a bit of spare flex or shrink wrap

or

  • Just use a bigger breadboard, but where’s the fun in that!?

I first opted for b, which I accomplished by stripping some of the coating from a length of wire and slipping it over the resistor leads. I then tidied this up using the homemade SIL resistor network from my half-hour hacks article.

Apart from the mess of resistors, the layout is pretty straight forward. You’ll need ( wires from our jumper lead selection can be substituted with any wire you can cut to length ):

  • 1x 74HC595 shift register
  • 8x 330Ohm resistors
  • 8x LEDs
  • 5x Female to Male jump wires ( peel some off our Jumper Jerky )
  • 8x brown jump wires ( from our jumper lead selection )
  • 1x blue jump wire ( from our jumper lead selection )
  • 2x white jump wire ( from our jumper lead selection )
  • 1x 1uF capacitor

To put together the circuit, you must:

  1. Place the Shift Register on the far left, with the notch facing left
  2. Bridge rows 1 to 7 on the top of the breadboard with a blue wire
  3. Bridge row 4 from the top to row 8 on the bottom with a white wire
  4. Bridge row 8 from the bottom to row 9 on the top also with a white wire
  5. Bridge rows 10 through to 17 on the top to row 9 on the top with resistors- this may be tricky if you're opting for single resistors, so look into using a SIL network, a custom SIL network or homemade resistor-LEDs instead.
  6. Plug an LED into each row from 10 to 17, bridging the grove in the middle and making sure the short leg is towards the resistor and the long leg is towards the bottom.
  7. Bridge row 2 on the top to row 10 on the bottom with a brown wire
  8. Now grab the remaining 7 brown jump wires and bridge rows 1 to 7 on the bottom to rows 11 to 17 on the bottom.

Pinout for the 74HC595 Shift Register

Your shift register should now be set up and ready to use. The next step is to get it connected to your Raspberry Pi and start shifting out some bits.

Connecting To Your Pi

You need to make 5 connections to your Pi in order to use a shift register. These are Power, Ground, Data, Latch and Clock. It really doesn't matter where you connect Data, Latch and Clock but there's a convinient row of three pins between Ground and Power that I like to use- BCM 17, 27 and 22 respectively.

Since they line up nicely, let's connect up power to physical pin 17 ( the 3v3 power pin about half way along the header ) and then Data to BCM 22, Latch to BCM 27 and Clock to BCM 17.

The Code: Part 1, the theory

The code for shifting out is simple, although the most difficult concept to grasp is the idea of bits and how to shift through a byte to get the value of each bit.

A byte is really nothing but a sequence of 8 bits like 0b10100000. Shifting bits does exactly what you might think- you move them to the left or to the right.

If we take our example byte, 0b10100000, and imagine we want to copy it to our register how might we approach this? Well since the register only has one data pin, we have to do it serially, one bit at a time. The alternate to this would be a parallel transfer, which would involve 8 pins set to the state of each of our bits- inidentally this is what the Shift Register outputs which is why it's often called a Serial to Parallel Shift Register.

To check the first bit in our sequence, we need to use the 'bitwise' operator 'and', in Python this is just the ampersand character: &.

0b10100000 & 1 = 0

Why does this equal 0? Well, 1 is what you get when you set the lowest possible bit, so we can expand this to:

0b10100000 & 0b00000001 = 0

It's easy to see now why it's 0. We're comparing the bits on the far right, 0 and 1 will always equal 0.

Using this very simple logical operator we've extracted the first bit, now let's see how we extract the next bit before worrying about how to send them to a Shift Register.

0b10100000 >> 1 = 0b01010000

Woah, what just happened? We used the logical shift right operator. This shifts every single bit in our byte right by one place and fills in the left most bit with a zero. This has removed the bit we just checked and replaced it with a new zero, so our next value is zero. Let's shift a few more times and see what we get:

0b01010000 >> 4 = 0b00000101

We've skipped a few places so that we get a 1 in the position we're checking. Now what happens if we 'and' it?

0b00000101 & 1 = 1

It's flipped to a 1. 1 and 1 = 1. Now we have some idea of how to move bits around and get their values sequentially for outputting on an IO pin, let's try some code:

The Code: Part 2, the actual code

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
PIN_DATA  = 22
PIN_LATCH = 27
PIN_CLOCK = 17
GPIO.setup(PIN_DATA,  GPIO.OUT)
GPIO.setup(PIN_LATCH, GPIO.OUT)
GPIO.setup(PIN_CLOCK, GPIO.OUT)

def shiftout(byte):
  GPIO.output(PIN_LATCH, 0)
  for x in range(8)
    GPIO.output(PIN_DATA, (byte >> x) & 1)
    GPIO.output(PIN_CLOCK, 1)
    GPIO.output(PIN_CLOCK, 0)
  GPIO.output(PIN_LATCH, 1)

Not bad, eh? A very simple piece of code, for a simple concept. What we've done here is condensed the ideas presented in our theory section into a single line of code.

GPIO.output(PIN_DATA, (byte >> x) & 1)

Every iteration of our for loop gives us a new value of x from 0 to 7. Our byte shifted right by 0 is - well - an unmodified byte, so this gives us the right-most number. 'And' this with 1 and you get a single 1 or 0 which we can use to write straight out to our PIN_DATA.

The next iteration gives us an x of 1, which shifts our byte right 1 place, moves the new bit into place and changes the outcome of the 'and' operation accordingly.

Using the code!

Now it's time to find some LEDs and resistors, hook them up to your Shift Register and start shifting out bits. Try something like the following to shift out the numbers 0 to 255 ( the range of a byte ) and see your LEDs count up in binary:

import time
for x in range(255):
  shiftout(x)
  time.sleep(0.001)
That's all folks!

Search above to find more great tutorials and guides.

Plasma 2040

Swathe everything in rainbows with this all-in-one, USB-C powered controller for WS2812/Neopixel and APA102/Dotstar addressable LED strip.