I find the best way to manage multiple "things" in code is to first represent them in code.
To do this with 2 (or more) RGB LEDs I would first create a structure representing the state of an LED -
struct colour {
byte r;
byte g;
byte b;
};
struct led {
struct colour col;
struct colour dest;
byte delay;
};
What I have here is a led with 2 "colours", col being the current colour - this is what is written out by the routine that sets the colours, using whatever method you have for controlling your LEDs - in my case this was for controlling some bliptronics LEDs.
The dest colour is the intended colour.
Then all you need in your main loop is to loop around your LEDs, increment or decrement each Red, Green and Blue colour value in the direction of the destination colour value. When nothing needed incrementing/decrement you have reached that colour and can do whatever is necessary to select a new destination colour.
Once all LEDs have been altered, loop again and output the colours.
Some snippets of my code - the show_cycle routine picks the next colour from colour_sequence. I also have a delay status to enable differing change speeds per LED -
struct colour sequence[] = {
{ 0x1F, 0, 0 },
{ 0x1F, 0, 0x1F },
{ 0, 0, 0x1F },
{ 0, 0x1F, 0x1F },
{ 0, 0x1F, 0 },
{ 0x1F, 0x1F, 0 },
{ 0x1F, 0x1F, 0x1F },
};
struct led leds[NUM_LEDS];
int seq_pos=0;
void setup() {
byte Counter;
// setup/run the fast spi library
FastSPI_LED.setLeds(NUM_LEDS);
FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803);
//FastSPI_LED.setChipset(CFastSPI_LED::SPI_HL1606);
//FastSPI_LED.setChipset(CFastSPI_LED::SPI_595);
// this is the default, but included here to show where/how to change it
FastSPI_LED.setCPUPercentage(50);
FastSPI_LED.init();
FastSPI_LED.start();
for (int n=0;n<NUM_LEDS; n++) {
leds[n].col.r=0;
leds[n].col.g=0;
leds[n].col.b=0;
leds[n].dest.r=0;
leds[n].dest.g=0;
leds[n].dest.b=0;
leds[n].delay=0;
}
show();
}
void show()
{
unsigned char *pData = FastSPI_LED.getRGBData();
for(int i=0; i < NUM_LEDS; i++) {
*pData++ = (leds[i].col.g << 3);
*pData++ = (leds[i].col.b << 3);
*pData++ = (leds[i].col.r << 3);
}
FastSPI_LED.show();
}
int move_led(struct led * l) {
int flg=0;
if (l->delay==0) {
if (l->dest.r > l->col.r) {
l->col.r++;
flg++;
}
else if (l->dest.r < l->col.r) {
l->col.r--;
flg++;
}
if (l->dest.g > l->col.g) {
l->col.g++;
flg++;
}
else if (l->dest.g < l->col.g) {
l->col.g--;
flg++;
}
if (l->dest.b > l->col.b) {
l->col.b++;
flg++;
}
else if (l->dest.b < l->col.b) {
l->col.b--;
flg++;
}
}
else {
l->delay--;
flg++;
}
return(flg);
}
unsigned int phase;
void loop() {
int n;
int flg=0;
for (n=0;n<NUM_LEDS;n++) flg += move_led(&leds[n]);
if (flg==0) {
show_cycle();
}
show();
delay(DELAY);
}
void show_cycle() {
int n,r;
seq_pos++;
r = random(0,4);
if (seq_pos>= sizeof(sequence)/sizeof(colour)-1 ) seq_pos=0;
for (n=0;n<NUM_LEDS; n++) {
leds[n].dest.r=sequence[seq_pos].r;
leds[n].dest.g=sequence[seq_pos].g;
leds[n].dest.b=sequence[seq_pos].b;
switch(r) {
case 0:
if (n > (NUM_LEDS/2)) leds[n].delay = (n - (NUM_LEDS/2)) * 10;
else leds[n].delay=abs(n-5) * 10;
break;
case 1:
leds[n].delay=n*10;
break;
case 2:
leds[n].delay=(NUM_LEDS-1-n) * 10;
break;
case 3:
break;
case 4:
if (n > (NUM_LEDS/2)) leds[n].delay = n * 10;
else leds[n].delay= (NUM_LEDS-1-n) * 10;
break;
}
}
}