Color fade over set time giving strange outputs.

Hey guys,

I'm relatively new to Arduino and this forum has been insanely useful to help with almost every speed bump along the way! However, I'm having an issue that I can't find an answer for and it's been giving me a headache. Any help would be appreciated.

I have an LED strip (5050 SMD LEDs with the ws2811 chip) and I am trying to get it to flash a color, then fade from that color to off. My code is figuring out how long the code has been running since it entered the function, then multiplies the RGB values of the original color by the (decay time - elapsed time ) / decay time , which should give values from 1 to 0 as the code loops through. However, the first iteration always sets the values of non zero RGB attributes to 20, and I'm not really sure why. I also noticed that some of the other values aren't what I would have expected.

Here is my function:

void fadeColor( CRGB flashColor)
{
    int i = 0;
    int startTime = (int)millis();
    int delayLeft = 280;
    int curTime;
    CRGB curColor;
    
    Serial.print("starting color Red: ");
    Serial.print(flashColor.red);
    Serial.print(" starting color Green: ");
    Serial.print(flashColor.green);
    Serial.print(" starting color Blue ");
    Serial.print(flashColor.blue);
    Serial.print("\n");
    while( delayLeft > 0 )
    {
        Serial.print("loop #");
        Serial.print(i);
        Serial.print(" delayLeft = ");
        Serial.print(delayLeft);
        Serial.print("\n");
        i++;
        //calculate the color
        curColor.red = flashColor.red * delayLeft / 280;
        curColor.green = flashColor.green * delayLeft / 280;
        curColor.blue = flashColor.blue * delayLeft / 280;
        Serial.print(" current color Red = ");
        Serial.print(curColor.red);
        Serial.print(" current color Green = ");
        Serial.print(curColor.green);
        Serial.print(" current color Blue = ");
        Serial.print(curColor.blue);
        Serial.print("\n");
        
        //Display the color
        for(int i= startIndex; i < endIndex; i+= spacing)
        {
            leds[i] = curColor;
        }
        FastLED.show();
        
        curTime = (int)millis();
        delayLeft = 280 - ( curTime - startTime) ;
    }
}

FastLED.show() is a function that pushes the data from my leds array to the strip itself from the LED library I'm using, and leds is an array of CRGB values. The indexing on the for loop is a way of choosing which LEDs light up on the strip. Let me know if you need any additional info about the code.

And here is some debugging output from running this code:

message start time = 211
blue fade
starting color Red: 0 starting color Green: 0 starting color Blue: 255
loop #0 delayLeft = 280 current color Red = 0 current color Green = 0 current color Blue = 20

loop #1 delayLeft = 137 current color Red = 0 current color Green = 0 current color Blue = 147

loop #2 delayLeft = 38 current color Red = 0 current color Green = 0 current color Blue = 34

Elapsed time: 355

message start time = 713
green fade
starting color Red: 0 starting color Green: 255 starting color Blue: 0
loop #0 delayLeft = 280 current color Red = 0 current color Green = 20 current color Blue = 0

loop #1 delayLeft = 137 current color Red = 0 current color Green = 147 current color Blue = 0

loop #2 delayLeft = 37 current color Red = 0 current color Green = 33 current color Blue = 0

Elapsed time: 355

message start time = 1716
green fade
starting color Red: 0 starting color Green: 255 starting color Blue: 0
loop #0 delayLeft = 280 current color Red = 0 current color Green = 20 current color Blue = 0

loop #1 delayLeft = 137 current color Red = 0 current color Green = 147 current color Blue = 0

loop #2 delayLeft = 37 current color Red = 0 current color Green = 33 current color Blue = 0

Elapsed time: 356

message start time = 2243
blue fade
starting color Red: 0 starting color Green: 0 starting color Blue: 255
loop #0 delayLeft = 280 current color Red = 0 current color Green = 0 current color Blue = 20

loop #1 delayLeft = 138 current color Red = 0 current color Green = 0 current color Blue = 148

loop #2 delayLeft = 36 current color Red = 0 current color Green = 0 current color Blue = 32

Elapsed time: 356

message start time = 2745
green fade
starting color Red: 0 starting color Green: 255 starting color Blue: 0
loop #0 delayLeft = 280 current color Red = 0 current color Green = 20 current color Blue = 0

loop #1 delayLeft = 137 current color Red = 0 current color Green = 147 current color Blue = 0

loop #2 delayLeft = 37 current color Red = 0 current color Green = 33 current color Blue = 0

Elapsed time: 356

If you notice, the last run through of a green fade, loop#1 says that the delayLeft is 137ms, so the calculated green value should be 137 / 280 * 255 = 124.76, but the value I ended up getting was 147, and the values during loop #0 that should be 255 or slightly lower are always 20.

Any ideas where these errors are coming from? My best guess was that millis() returns an unsigned long and there was some kind of typecasting error, but during loop#0 I don't even use millis() to get my delayLeft value, I hard coded it myself.

Any help would be appreciated! The fade effect looks awesome other than the slight flash at the beginning, and I'd love to have this ready to implement in some projects I'm working on.

Hi, try the following changes:

Change startTime and delayLeft from int to unsigned long.

Remove the "(int)" when using millis ().

Change 280 to 280UL.

Paul

Hey Paul,

Thanks so much! That fixed it. I also had to change curTime to an unsigned long. This did cause another problem with the while loop condition, since when you subtract something greater than 280 while calculating the delayLeft, you get a big positive value, so my while condition was changed to make sure 281 > delayLength > 0. Simple fix.

I'm new to the forums, so I'm not sure if I give you karma or something, but if there's something like that I'm supposed to do for you let me know.

Thanks Jacob, karma is the usual way. If I reach 100 I get a yacht...

Looks like I can't give karma yet :stuck_out_tongue: I have no + button. Perhaps I'l l come back when it let's me :stuck_out_tongue: