Control LEDs with Explorer HAT Pro and an 8-bit shift register
This intermediate tutorial will show you how to use Explorer HAT Pro to control 8 LEDs (or even more...) from just 3 output pins. Because Explorer HAT Pro has just 4 output pins, normally, you would be able to control only 4 LEDs, but the 8-bit shift register is a cunning little bit of kit. The wiring here is a bit of a logistical nightmare, but hopefully with the wiring diagram you'll manage.
8-bit shift registers for dummies
In very simple terms, the 8-bit shift register has a series of 8 on/off switches that can hold the values 0 (off) or 1 (on). These 8 bits make 1 byte and can encode integer values up to 255 in binary. Each of these 8 bits are filled up one-by-one and shifted along each time a new one is filled, hence the name shift register. There are two latch pins that lock in these bits, the shift register clock (SRCLK) and the storage register clock (RCLK), as well as a serial (SER) pin that sets each bit on or off.
Each of the 8 bits controls one output pin, and we'll use these 8 output pins to control our 8 LEDs. This method of controlling multiple output pins with only a few input pins is known as serial-in-parallel-out (SIPO) as the information is passed in serially (the 8 bits) and then sent out in parallel (the states of the 8 output pins are updated at the same time).
There's a slight complication with using Explorer HAT Pro to control the shift register, in that we need to be able to set the output pins to high or low, and the Explorer HAT's output pins get pulled to ground (low) when they are switched on rather than high. Fortunately, there's an easy solution - pull-up resistors - which will pull the output pins to high when they are off, meaning that off is on and on is off. These are simple to connect up, we just connect the three input pins of the shift register up to three of the Explorer HAT Pro's output pins and also connect each of these to the 5V supply from Explorer HAT pro via a 10 kΩ resistor.
Setting the hardware up
We need quite a few things to set this all up:
- A Raspberry Pi
- Explorer HAT Pro
- 74HC595 8-bit shift register
- 8 5mm LEDs
- 8 470 Ω resistors
- 3 10 kΩ resistors
- A mini breadboard or 400 point (half-size) breadboard
- A bunch of jumper leads
Note that you can get all of this, with the exception of the Raspberry Pi, Explorer HAT and mini breadboard, in the Explorer HAT Pro parts kit.
I've set this up a couple of different ways. In the wiring diagram below, I've put the LEDs and voltage-limiting resistors on one mini breadboard and the shift register and pull-up resistors on the mini breadboard on Explorer HAT Pro. You can, and I have, put everything on the same mini breadboard, but the wiring is a complete nightmare! If you want everything on the same breadboard, then I'd suggest using a larger half-size breadboard.
Here's the wiring diagram.
I connected the shift register clock (SRCLK) pin to output one on Explorer HAT pro, the storage register clock (RCLK) pin to output two and the serial (SER) pin to output three, but this doesn't matter as long as you specify the pins correctly in the Python code.
Setting the software up
I've created a new plugins module, in my fork of the Explorer HAT Python library, that
ShiftRegister class with methods for toggling the pins on or off and a few
different patterns to use with LEDs.
Here's how to clone and install my fork:
curl https://get.pimoroni.com/i2c | bash sudo apt-get install python-smbus git clone https://github.com/sandyjmacdonald/explorer-hat.git cd explorer-hat/library sudo python setup.py install
I'll explain below how to use the
ShiftRegister class and how it works, but if
you're impatient, or just want to make sure that you've connected it all up correctly,
then you can start an interactive Python prompt by typing
python and pressing return.
Type the following to run a demo of the
from explorerhat import plugins shiftreg = plugins.ShiftRegister() shiftreg.demo()
This should blink all 8 LEDs on and off 5 times, run along the line of LEDs 5 times, alternately blink the odd and even LEDs 5 times and run back and forth along the line of LEDs 5 times.
How it works and how to use the ShiftRegister class
Here's the basic function from the
ShiftRegister class that toggles a pin on or off:
import explorerhat srclk = explorerhat.output.one rclk = explorerhat.output.two ser = explorerhat.output.three def toggle_pin(pin, state): rclk.on() for p in range(8): srclk.on() if p == pin: if state == 1: ser.off() else: ser.on() else: if state == 1: ser.on() else: ser.off() srclk.off() rclk.off()
So, if you want to toggle on LED 1 (remember that indices begin from 0 in Python, so
pin 1 is actually pin 0) you would simply use
toggle_pin(0, 1). Note that the
variable uses 0 for off and 1 for on in this function.
We'll break down how the function works.
Outside our function, we import the
explorerhat library and define our
toggle_pin function takes two variables -
state - that define the pin
we want to toggle and whether to toggle it off or on (0 or 1 respectively).
Remember that the pull-up resistors reverse what is happening with the output pins, so when it says on in the function, that's actually off and vice versa.
We toggle the storage register clock pin,
rclk, off to begin with
Then for each output pin,
for p in range(8):, we first toggle the shift register
srclk, off with
Then we check whether it's the pin we want to
toggle on or off with
if p == pin:. If it is, we check whether to toggle it on
if state == 1: and switch the serial pin,
ser, on with
we switch it off with
We toggle the shift register clock,
We then go through the remainder of the eight pins, doing the same as we did above - toggling the shift register clock off, checking whether it's the pin we want to toggle on or off and then toggling the serial pin accordingly, and toggling the shift register clock on each time.
Finally, we toggle the storage register clock pin,
rclk, on, to shift out all of the
bits we stored.
So, that's how the basic function to toggle a single output pin on or off works. Obviously, if we wanted to toggle several pins simultaneously, this function wouldn't do, because if we toggle one pin on, it assumes we want to toggle all of the others off.
To toggle all of the pins on or off, we'd just have the same function, with the
for p in range(8): loop, but exclude the
if p == pin: and
else, as follows:
def toggle_all(self, state): rclk.on() for p in range(8): srclk.on() if state == 1: ser.off() else: ser.on() srclk.off() rclk.off()
In the Explorer HAT pro Python plugins module that I've written, there's a
class that can be used to control the shift register with a number of methods of the
class (they're just functions that belong to the class). This allows us to create
objects assigned to a variable, e.g.
shiftreg = plugins.ShiftRegister(), and then
run the methods within the class, like the demo method, with
Other methods of the ShiftRegister class
Here's the full list of methods available so far in the
shiftreg.toggle_pin() # Toggle a single pin shiftreg.toggle_all() # Toggle all of the pins shiftreg.toggle_odd() # Toggle the odd numbered pins shiftreg.toggle_even() # Toggle the even numbered pins shiftreg.chase() # Toggle all the pins sequentially in one direction shiftreg.scan() # Toggle all the pins sequentially back and forth shiftreg.demo() # Runs all of the above
It's simple to add your own method to the
ShiftRegister class. You just need to
remember a few things. First, it needs to be within the
ShiftRegister class, i.e.
indented a level further in than the first line of the class, where it says
class ShiftRegister:. Next, it looks just like a normal Python function, in that
it begins with
def method_name():, except that you must always pass
self as the
first argument like so:
def method_name(self, arg1, arg2):. You need to pass
even if you're not passing any other arguments in, as I have in the previous example.
As long as you follow the pattern I showed above to set the pins - toggle the storage register clock off then for each pin, toggle the shift register clock off, the serial pin on or off and the shift register clock on, and finally toggle the storage register clock back on - then the world is your lobster (or oyster, or whatever)!
Taking it further
It's possible to daisy-chain the 8-bit shift register chips together to drive even more LEDs from the same 3 output pins. You'd just connect up the last output pin of one chip to the serial input pin of the second chip and connect up the other two input pins, the storage register clock and the shift register clock, from the two chips, so that they switch on and off at the same time.
I won't show you how to do that here, and you'd have to modify the code to do it, but I encourage you to give it a try!
Search above to find more great tutorials and guides.