Arduino Programming – Playing With Shift Registers (a.k.a Even More LEDs)

James Bruce 13-01-2012

arduino programmingToday I’ll attempt to teach you a little bit about Shift Registers. These are a fairly important part of Arduino programming, basically because they expand the number of outputs you can use, in exchange for only 3 control pins. You can also daisy-chain shift registers together in order to get even more outputs.


This is a significant jump in difficulty from previous tutorials though, and I strongly suggest you have a really good understanding on the previous material (links at the end of this article), as well as understanding the basics of binary What Is Binary? [Technology Explained] Given that binary is so absolutely fundamental to the existence of computers, it seems odd that we’ve never tackled the topic before - so today I’d thought I’d give a brief overview of what binary... Read More which I wrote last time.

What Is A Shift Register?

An output shift register, technically speaking, receives data in serial and outputs it in parallel. In practical terms, this means we can quickly send a bunch of output commands to the chip, tell it to activate, and the outputs will be sent to the relevant pins. Instead of iterating through each pin, we simply send the output required to all the pins at once, as a single byte or more of information.

If it helps you to understand, you can think of a shift register as an ‘array’ of digital outputs, but we can skip the usual digitalWrite commands and simply send a series of bits to turn them on or off.

How Does It Work?

The shift register we will be using – the 74HC595N included in the Oomlout starter kit – needs only 3 control pins. The first is a clock – you needn’t worry too much about this as the Arduino serial libraries control it – but a clock is basically just an on/off electrical pulse that sets the pace for the data signal.

The latch pin is used to tell the shift register when it should turn its outputs on and off according to the bits we just sent it – i.e., latching them into place.


Finally, the data pin is where we sent the actual serial data with the bits to determine the on/off state of the shift register’s outputs.

The whole process can described in 4 steps:

  1. Set the data pin to high or low for the first output pin on the shift register.
  2. Pulse the clock to ‘shift’ the data into the register.
  3. Continue setting the data and pulsing the clock until you have set the required state for all output pins.
  4. Pulse the latch pin to activate the output sequence.


You need the following components for this project:

  • 7HC595N shift register chip
  • 8 LEDS and appropriate resistors, or whatever you want to output to
  • The usual breadboard, connectors, and a basic Arduino

If you have the Oomlout starter kit, you can download the breadboard layout from here.


Here’s the assembly video:

The board layout:

arduino programming


And my assembled version:

Arduino Programming - Playing With Shift Registers (a.k.a Even More LEDs) assembled shift register tutorial

I’ve modified the original code provided by Ooolmout, but if you’d like to try that instead, it can be downloaded in full here. Explanation of the code is included, so copy and paste the whole thing from below or pastebin to read an explanation of the code.

