Programming Logic (Shift Registers)

void ShiftByteOut(byte chip, byte b)
{  
   byte bp2 = B00000000;   
   digitalWrite(latchPin, LOW);  
   for(byte n2=0; n2<MaxShiftRegisters+1; n2++)
   {
      CheckBuffer();   
      if (chip==n2)
         shiftOut(dataPin, clockPin, MSBFIRST, b);
       else
         shiftOut(dataPin, clockPin, MSBFIRST, bp2);
   }     
   digitalWrite(latchPin, HIGH);     
}

The Theory (this code works because I only have 2 shift registers) - if i had 3 or more… I don’t think this code works. Basically, in the loop, it works it’s way through all the chips (8 bits in, 8 bits in, 8 bits out to the next chip Daisy Chained .

I can’t the life of me work out how to say do this.

5 shift registers.

I want to write 1 byte to the 3rd shift register

//void ShiftByteOut(byte chip, byte b)
ShiftByteOut(3,B10101010); //3rd shift register gets this value.
//all the other shift registers now contain 0 for each bit.

Filling the registers is easy, i could simply send 1 byte, 5 times, to shift the data out of the 1st shift register to the 5th shift register. it’s the logic and i think i’m way out on my code lol - what’s the easiest way to access a specific register? - I don’t mind all the other shift registers being empty (0 for each bit for every pin) as long as i can access eg the 3rd Shift Register, and modify it’s contents.

Cheers :slight_smile:

With daisy-chained shift registers you have to send data to all of them every time you update. Typically you use a variable (an array) to hold the current state, and shift that out after a change.

Another way to do it would be to loop round the output from the last register back to another (INPUT) pin - then you can avoid having to copy the state of the registers in variables, but that's somewhat more complex and more fragile.

If the registers are latched (such as 74HC595) you only clock the latch pin after updating all the registers (to avoid glitches on the unchanged outputs).

ahhh, ok which I am in a round about doing anyway (yes it’s a 74hc) …

Since there’s no array of “bits”… you see my for loop, well it does more or less just that.

 for(byte n2=0; n2<MaxShiftRegisters+1; n2++)
   {
      if (chip==n2)
         shiftOut(dataPin, clockPin, MSBFIRST, b);    //once we get to register 3, place the contents of b into 
       else 
         shiftOut(dataPin, clockPin, MSBFIRST, bp2);  //bp2 = B00000000
   }

if (chip==n2)
// this is not going to work is it, because let’s suppose

In > shiftreg1
In > shiftreg1 > shiftreg2
In > shiftreg1 > shiftreg2 > shiftreg3

so now, we put the value we want in, it has to go to the first shiftregister1 - then i have to …

ok i’ll have to rethink the code or find an example :slight_smile:

Create a buffer for each of your registers (use a string for example). Update the buffer first and send them out sequentially.

ohhh a string, never occurred to me lol, thank you :)

No don’t use strings, just use as many bytes as you have shift registers in a byte array.
Set the bits you want and when you want to update it send out ALL the bytes.

This is very simple, as Mike says have an array of bytes and shift them all out. Something like this

#define N_REGS 5

byte srVals[N_REGS];

// some code that sets various values for each shift reg and puts the values in the appropriate byte in srVals

digitalWrite(latchPin, LOW);  
for (int i = 0; i < N_REGS; i++) {
    shiftOut(dataPin, clockPin, MSBFIRST, srVals[i]);
}
digitalWrite(latchPin, HIGH);

Rob

cjdelphi, there is a small library for easily daisy chain 74hc595: http://bildr.org/2011/08/74hc595-breakout-arduino

May be useful :)

Guix, absolutely perfect! it was starting to do my head in cheers :)