In the first post I said we would be doing a Larson scanner, and all we’ve done so far is make a light that goes back and forth in different colors. That is cool and all, but what about the FADING!
In standard Larson scanner, this is pretty easily done; you just need a way to go backwards for <n> steps and then you just write the bright color at the current spot and then dim it as you go backwards. With the color wheel, however, you would need to keep track of what the colors of the previous spots were and dim that color.
Seems like a lot of work to me.
Instead, we’re going to be building something that I think is a little cooler – a fading LED strip. Set a point to a specific color, and over <N> steps, it will automatically fade to black.
Hmm. It sounds like what we need is some code that can blend from a color to black. We already have a class that can do that – the ColorBlend class. We can just leverage that to do what we want. Here’s a test:
static void TestSingleFade()
{
FadingLedStrip fadingLedStrip(4);
LedStrip ledStrip;
LedColor ledColor;
fadingLedStrip.setColor(1, 255, 0, 0);
fadingLedStrip.show(ledStrip);
ledColor = ledStrip.getColor(1);
Assert::AreEqual(255, ledColor.Red);
fadingLedStrip.show(ledStrip);
ledColor = ledStrip.getColor(1);
Assert::AreEqual(191, ledColor.Red);
fadingLedStrip.show(ledStrip);
ledColor = ledStrip.getColor(1);
Assert::AreEqual(127, ledColor.Red);
fadingLedStrip.show(ledStrip);
ledColor = ledStrip.getColor(1);
Assert::AreEqual(63, ledColor.Red);
fadingLedStrip.show(ledStrip);
ledColor = ledStrip.getColor(1);
Assert::AreEqual(0, ledColor.Red);
}
We set a color and then each time we call show(), it dims the color down. In this case, the dim count is set to 4, so it will take 4 more steps to dim all the way down.
The code for FadingLedStrip is here:
class FadingLedStrip
{
int _steps;
ColorBlender _blenders[15];
public:
FadingLedStrip(int steps)
{
_steps = steps;
}
void setColor(int ledNumber, int red, int green, int blue)
{
_blenders[ledNumber].blendToColor(LedColor(red, green, blue), 0);
_blenders[ledNumber].blendToColor(LedColor(0, 0, 0), _steps);
}
void show(LedStrip& ledStrip)
{
for (int i = 0; i < 15; i++)
{
LedColor ledColor = _blenders[i].getCurrentColor();
ledStrip.setColor(i, ledColor.Red, ledColor.Green, ledColor.Blue);
_blenders[i].step();
}
ledStrip.show();
}
};
It keeps an array of ColorBlenders – one per LED. When we set a color, we tell the blender to immediately switch to that color, and we also tell it to blend to black of the specified number of steps.
The show() method then walks through all of the blenders and copies the color of each blender to the real strip and tells the blender to step.
Here’s a video of the final result:
Larson Scanner from Eric Gunnerson on Vimeo.
So, what do you think ?