Cross-fade ws2801

Hi there,

I’m trying to solve defining a cross-fade from a ‘previous’ colour to a ‘new colour’. I’ve seen a previous post in this forum as follows:

for (int i = 0; i <= 10; i++) {
  currentColorR = ((oldColorR * (10 - i)) + (newColorR * i)) / 20;
  currentColorG = ((oldColorG * (10 - i)) + (newColorG * i)) / 20;
  currentColorB = ((oldColorB * (10 - i)) + (newColorB * i)) / 20;

  write your analog values 
  delay some amount
}

…which I believe is the direction I need to go. But following many attempts, my limited code understanding is failing to find a solution to integrating this into my sketch. Any tips would be very gratefully received as I’ve hit a wall. The function I’m struggling with is commented near the bottom. Thanks.

#include "SPI.h"
#include "Adafruit_WS2801.h"

//DEFINE OUTPUT PINS
int dataPin  = 2; //Yellow wire
int clockPin = 3; //Green wire

//SET NUMBER OF PIXELS
Adafruit_WS2801 strip = Adafruit_WS2801(75, dataPin, clockPin, WS2801_GRB);

//LED PIXEL ARRAYS
const unsigned int NUMBEROFCONDS = 3;
byte Gale[] = { 1, 20, 43, 63};
byte Thunder[] = { 26, 33, 37, 59, 60, 63, 71};
byte Snow[] = { 21, 59, 61, 68}; 


char *lookupName[NUMBEROFCONDS] = {"Gale", "Thunder", "Snow" };
byte *lookupArray[NUMBEROFCONDS] = {Gale, Thunder, Snow};
int lookupArraySize[NUMBEROFCONDS] = { 4, 7, 4};


//SETUP
void setup(){
  strip.begin();

    // Update LED contents, to start they are all 'off'
  strip.show();

  Serial.begin(9600);
}

//CHECK & UPDATE LOOP
void loop(){
      colorFade(Color( 0, 0, 255), "Gale"); // ideally I could specify start and end RGB values here and a fade duration. The reason being I want the LEDs to fade from and back to the colourWipe above.
      colorFade(Color( 113, 20, 0), "Thunder");
      colorFade(Color( 0, 150, 20), "Snow");
    delay(100); //wait 10 seconds before connecting again
  }


// MAIN FUNCTIONS

//This is the function I'm having trouble with...
void colorFade(uint32_t c, char* wthrname) {
  int i, j, index;
  for (index = 0; index < NUMBEROFCONDS; index++) {
    if (strcmp(wthrname, lookupName[index]) == 0) 
      break;
    }
    if (index == NUMBEROFCONDS) // No match found 
      return;
      
  byte *myArray = lookupArray[index];
  unsigned int myArraySize = lookupArraySize[index];
  
  for (c=0; c < 256; c++) { //What I'm really aiming for here is a function that will allow me to specify  START and END RGB values - a cross-fade function. So that in the Loop, I would ideally be able chose a starting RGB colour that fades to an ending RGB colour - for any of the LED arrays. Currently this 'for' is just fading in to blue, no matter what the Loop RGB values say.
    for (i=0; i < myArraySize; i++) { 
      strip.setPixelColor(myArray[i], c); 
    }
    strip.show();  
    delay(50);
    Serial.println("Fade In: ");
    Serial.println(wthrname);
    Serial.println("");
  }
}


// Create a 24 bit color value from R,G,B
uint32_t Color(byte r, byte g, byte b)
{
  uint32_t c;
  c = r;
  c <<= 8;
  c |= g;
  c <<= 8;
  c |= b;
  return c;
}

Hi There,

For others looking for crossfade between two colors, here is my function I use together with the adafruit ws2801 library, enjoy:

// usage:
// colorCrossFade(0,250,0,128,50,0,100,20); // fade from green to orange in 20 steps with delay of 100 between steps

void colorCrossFade(uint8_t r, uint8_t g, uint8_t b, uint8_t r2, uint8_t g2, uint8_t b2, uint8_t wait, uint8_t steps) 
{
  int currentColorR = 0;
  int currentColorG = 0;
  int currentColorB = 0;
  
  for (int j = 0; j <= steps; j++) {
    currentColorR = ((r * (steps - j)) + (r2 * j)) / (steps*2);
    currentColorG = ((g * (steps - j)) + (g2 * j)) / (steps*2);
    currentColorB = ((b * (steps - j)) + (b2 * j)) / (steps*2);
  
    for (int i=0; i < strip.numPixels(); i++) {
        strip.setPixelColor(i, currentColorR, currentColorG, currentColorB);
      }
    strip.show(); 
    delay(wait);
  }
}