Multiple Shift Register 74HC595 Daisy Chained Together

Subject: Multiple Shift Register 74HC595 Daisy Chained Together.

Hi Guys,
I have been around programing for many years but I’m new to the Arduino and Electronics in general.
Following some examples and playing with bread boards I have come up with my first project.

It is an 8 (rows) x 32 (columns) LED Display for my Arduino.
My first goal is to be able to turn on any individual LED given its row and column position.

The Setup
For the LED’s I have connected all the anodes together for the columns and all the cathodes together to form the rows. (similar to all those led cubes around)
I have used one Shift register to set the negative on the rows side of the LEDs.
I have used four Shift Registers to set the positive on the column side of the LEDs.

Shift Register Data Sheet http://www.ti.com/lit/ds/symlink/sn74hc595.pdf

The four column shift registers are daisy chained together Pin 9 serial data output connected to pin 14 serial data input
As shown in this example http://arduino.cc/en/tutorial/ShiftOut#.UwBJzqi4ZaQ

The first 8 x 8 matrix (col 1 through 8 and row 1 through 8 ) work exactly as expected so I have the resistors, transistors, Arduino basically hooked up correctly.

The Trouble
My problem is the 2nd , 3rd and 4th bank of 8 x 8 LED’s basically mirror the first bank.
When I try and enable Col 9 Row1 for example, I don’t really understand what the display is doing.

I tried to follow the example of how to pass the second and subsequent shift register a value but I don’t understand it. Code "Sample 2.1 Dual Binary Counters" from the tutorial above.

I also found an interesting post here but don’t know how to apply it to my case. I guess I’m missing a fundamental bit (no pun intended)
http://forum.arduino.cc/index.php?PHPSESSID=tra3haijdf3rpdsrb893a1a6d0&topic=216499.0

Here is my code so far.
Any assistance / suggestions greatly appreciated.

// Coloumn Connections
int colLatchPin = 8;
int colClockPin = 12;
int colDataPin = 11;

// Row Connections
int rowLatchPin = 7;
int rowClockPin = 10;
int rowDataPin = 9;

int rowLed [9]  = {1,2,4,8,16,32,64,128,0};
int colLed [33] = {1,2,4,8,16,32,64,128,257,258,260,264,272,288,320,384,513,514,516,520,528,544,576,640,769,770,772,776,784,800,832,896,0};

 
void setup() 
{
  Serial.begin(57600);
  
  pinMode(colLatchPin, OUTPUT);
  pinMode(colDataPin, OUTPUT);  
  pinMode(colClockPin, OUTPUT);
  
  pinMode(rowLatchPin, OUTPUT);
  pinMode(rowDataPin, OUTPUT);  
  pinMode(rowClockPin, OUTPUT);
  
  // Turn everything off to start with
  updateShiftRegister(rowLatchPin, rowClockPin, rowDataPin, rowLed[8]);
  updateShiftRegister(colLatchPin, colClockPin, colDataPin, colLed[32]);
  
  Serial.print("Col\t");
  Serial.print("Row");
  Serial.println();
  
}
 
void loop() 
{

  for (int row = 0; row < 8; row++)
  {
    updateShiftRegister(rowLatchPin, rowClockPin, rowDataPin, rowLed[row]);
        
    for (int col = 0; col < 8; col++)
    {
        updateShiftRegister(colLatchPin, colClockPin, colDataPin, colLed[col]);
        
        Serial.print(col);
        Serial.print("\t");
        Serial.print(row);
        Serial.println();
        
        delay(500);
    }
  }
}
 
void updateShiftRegister(int latchPin, int clockPin, int dataPin, int led)
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, led);
   digitalWrite(latchPin, HIGH);
}
void updateShiftRegister(int latchPin, int clockPin, int dataPin, int led)
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, led);
   digitalWrite(latchPin, HIGH);
}

This only writes out 8 bits at a time. I think you are assuming that it is writing more than that. When you have 4 595 daisy chained together, you are pushing the bit pattern over by one bank at a time rather than replacing all 4 together.

Think of those 4 '595's as one 32 bit shift register, because that's what they are,
and shift 32 bits.
Make sure you have enough decoupling on the chips too, its important when
switching lots of LEDs.

Hi Marco,
Thanks for the reply. What you say makes sense but I don't understand how to do it correctly.
So I have to send 4 bytes at once with the bits set for the LEDs I want turned on.

Binary
00000011 00000000 00000000 11111111
Decimal
3 0 0 255

I'd expect this to turn on the first 2 LED and the last 8 (not sure if I need to change the MSBFirst to LSBFirst)

The other example I found looks like this. He is only controlling two Shift Registers
http://forum.arduino.cc/index.php?PHPSESSID=tra3haijdf3rpdsrb893a1a6d0&topic=216499.0
Unfortunately I don't understand what it is doing.
I'm sure it comes down to these two lines. Any hints how I can adapt this to send 4 bytes at once?

int ByteHigh = (currentValue & 65280)/256;
int ByteLow = currentValue & 255;

Regards
David

Extract

void loop() {
  for (int currentValue = 0; currentValue < 65536; currentValue++) {
    //Mask counter with 1111111100000000 to select high order byte and divide by 256 to scale to a 8 bit output
    int ByteHigh = (currentValue & 65280)/256;
    //Mask counter with 0000000011111111 to select low order byte
    int ByteLow = currentValue & 255;

    // Disable the latch while we clock in data
    digitalWrite(latchPin, LOW);
    
    // Send the value as a binary sequence to the module
    shiftOut(dataPin, clockPin, MSBFIRST, ByteHigh);
    shiftOut(dataPin, clockPin, MSBFIRST, ByteLow);
   

    // Enable the latch again to set the output states
    digitalWrite(latchPin, HIGH);

    delay(200);
void updateShiftRegister(int latchPin, int clockPin, int dataPin, int count,  int *led)
{
   digitalWrite(latchPin, LOW);
   for (uint8_t i=0; i<count; i++)
       shiftOut(dataPin, clockPin, MSBFIRST, led[i]);
   digitalWrite(latchPin, HIGH);
}

This writes out 'count' registers. Starting at the one pointed to by led. You supply the count and then the address of the start of the data (syntax like updateShiftRegister(colLatchPin, colClockPin, colDataPin, 4, &colLed[32]) )

Did you ever figure out how to get 16 bits over to the two 595s? I'm struggling with the code. And, I want to set the order myself as i'm going to pulse relays with them.

const int SER   =12;
const int LATCH =9;
const int CLK   =11;

void setup() {
  // Set pinmodes as outputs
  
  pinMode (SER, OUTPUT);
  pinMode (LATCH, OUTPUT);
  pinMode (CLK, OUTPUT);
  
}

void loop() 
{


digitalWrite(LATCH, LOW);
    shiftOut(SER, CLK, MSBFIRST, B10101010);
    shiftOut(SER, CLK, MSBFIRST, B10101010);  
    digitalWrite(LATCH, HIGH);
delay(2000);



digitalWrite(LATCH, LOW);
    shiftOut(SER, CLK, MSBFIRST, B00000000);
    shiftOut(SER, CLK, MSBFIRST, B10101010);     
    digitalWrite(LATCH, HIGH);
delay(500);


digitalWrite(LATCH, LOW);
    shiftOut(SER, CLK, MSBFIRST, B00010000);  
    shiftOut(SER, CLK, MSBFIRST, B00010000); 
    digitalWrite(LATCH, HIGH);
delay(500);


  }
    /code]