Hmm. The pattern doesn't look right to me, but perhaps one of us copied it wrong.
How about this (you'll need to change the output function to output the low 24 bits of "leds" to the three 595s):
unsigned long leds = ~(0x040201); /* One red, one green, and one blue LED on. */
void loop() {
/* Rotate 24 bits */
leds += leds; /* Left shift one bit */
if (leds & 0x1000000) {
/* rotate 24th bit back into bit 0 */
leds |= 1;
}
}
The compiler IS smart enough to optimized the single bit tests of the long to tests within a single byte (yeah!), so the code isn't too bad. it's not quite as smart as it could be about moving the long too and from memory (it does much better if leds is a local variable (is there a way in gcc to get global variables to be stored in registers?)):
> arduino-0008/tools/avr/bin/avr-objdump -S RGBfollow.elf
:
void loop ()
{
/* Rotate 24 bits */
leds += leds; /* Left shift one bit */
a4: 80 91 00 01 lds r24, 0x0100
a8: 90 91 01 01 lds r25, 0x0101
ac: a0 91 02 01 lds r26, 0x0102
b0: b0 91 03 01 lds r27, 0x0103
b4: 88 0f add r24, r24
b6: 99 1f adc r25, r25
b8: aa 1f adc r26, r26
ba: bb 1f adc r27, r27
bc: 80 93 00 01 sts 0x0100, r24
c0: 90 93 01 01 sts 0x0101, r25
c4: a0 93 02 01 sts 0x0102, r26
c8: b0 93 03 01 sts 0x0103, r27
if (leds & 0x1000000) {
cc: b0 ff sbrs r27, 0
ce: 09 c0 rjmp .+18 ; 0xe2 <loop+0x3e>
/* rotate 24th bit back into bit 0 */
leds |= 1;
d0: 81 60 ori r24, 0x01 ; 1
d2: 80 93 00 01 sts 0x0100, r24
d6: 90 93 01 01 sts 0x0101, r25
da: a0 93 02 01 sts 0x0102, r26
de: b0 93 03 01 sts 0x0103, r27
e2: 08 95 ret