Go Down

Topic: Looking for multiple RGB LED fading code, help please! (Read 1 time) previous topic - next topic

shtonkalot

I've been having no end of trouble trying to get a couple of RGB LEDs to fade between colours independently.
I've spent dozens of hours trying to find example code and editing the code I have found all to come up with nothing quite like what I'm after.

Maybe I've just assumed that this is easy to do and am wrong about it? I got the arduino believing I was getting a well supported product with heaps of users helping each other do stuff. So far the only help I've found is example code written ages ago that I can't figure out how to modify.
I'm getting so frustrated I feel like snapping the damn thing.

I just want to be able to cycle RGB colours independently on each light (starting with 2 RGB LEDs).

anyway, I've made another thread that outlines most of where I'm up to in my current frustration cycle plus shows the closest to correct code I have running here: http://arduino.cc/forum/index.php/topic,55390.0.html
I'm making this thread as a last ditch effort for some help.

If anyone can give me any suggestions for other places I may get help or has any input they believe will help me learn to do what I'm after I'd greatly appreciate it. Like super appreciate it.
I'd even appreciate a reply telling me I've got no hope, that would be more helpful than nothing.

defsdoor

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 -

Code: [Select]
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 -
Code: [Select]

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;
    }
  }
}


shtonkalot

Thank you so much defsdoor. I'm very grateful for the code examples to play with.
I won't lie, it looks fairly confusing to me but I'm sure I'll work it out. Thanks for taking the time to explain it.

It appears to be what I'm after, thanks again.

Go Up