arduino + shift register = led chasers

Hi guys,
I'm doing a LEDs chaser with around 24 LEDs total. Since the 74HC595 shift register only control 8 LEDs. So i needed to expand the LEDs to another shift registers. The code I have so far for the chaser w/ one shift register is below in binary--

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

byte patterns[30] = {
  B00000001, 100,
  B00000010, 100,
  B00000100, 100,
  B00001000, 100,
  B00010000, 100,
  B00100000, 100,
  B01000000, 100,
  B10000000, 100};
  
  int index = 0;
  int count = sizeof(patterns) / 2;
  
void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  
    digitalWrite(latchPin, LOW);   
    shiftOut(dataPin, clockPin, MSBFIRST, patterns[index * 2]);  
    digitalWrite(latchPin, HIGH);
    
    delay(patterns[(index * 2) + 1]);
    
    index++;
    
    if (index >= count){
    index = 0;
    }
}

how do I make a LEDs chaser with 3 shift registers that control 34 LEDs ??

Here is some code I wrote a while back for that shift register to PWM leds.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1278251011

Also - you will need external power to run that many LEDs.
Power Tips:

  1. You can use a 5 volt DC power adapter (i.e. dlink 3000ma). 3 amps runs 50 LEDs, so you may need a 2amp supply at least.
  2. You can also power the arduino using the same power supply - 5 volts
  3. Connect grounds - always have to have common grounds.

Best of luck

You could make a smoother looking display by not shifting out all 8 (or your expansion to 24) bits every time.

You seem to only be going in 1 direction.

write the data bit high
pulse shift clock once
write the data bit low
toggle the latch pin

for (bits = 1 to 23){
pulse the shift clock once
toggle the latch pin)
}

after this sequence of 24 clock/latch pins, repeat

This will smoothly walk a 1 across the outpins without all the extraneous shiftouts that can make your display seem to flicker in between.

If you had universal shift register, you could go back & forth (shifting left to right & right to left). CD74AC299, 74AC299, that kind of part. ~50 cents at Newark.com

Also, how many shift register can one atmega328 control?

krazyhorze:
Also, how many shift register can one atmega328 control?

Theoretically infinite, although at large values it would take quite long to address them all. What you do is just pass 16/24 bits instead of 8 to the registers before setting the latch, and wire all of their inputs together.

I have 20 of them quite happily running 7 segment displays, and the lot update in about 100mS via a 2400 rf link

Wow, that's pretty nice performance Boffin1.

How do i expand my code above so that its a LEDs chaser with 2 shift register(24 leds)?

Do three shiftouts here

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, patterns[index * 2]);
digitalWrite(latchPin, HIGH);

instead of patterns array, just define 3 bytes and use << and >> to walk a 1 across them

shiftOut(dataPin, clockPin, MSBFIRST, byte1);
shiftOut(dataPin, clockPin, MSBFIRST, byte2);
shiftOut(dataPin, clockPin, MSBFIRST, byte3);

Hardware engineer approach (check the reference section for correct format of bit-shift command)
byte1 = 0x01;
next time thru
byte1 = byte1<<1;
if byte1 == 0x80, the byte2 = 0x01;
etc.
When byte3 = 0x80, then shift the other way to walk the 1 back across.

Others might say make byte1 a 4byte-long variable, then do shift-outs as

shiftOut(dataPin, clockPin, MSBFIRST, byte1);
shiftOut(dataPin, clockPin, MSBFIRST, byte1>>8);
shiftOut(dataPin, clockPin, MSBFIRST, byte1>>16);

Many options exist...

CrossRoads:
Do three shiftouts here

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, patterns[index * 2]);
digitalWrite(latchPin, HIGH);

instead of patterns array, just define 3 bytes and use << and >> to walk a 1 across them

shiftOut(dataPin, clockPin, MSBFIRST, byte1);
shiftOut(dataPin, clockPin, MSBFIRST, byte2);
shiftOut(dataPin, clockPin, MSBFIRST, byte3);

Hardware engineer approach (check the reference section for correct format of bit-shift command)
byte1 = 0x01;
next time thru
byte1 = byte1<<1;
if byte1 == 0x80, the byte2 = 0x01;
etc.
When byte3 = 0x80, then shift the other way to walk the 1 back across.

Others might say make byte1 a 4byte-long variable, then do shift-outs as

shiftOut(dataPin, clockPin, MSBFIRST, byte1);
shiftOut(dataPin, clockPin, MSBFIRST, byte1>>8);
shiftOut(dataPin, clockPin, MSBFIRST, byte1>>16);

Many options exist...

can I use the bitshift << or >> to shift the bit with the code I have right now?

instead of (index * 2) +1 ??

I don't see why not.