Friday, January 13, 2012

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

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

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 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.


Implementation


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:



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 @ MakeUseOf.com |
* ---------------------------------------------------------
*/


//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);
delay(100);
}
}

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
delay(100);
}

}


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.



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.




1 comment:

[Please do not advertise, or post irrelevant links. Thank you for your cooperation.]