Overview
Although you could wire up eight LEDs each with a resistor to an Arduino pin (like we did for an RGB LED in Lesson 2) you would rapidly start to run out of pins on your Arduino. If you don't have a lot of stuff connected to your 'duino it's OK to do so - but often times we want buttons, sensors, servos, etc and before you know it you've got no pins left. So, instead of doing that, you are going to use a chip called the 74HC595 Serial to Parallel Converter. This chip has eight outputs (perfect) and three inputs that you use to feed data into it a bit at a time.
This chip makes it a little slower to drive the LEDs (you can only change the LEDs about 500,000 times a second instead of 8,000,000 a second) but it's still really really fast, way faster than humans can detect, so it's worth it!
Page last edited October 03, 2012
Text editor powered by tinymce.
Parts
To build the project described in this lesson, you will need the following parts.
Page last edited October 03, 2012
Text editor powered by tinymce.
Breadboard Layout
- Digital 4 from the arduino goes to pin #14 of the shift register
- Digital 5 from the arduino goes to pin #12 of the shift register
- Digital 6 from the arduino goes to pin #11 of the shift register
After the chip, put the resistors in place. You need to be careful that none of the leads of the resistors are touching each other. You should check this again, before you connect the power to your Arduino. If you find it difficult to arrange the resistors without their leads touching, then it helps to shorten the leads so that they are lying closer to the surface of the breadboard.Next, place the LEDs on the breadboard.
The longer positive LED leads must all be towards the chip, whichever side of the breadboard they are on.
It now just remains to attach the jumper leads as shown above. Do not forget the one that goes from pin 8 of the IC to the GND column of the breadboard.
Load up the sketch listed a bit later and try it out. Each LED should light in turn until all the LEDs are on, and then they all go off and the cycle repeats.
Page last edited October 03, 2012
Text editor powered by tinymce.
The 74HC595 Shift Register
The chip is of a type called a shift register.
The shift register holds what can be thought of as eight memory locations, each of which can be a 1 or a 0.
To set each of these values on or off, we feed in the data using the 'Data' and 'Clock' pins of the chip.
The clock pin needs to receive eight pulses. At the time of each pulse, if the data pin is high, then a 1 gets pushed into the shift register. Otherwise, it is a 0. When all eight pulses have been received, then enabling the 'Latch' pin copies those eight values to the latch register. This is necessary, otherwise the wrong LEDs would flicker as the data was being loaded into the shift register.
The chip also has an OE (output enable) pin, this is used to enable or disable the outputs all at once. You could attach this to a PWM capable Arduino pin and use 'analogWrite' to control the brightness of the LEDs. This pin is active low, so we tie it to GND.
Page last edited October 03, 2012
Text editor powered by tinymce.
Arduino Code
Here is the full sketch, the discussion of how it works follows on from it.
/*
Adafruit Arduino - Lesson 4. 8 LEDs and a Shift Register
*/
int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
byte leds = 0;
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
leds = 0;
updateShiftRegister();
delay(500);
for (int i = 0; i < 8; i++)
{
bitSet(leds, i);
updateShiftRegister();
delay(500);
}
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
int latchPin = 5; int clockPin = 6; int dataPin = 4;
byte leds = 0;
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
The loop function pauses for half a second and then begins to count from 0 to 7 using the 'for' loop and the variable 'i'. Each time, it uses the Arduino function 'bitSet' to set the bit that controls that LED in the variable 'leds'. It then also calls 'updateShiftRegister' so that the leds update to reflect what is in the variable 'leds'.
There is then a half second delay before 'i' is incremented and the next LED is lit.
void loop()
{
leds = 0;
updateShiftRegister();
delay(500);
for (int i = 0; i < 8; i++)
{
bitSet(leds, i);
updateShiftRegister();
delay(500);
}
}
The third parameter specifies which end of the data you want to start at. We are going to start with the right most bit, which is referred to as the 'Least Significant Bit' (LSB).
The last parameter is the actual data to be shifted into the shift register, which in this case is 'leds'.
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
Page last edited October 03, 2012
Text editor powered by tinymce.
Brightness Control
We can use this pin along with the 'analogWrite' function, that we used back in Lesson 3, to control the brightness of the LEDs using PWM (also see Lesson 3).
To do this, all you need to do, is to change the connection to pin 13 of the 74HC595 so that instead of connecting it to Ground, you connect it to pin 3 of the Arduino.
The sketch below, will once all the LEDs have been lit gradually fade them back to off.
/*
Adafruit Arduino - Lesson 4. 8 LEDs and a Shift Register - Brightness
*/
int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
int outputEnablePin = 3;
byte leds = 0;
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(outputEnablePin, OUTPUT);
}
void loop()
{
setBrightness(255);
leds = 0;
updateShiftRegister();
delay(500);
for (int i = 0; i < 8; i++)
{
bitSet(leds, i);
updateShiftRegister();
delay(500);
}
for (byte b = 255; b > 0; b--)
{
setBrightness(b);
delay(50);
}
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
void setBrightness(byte brightness) // 0 to 255
{
analogWrite(outputEnablePin, 255-brightness);
}
Page last edited October 03, 2012
Text editor powered by tinymce.
Other Things to Do
- Make a 'Larson Scanner' scanning lights as found on the front of KITT in the TV series Knight Rider and also found on Cylons in the series Battle Start Galactica.
- Make an electronic dice. Arrange 6 of the LEDs as two columns of three LEDs with one LED in the middle. Hint – take at a look at the Arduino function called 'random'.
You are going to use much of the same breadboard setup in lesson 5 with a few minor changes, so do not dismantle it all just yet.
Simon Monk is author of a number of books relating to Open Source Hardware. The following books written by Simon are available from Adafruit: Programming Arduino, 30 Arduino Projects for the Evil Genius and Programming the Raspberry Pi.
Page last edited October 03, 2012
Text editor powered by tinymce.





