Four Shift Registers with 32 LEDs

I cascaded four SN74HC595 shift registers to control 32 LEDs on 4 registers using 3 wires. I am adding a I2C 20x4 LCD screen to display the register and led values. I might add a standard 16x2 LCD screen to show up it is done.

COMPONENTS AND SUPPLIES

LED

32

220 Ohm Resistor

1

Small Breadboard

1

NECESSARY TOOLS AND MACHINES

spools of wire

wire cutters

SN74HC595 shift registers

ABOUT THIS PROJECT

First video file of project

Cool factor of this project:   3 wires:  Data, Clock, Latch to send the signals to 32 LEDs

I hate having a lot of wires going to the Arduino.   Makes the project look sloppy.

I cascaded four SN74HC595 shift registers to control 32 LEDs on 4 registers using 3 wires.

The SN74HC595 shift register is SIPO, serial in, parallel out.   What does SIPO mean:  3 wires in to the shift register controls n x 8 parallel outputs.   n is the number of shift registers cascaded

int latchPin = 8; // SR Latch Pin 12 Digital pin
int dataPin = 11; // SR Pin 14 PWM pin
int clockPin = 12; // SR Clock Pin 11 Digital pin

On the SN74HC595 you have 16 pins.   The notch and dot shows you pin 1.

8 outputs are:
QA to QH
Pin 14: Data, I place it on a pwm pin 11
Pin 12: Latch, I place it on digital pin 8
Pin 11: Clock, I place it on digital pin 12

I am adding a I2C 20×4 LCD screen to display the register and led values. I might add a standard 16×2 LCD screen to show up it is done.    The project will explain how to cascade the shift registers.

I am using four 220 ohm resistor arrays I purchased from Digikey.   I am going to be ordering 330 ohm resistor arrays soon.   Instead of a resistor on each LED, the resistor arrays are an IC chip with 8 resistors inside.

How many can you cascade, as many as you want.   You can get 64-bit shift registers for 8×8 matrix of LEDs.   The issue is all the wires on the bread board can get complicated.

LEDS:  I setup 4 Reds then 4 Blues per register.   First LED is LED 0 and last one is LED 31.

I set the code to scale.  As you see I am at four.
int numOfRegisters = 4;
byte* registerState;

This section of code sets the registers to start at 0 and go up to 3.   I use MSBFIRST because of the order I am lighting the LEDs: QA to QH

void regWrite(int pin, bool state){
//Determines register
int reg = ( pin / 8 );
//Determines pin for actual register
// int actualPin = pin – (8 * reg);
int actualPin = ( pin % 8 );

Serial.print(“reg: “);
Serial.print(reg);
Serial.print(“n”);

Serial.print(“pin: “);
Serial.print(pin);
Serial.print(“n”);

//Begin session
digitalWrite(latchPin, LOW);

for (int i = numOfRegisters – 1; i >=0; i–) {
//Get actual states for register
byte* states = &registerState[i];

//Update state
if (i == reg){
bitWrite(*states, actualPin, state);
}

//Write
shiftOut(dataPin, clockPin, MSBFIRST, *states);
delay(100);
}

//End session
digitalWrite(latchPin, HIGH);
}

Register 0: pins 0 to 7
Register 1: pins 8 to 15
Register 2: pins 16 to 23
Register 3: pins 24 to 31

Pins on each register are 0 to 7.

Test pin 25:

int reg = (25 / 8 );
//Determines pin for actual register
// int actualPin = 25 – (8 * reg);
int actualPin = ( 25 % 8 );

int reg = (25 / 8 );  = int (3.125) or reg = 3
int actualPin = ( 25 % 8 );  =  actualPin 3 Remainder 1 or Actual pin is pin 1

So pin 25 translates to Register 3 Pin 1

CUSTOM PARTS AND ENCLOSURES

COMMENTS

Leave a Reply

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

#include <LiquidCrystal_I2C.h> // Library for LCD int latchPin = 8; // SR Latch Pin 12 Digital pin int dataPin = 11; // SR Pin 14 PWM pin int clockPin = 12; // SR Clock Pin 11 Digital pin LiquidCrystal_I2C lcd20x4_24 = LiquidCrystal_I2C(0x24, 20, 4); // Change to (0x27,20,4) for 20×4 LCD. unsigned int Var = 0; int numOfRegisters = 4; byte* registerState; void regWrite(int pin, bool state){ //Determines register int reg = ( pin / 8 ); //Determines pin for actual register // int actualPin = pin – (8 * reg); int actualPin = ( pin % 8 ); Serial.print(“reg: “); Serial.print(reg); Serial.print(“n”); Serial.print(“pin: “); Serial.print(pin); Serial.print(“n”); //Begin session digitalWrite(latchPin, LOW); for (int i = numOfRegisters – 1; i >=0; i–) { //Get actual states for register byte* states = &registerState[i]; //Update state if (i == reg){ bitWrite(*states, actualPin, state); } //Write shiftOut(dataPin, clockPin, MSBFIRST, *states); delay(100); } //End session digitalWrite(latchPin, HIGH); } void HeartOfStainlessSteel_20x4_24() { lcd20x4_24.init(); lcd20x4_24.backlight(); lcd20x4_24.setCursor(0, 0); // 4th column 1st row lcd20x4_24.print(” “); lcd20x4_24.setCursor(0, 1); // 9th column 2nd row lcd20x4_24.print(” “); lcd20x4_24.setCursor(0, 2); // 7th column 3rd row lcd20x4_24.print(” “); lcd20x4_24.setCursor(3, 3); // 3rd column 4th row lcd20x4_24.print(“LCD 20×4: 0x24”); } void setup() { Serial.begin(9600); HeartOfStainlessSteel_20x4_24(); while (!Serial); // wait for serial monitor Serial.println(“nI2C Scanner”); // I2C Scanner Code //Initialize array registerState = new byte[numOfRegisters]; for (size_t i = 0; i < numOfRegisters; i++) { registerState[i] = 0; } //set pins to output so you can control the shift register pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); for (int k = 0; k < 32; k++){ regWrite(k, HIGH); lcd20x4_24.setCursor(0, 2); // 1st column 3rd row lcd20x4_24.print("LED: "); lcd20x4_24.setCursor(5, 2); // 6th column 3rd row lcd20x4_24.print(k); Serial.print("k: "); Serial.print(k); Serial.print("n"); delay(500); regWrite(k, LOW); } } void loop() { // I2C Scanner Code byte error, address; int nDevices; Serial.println("Scanning…"); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknown error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices foundn"); else Serial.println("donen"); delay(5000); // wait 5 seconds for next scan // I2C Scanner Code }
PROJECT AUTHOR
Leave a comment
TEAM MEMBERS
SCSIraidGURU

Fred

ADDITIONAL CONTRIBUTORS
Fred

He helped speed up debugging the code.

TABLE OF CONTENTS
Leave a comment
Share on whatsapp
Share on facebook
Share on twitter
Share on linkedin
Share on reddit
Share on pinterest
Share on email

SIMILAR PROJECTS YOU MIGHT LIKE

A simple light meter. It’s not calibrated to any meaningful scale, but the digital readout shows a higher number the brighter is the light falling on the photoresistor.
I got the Inventr Mega kit and started work on a lock for a door by using a 4×4 keypad, Uno, 20×4 LCD, and some resistors.