/*     ---------------------------------------------------------
 *     |  Shift Register Tutorial, based on                    | 
 *     |  Arduino Experimentation Kit CIRC-05                  |
 *     |          .: 8 More LEDs :. (74HC595 Shift Register)   |
 *     ---------------------------------------------------------
 *     |  Modified by James @                    |
 *     ---------------------------------------------------------

//Pin Definitions
// 7HC595N has three pins
int data = 2; // where we send the bits to control outputs 
int clock = 3; // keeps the data in sync
int latch = 4; // tells the shift register when to activate the output sequence

void setup()
   // set the three control pins to output
  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);  
  pinMode(latch, OUTPUT);  
  Serial.begin(9600); // so we can send debug messages to serial monitor

void loop(){
    outputBytes(); // our basic output which writes 8-bits to show how a shift register works. 
    //outputIntegers(); // sends an integer value as data instead of bytes, effectively counting in binary. 
void outputIntegers(){
     for (int i=0;i<256;i++){
        digitalWrite(latch, LOW);     
        Serial.println(i);  // Debug, sending output to the serial monitor
        shiftOut(data, clock, MSBFIRST, i); 
        digitalWrite(latch, HIGH);   

void outputBytes(){
    /* Bytes, or 8-bits, are represented by a B followed by 8 0 or 1s. 
        In this instance, consider this to be like an array that we'll use to control
        the 8 LEDs. Here I've started the byte value as 00000001
    byte dataValues = B00000001; // change this to adjust the starting pattern
    /* In the for loop, we begin by pulling the latch low, 
        using the shiftOut Arduino function to talk to the shift register, 
        sending it our byte of dataValues representing the state of the LEDs
        then pull the latch high to lock those into place.
        Finally, we shift the bits one place to the left, meaning the next iteration
        will turn on the next LED in the series.
        To see the exact binary value being sent, check the serial monitor.
    for (int i=0;i<8;i++){
      digitalWrite(latch, LOW);     
      Serial.println(dataValues, BIN);  // Debug, sending output to the serial monitor
      shiftOut(data, clock, MSBFIRST, dataValues); 
      digitalWrite(latch, HIGH);   
      dataValues = dataValues << 1; // Shift the bits one place to the left - change to >> to adjust direction

Bit-Shifting (OutputBytes Function)

In the first loop example – outputBytes() – the code utilises a 8-bit sequence (a byte) which it then shifts left each iteration of the for loop. It’s important to note that if you shift further than is possible, the bit is simply lost.


Bit-shifting is done using << or >> followed by the number of bits you want to shift by.

Check out the following example and make sure you understand what’s happening:

byte val = B00011010
val = val << 3 // B11010000
val = val << 2 // B01000000, we lost those other bits! 
val = val >> 5 // B00000010

Sending Integers Instead (OutputIntegers Function)

If you send a whole number to the shift register instead of a byte, it will simply convert the number into a binary byte sequence. In this function (uncomment in the loop and upload to see the effect), we have a for loop that counts from 0-255 (the highest integer we can represent with one byte), and sends that instead. It basically counts in binary, so the sequence may seem a little random unless your LEDs are laid out in a long line.

For example, if you read the binary explained article, you’ll know that the number 44 will be represented as 00101100, so LEDs 3,5,6 are going to light up at that point in the sequence.

Arduino Programming - Playing With Shift Registers (a.k.a Even More LEDs) binary 44

Daisy Chaining More Than One Shift Register

The remarkable thing about Shift Registers is that if they are given more than 8-bits of information (or however large their registry is), they will shift the other additional bits out again. This means you can connect up a series of them together, push in one long chain of bits, and have it distributed to each register separately, all with no additional coding on your part.

Although we won’t be detailing the process or schematics here, if you have more than one shift register you can try the project from the official Arduino site here.

Other articles in the series:

That’s as far as we’ll go with shift registers today, as I think we’ve covered a lot. As ever, I’d encourage you to play with and adjust the code, and feel free to ask any questions you may have in the comments, or even share a link to your awesome shift register based project.

Affiliate Disclosure: By buying the products we recommend, you help keep the site alive. Read more.

Whatsapp Pinterest

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. William Moore
    August 13, 2017 at 3:03 pm

    I originally thought this was a S4A shift register tutorial, but it turned out to be Arduino C. None the less, I tried it while thinking how it might be possible to translate into a S4A app. While I got it to work for Arduino C, I have decided it's close to impossible to get it going for S4A. With S4A you are limited to dealing with integers and real numbers; they don't have a byte data type, they have no way of dealing with numbers in hex or binary, and they don't have bit-oriented operators like a bit-wise shift-left (or shift-right). So, I can't figure out a way to convert an 8-bit number (a byte) into a serial stream of bits with the MSB being transmitted first. I thought I was on track with an idea where I could test if the number was an odd or an even number using the mod operator (num % 2), then if an odd number, perform a digitalWrite(dataPin, HIGH), and if an even number perform a digitalWrite(dataPin,LOW), then make "num = num / 2", and repeat that 8 times. But this technique resulted in a LSB bit stream which still wasn't working right probably due to some other bug(s). These bugs are likely the result of not having a "byte" datatype. Anyway I got tired of fooling with it and concluded that for most mortals, it was just not possible to do with S4A. It should be doable under BlocklyDuino Enhanced as that block language translates into Arduino C code. But for this lesson I was trying to develop, the focus is on S4A. So, with just a couple weeks till school starts up again I'll focus on other S4A lessons/projects.

  2. Scott
    June 6, 2016 at 1:33 am

    Hey, thanks for this tutorial! I am just starting to play around with hardware, and I'm new to the Arduino language (I'm a VBA guy by day). Am I correct that the code provided is incomplete? I'm getting compile errors for just copying and pasting. It appears to me that the code as written above is calling function "outputBytes()" without defining it. Also getting indications that Arduino 1.6.9 is not ignoring the intended comments in the code. Can you please clarify expectations of the provided code? I'm going to try the oomlout version and see where that gets me in the meantime.

    Thank you. I appreciate it.

    • James Bruce
      June 6, 2016 at 2:49 pm

      This is the full code:

      • Scott
        June 8, 2016 at 12:29 am

        Okay, thank you. I got it to work. I didn't try pastebin at first because I had the impression from the text that I could just copy it from there.

        It works well. Thank you for the tutorial.

  3. nico
    February 13, 2015 at 12:43 am

    hi, thanks for the tutorial.
    my leds keep on and only dimm... any idea?

    • James Bruce
      February 13, 2015 at 8:26 am

      LEDs wired in reverse; shift register wired in reverse; ground wires not connected properly - there could be many reasons. Check your wiring, basically.

  4. Karkala Nayak
    January 14, 2012 at 4:32 pm

    MakeuseOf Just got COMPLEX!!! Damn!! these things are just too complex to understand...

    • Aibek
      January 15, 2012 at 7:29 am

      In order to easily understand this or any future article about the Arduino you need to read some of the first articles from Arduino series which are listed at the bottom of this post.


      • Karkala Nayak
        January 16, 2012 at 7:46 am

        sorry, i was not aware of the older posts. Thank you for pointing out.

        • Aibek
          January 16, 2012 at 8:42 am

          you're welcome)