How a Shift Register works

So, as promised, here is my take on shift registers. I will explain how they work using the M74HC595 8-bit shift register - because that‘s the type I usually use. They are available for a few cents each at many places; here in Germany, I tend to buy them from Conrad, but you can get the from many other sources like Sparkfun or Banggood.

The basics

A shift register is an integrated circuit that takes serial input - one bit after another - and converts that to parallel output (8 bits at a time.) Since you can daisy-chain them, you can get even wider parallel output, such as 16, 24 or even 32 bits.

The benefit from using a shift register for all kinds of input and output circuit is that if you have a limited number of output lines from your Arduino or other microcontroller, you can access a virtually unlimited number of input and output channels while using just 3 data lines from your Arduino.

The way this works is a bit similar to how input on an old-fashioned pocket calculator works: You enter the first digit, and it gets placed at the very right of your display - it is the „least-significant digit“. When you press another digit key, the previously entered digit gets shifted by one place to the left, and the new digit sits to the right of it. You can do this as many times as the number of digits the calculator supports. The first digit you entered will be the most-significant digit, and the last digit is the least-significant digit.

The hardware

This is an example circuit in which a 74HC595 drives 8 LEDs which will show the binary byte value of the output. The three input lines (JP1) are connected to three digital output pins on your Arduino. Note the capacitor on the SH_CP (clock) pin; this will buffer out any potential flicker on the clock pin which could otherwise cause unwanted shifts (duplicated bits).

Shift register demo circuit diagram

Feeding serial data into the shift register

The shift register works almost in the same way as the calculator described above. You enter the first (binary) digit - also known as a bit - by setting the Data pin (DS) to either low (=0) or high (=1). The you raise the Clock pin (#11, SCK, sometimes called SH_CP) for a brief time; this tells the shift register to read the current state of the data pin and store that value as the least-significant bit (LSB.) internally. Then you lower the Clock pin before setting the level (low or high) for the next bit on the Data pin and raise the Clock pin briefly again. This accepts the second bit value, which will now be the LSB, while shifting the previously entered bit one place to the left.

Latching - Transferring to output

Once you have entered all 8 bits this way, you tell the shift register that you want to have the stored value transferred to the output pins (Q0 thru Q7); you do this by briefly raising the Storage Register Clock (or „latch“) pin (labelled RCK or ST_CP). Now the 8 output lines will have states (low or high) representing the 8 bits of input data in parallel. If you have, for example, 8 LEDs connected to these pins (with appropriate resistors protecting them, and the register, from overcurrent), you will see a 8-bit binary representation of your 8 serial-input bits.

How to drive this with an Arduino

Managing the state of the three input lines (Data, Clock and Latch) directly from Arduino code wouldn‘t be too difficult; you would just need some binary arithmetics to figure out the bit values, and a loop. But fortunately, it is even easier. Arduino has a shiftOut() command, that lets you transfer a while 8-bit number with a single command to that shift register. The shiftOut command takes four arguments:

  • The pin number (on the Arduino) to which the Data pin has been connected;
  • The pin number to which the Clock pin has been connected;
  • A flag in which order the bits should be transmitted (least-significant or most-significant bit first);
  • and the actual byte value to shift out.

For the Data and Clock pins, any digital-out pin on the Arduino will do; same for the Latch pin.

The following code will cycle from 0 to 255 (b00000000 thru b11111111) with just a few lines of code.

#define PIN_DATA 11
#define PIN_CLOCK 12
#define PIN_LATCH 8

byte byteValue = 0;

void setup() {    // put your setup code here, to run once:    pinMode(PIN_LATCH, OUTPUT);    pinMode(PIN_CLOCK, OUTPUT);    pinMode(PIN_DATA, OUTPUT); }

void loop() {    shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, byteValue);

   // set the latch pin to HIGH for a short period to trigger the output    digitalWrite(PIN_LATCH, HIGH);    delay(10);    digitalWrite(PIN_LATCH, LOW);

   delay(300);

   byteValue++; }

The setup in action

Below is a short video showing the shift register in action.

Coming up next

In the next blog post, I will explain how you can daisy-chain two or more shift registers, and how to use them to for input too. Stay tuned!

Comments

1 comments

Got questions?

If you have any questions, please let me know. Just use this comment form to post your questions.

You can submit a comment or question related to this blog post. Your post may be subject to moderation and therefor not appear immediately. Please be patient.