NeoPixelBus icon indicating copy to clipboard operation
NeoPixelBus copied to clipboard

Multiple animations example

Open bramvrensen opened this issue 6 years ago • 2 comments

Hi Makuna,

First let me thank you for the great work you did and state that I am no programmer, I have some basic C++ knowledge from my eduction but thats already 8 years ago.

I have succesfully used the library to implement nice crossfades on my entire strip. I am now trying to "split" my strip in 3 parts that can be controlled individually (through homeassistant via MQTT) as if they are 3 separate 3 lights.

I can't figure out how to do this.

I use a fadeToColor function to set the desired color and then use your BlendAnimUpdate function. How can I modify this combo for multiple independent animations?

This is my fadeToColor function:

void fadeToColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t white, uint16_t time)
{
        // Fade upto a random color
        // we use HslColor object as it allows us to easily pick a hue
        // with the same saturation and luminance so the colors picked
        // will have similiar overall brightness
        RgbwColor target = RgbwColor(red,green,blue,white);
        uint16_t fadeTime = 0;

        animationState[0].StartingColor = strip.GetPixelColor(0);
        animationState[0].EndingColor = target;

        if(transitionUpdated == true)
        {
          fadeTime = time;
        }
        else
        {
          fadeTime = 0;
        }

        animations.StartAnimation(0, fadeTime, BlendAnimUpdate);

        // as we have processed the fade information, clear the transitionUpdated flag
        transitionUpdated = false;
}

And this is the blend function:

void BlendAnimUpdate(const AnimationParam& param)
{
    // this gets called for each animation on every time step
    // progress will start at 0.0 and end at 1.0
    // we use the blend function on the RgbColor to mix
    // color based on the progress given to us in the animation
    RgbwColor updatedColor = RgbwColor::LinearBlend(
        animationState[param.index].StartingColor,
        animationState[param.index].EndingColor,
        param.progress);

    // apply the color to the strip
    for (uint16_t pixel = 0; pixel < PixelCount; pixel++)
    {
        strip.SetPixelColor(pixel, updatedColor);
    }
}

The fade function easily be adjusted to use a "startPixel" and "endPixel" parameter to define which pixels should be modified but I can't wrap my ehad around how to extend the rest to understand this funtionality.

Any help would be much appreciated.

Kind regards, Bram

bramvrensen avatar Mar 18 '18 01:03 bramvrensen

Hello, I too am trying to figure out how to do this.

For example, how might one call two different animations from the example files in one program?

Thank you, Barry

bpompea avatar Jun 23 '19 02:06 bpompea

First, the animation state is specific to that animation "channel" and its callback. Nothing more. This is relevant if you have a separate animations that use different state. The blend example needs starting color and ending color. Another animation may just need a pixel position as all it does is light a single pixel is a subset of the strip. What I am getting at here is not to confuse that the "array" of animation state MUST be used to match the animations; its just handy is some cases. There may not be any need of an array at if each animation is completely different.

You can start as many animations as you have defined to use. You didn't include how animantions is defined. The first param to StartAnimation is the animation number you want to start. if you have three different animations that all run at the same time, then start them all like...

animations.StartAnimation(0, fadeTime, BlendAnimUpdate);
animations.StartAnimation(1, blinkTime, BlinkAnimUpdate);
animations.StartAnimation(2, glowTime, GlowAnimUpdate);

If you want your BlendAnimUpdate to effect only a subset of pixels, then only apply it to a subset, show below how you might extend the state to include which pixels are effected

void BlendAnimUpdate(const AnimationParam& param)
{
    // this gets called for each animation on every time step
    // progress will start at 0.0 and end at 1.0
    // we use the blend function on the RgbColor to mix
    // color based on the progress given to us in the animation
    RgbwColor updatedColor = RgbwColor::LinearBlend(
        animationState[param.index].StartingColor,
        animationState[param.index].EndingColor,
        param.progress);

    // apply the color to the strip
    for (uint16_t pixel = animationState[param.index].StartingIndex; 
                   pixel <= animationState[param.index].EndingIndex; 
                   pixel++)
    {
        strip.SetPixelColor(pixel, updatedColor);
    }
}

Makuna avatar Jun 23 '19 05:06 Makuna