# Why is 1020 steps used for crossfading colors on an RGB LED?

I'm looking into how to smoothly crossfade between colors on an RGB LED with the Arduino and I've found this piece of code for doing it: https://www.arduino.cc/en/Tutorial/ColorCrossfader

I understand all parts of the code except for one thing. The values for red, green and blue are changed incrementally through 1020 steps, because 255*4 = 1020. But WHY 4? There are 3 colors, and 255 * 3 = 765. So why not 765 steps?

• 255 ^ 3 would be nearer the mark, and that's a lot more than 765. Or 1020...
– Brian Drummond
Dec 31 '15 at 11:53
• @Brian, that would be the number of steps to go through every possible colour combination. That wasn't the program intent. (Paraphrasing:) You define a series of RGB colours - #CC0000, #30DD00, etc. - and get the system to smoothly transition between them. The 1020 steps is intended to give quarter bit resolution on the step interval. Details in my answer. Jan 1 '16 at 21:51
• I'm looking a non=blocking cross fader because while it is cycling through the colours slowly the processor is still able to receive serial communications. So far the non-blocking ones are not smooth enough. Feb 22 '18 at 10:46

Extract from code:

``````int wait = 10;      // 10ms internal crossFade delay; increase for slower fades

for (int i = 0; i <= 1020; i++) {
redVal = calculateVal(stepR, redVal, i);
grnVal = calculateVal(stepG, grnVal, i);
bluVal = calculateVal(stepB, bluVal, i);

analogWrite(redPin, redVal);   // Write current values to LED pins
analogWrite(grnPin, grnVal);
analogWrite(bluPin, bluVal);

delay(wait); // Pause for 'wait' milliseconds before resuming the loop

if (DEBUG) { // If we want serial output, print it at the
if (i == 0 or i % loopCount == 0) { // beginning, and every loopCount times
}
DEBUG += 1;
}
}
``````

The 1020 in the loop determines the time taken to make the crossfade from the current colour to the next - not the total cycle as you seem to think. In the main loop we have

``````crossFade(red);
``````

And each of these crossfades will take 1024 * wait ms to complete. 'wait' is set to 10 ms so I would expect it to take 10.24 s to complete a fade from one colour to the next.

I think the large number (1020) is just to give a fine resolution in the steps calculation which is all done with integers. (What struck me as odd is that it doesn't use 256 * 4 = 1024.) The larger we make this number the finer the step resolution becomes. With coarse steps the ramp will complete too early.

Let's say we had 255 steps and we wish to go from 134 to 0.

``````step = 255 / (endValue - prevValue)
step = 255 / (134 - 0 ) = 1.9 which will be rounded down to 1.
``````

This means that the crossfade will be complete in 134 steps instead of 255. i.e., it will finish 47% early.

If we use 1020 steps and we wish to go from 134 to 0.

``````step = 1020 / (endValue - prevValue)
step = 1020 / (134 - 0 ) = 7.6 which will be rounded down to 7.
``````

This means that the crossfade will be complete in 938 steps instead of 1020. i.e., it will finish 8% early.

• But why is this written in the comments? There seems to be some meaning behind it: `* In the real program, the color percentages are converted to * 0-255 values, and there are 1020 steps (255*4).`
– Harald
Dec 31 '15 at 12:00
• See the update. Dec 31 '15 at 13:12
• The 1020 is indeed a granularity mistake. First he/she/they/them/it/x say(s) 0 to 255, to then conclude that's 255 levels. Undermines my trust in the efficiency of the remaining maths to be honest, as the total average effective fade error will be lower with the correct 1024 steps for quarter-bit granularity in integer maths. Though the better way is fixed point or integer-remainder maths of course, but "them" often finds that scary? Dec 31 '15 at 13:29
• I'd say it's fine for the application. I don't know that we'd notice the steps given that they're 1/255 of the full brightness. The Arduino code is intended for a learning audience and in this instance I think simplicity and readability wins over accuracy. Dec 31 '15 at 13:48
• "What struck me as odd is that it doesn't use 256 * 4 = 1024" Hee hee. This is classically known as a fence-post error. When you start at (let's say) a value of 00, it only takes 255 steps to get to the maximum value of 256. Dec 31 '15 at 19:54

For my transition between colors I used arrays during the setup to collect the main transitions (bigger jumps between RGB values) then during the loop I used a series of `analogWrite()` commands essentially splitting the jumps by a 16th, for example starting at `255, 0, 0` the next array value was `223, 0, 0` in the loop it went from `255, 0, 0` to `253, 0, 0` to `251, 0, 0` finally landing the last loop value of `225, 0, 0` before starting the loop over at the next array value of `223, 0, 0`. It's important to realize what colors transition into others and what the corresponding RGB values are of that transition.

Tomorrow I'll post my code, it's a bit messy as it was more proof of concept that starting with a distinct plan.