Help Understanding Cascading Shift Registers

I'm new to using shift registers so i've been doing some bread boarding to help find out how they work. I've got four 74HC595 shift registers cascaded together with LEDs on all the outputs.

I'm struggling with how the code works, I understand the data has to be separated (some how??) to spread it across the 4 shift registers.

I'm currently using some ultra simple code to count upwards in binary, the only issue is that the 4 shift registers all trigger simultaneously - so each register is displaying 8bits of binary at the same time, as apposed to them all working together to give me 32bits

here's the code so far, cheers -

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

int numberToDisplay = 0;

  void setup() 
  {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  }

    void loop() 
    {
        digitalWrite(latchPin, LOW);
        // shift out the bits:
        shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  
        //take the latch pin high so the LEDs will light up:
        digitalWrite(latchPin, HIGH);
        // pause before next value:
        delay(100);
        numberToDisplay = (numberToDisplay + 1);
    }

How are things wired up? Have you seen: http://www.arduino.cc/en/Tutorial/ShiftOut ? Which has a sample schematic and example code.

Yeah - I've used the tutorial page to get the wiring plan, they're wired up exactly the same, except for the extra shift registers. I've used pin 9 to cascade them together as shown in the shiftOut tutorial.

I've also used the code in the tutorial too, but because I'm trying to use 4 shift registers there's a few things I need to add.

I think the issue is to do with breaking the data up into separate bytes so the registers can work together.

Thanks for the reply. :)

I am currently working on a matrix project (only two 595’s though). The code I’m using to refresh the display is below (rows on one 595, columns on the other):

void refreshMatrix() {
  byte mask = B0000000;
  for (int c=0;c<MAX_COLS;c++) {
    mask = B0000000;
    for (int r=0;r<MAX_ROWS;r++) {
      if (ledState[r] & (1 << c)) mask |= 1<<r;
    }
    digitalWrite(latchPin595, 0);
    shiftOut(dataPin595, clockPin595, mask); // Rows  1 = on
    shiftOut(dataPin595, clockPin595, ~(1 << c)); // Columns 0 = on
    digitalWrite(latchPin595, 1);
  }
}

Note that I am using a single dimension array to store the state of the matrix and bitmath to muck about with the state.

In your case, two additional shiftOut’s should do the trick.

The best way to think about cascading shift registers would be to think about a clear tube with lines marked at 8 inch(bit) intervals. When you’re sending data to the registers, you are essentially putting an 8 inch cylinder of wood into the tube. With each successive cylinder, you push the first block one interval over.

So when you want to control the 4th S.R, you would send that data first, then the 3rd, 2nd, 1st, etc…

Now I am just learning myself so I may have something wrong, but it is working for me :slight_smile:

Ok - thanks for the code, i’m trying to do a few more shiftOuts but I’m still having issues, it’s probably a really basic question but what does the following symbols in your code mean? -

<<

Think I’ve go it now, I’m still not sure what << or >> means, but the code seems to work -

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

long numberToDisplay = 0;

  void setup() 
  {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  }

        void loop() 
        {
        digitalWrite(latchPin, LOW);
        
        shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay >> 24);
        shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay >> 16);
        shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay >> 8);
        shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);
        
        digitalWrite(latchPin, HIGH);
        delay(1);

        numberToDisplay = (numberToDisplay + 1);
        }

I wouldn’t call it a basic question, more of an intermediate one :slight_smile:

http://www.arduino.cc/playground/Code/BitMath

<< indicates a left shift. When I loop through each byte of the matrix array (one dimensional, one index per row, one bit per column), I use the left shift operator to select which bit I want to look at. For example, the following two code samples (should be) are identical.

int intArray[][] = {
 {128, 64, 32, 16, 8, 4, 2, 1},
 {128, 64, 32, 16, 8, 4, 2, 1}
}
for (int r=0;r<2;r++){
  for (int c=0;c<8;r++) {
    Serial.println(intArray[r][c],DEC);
  }
}
byte byteArray[] = {
 B11001110,
 B10011011
}
for (int r=0;r<2;r++){
  for (int c=0;c<8;r++) {
    Serial.println(byteArray[r] & 1 <<c, DEC);
  }
}

Essentially, it is used to store multiple values in a single byte (perhaps storing the state of a bank of dip switches in a single byte, as opposed to seperate ints or bytes for each switch).

I’m not exactly the best at explaining things, so hopefully you can understand from that and reading the bitmath page.

Thanks for the help, i've got a much better grasp of this bit shifting malarkey now 8-)