These are chat archives for Makuna/NeoPixelBus

24th
Dec 2016
pippin88
@pippin88
Dec 24 2016 09:03
I'm looking for some help with NeoPixelBus and animations for a word clock. I had a working word clock with the Adafruit Neopixel and Neomatrix libraries, however I was having crashes when I changed from an arduino to an ESP8266 (an Oak to be specific). I've now got the very basic clock working with NeoPixelBus, however I'm having great difficult with the animations side of things. I want to have a word fade in. I can't work out how to animate groups of pixels, particularly when using the topology function. I can't find any examples similar to what I want to do (animate a segment of the display rather than all of it). Pastebin of my original word clock code: http://pastebin.com/7iJ0qk8T. Pastebin of current NeoPixelBus code: http://pastebin.com/u1aGfrKJ (note, I've commented out any attempt at animations, and am just turning on and off the words). Help is appreciated.
Michael Miller
@Makuna
Dec 24 2016 20:34
@pippin88 The animation system is very flexible system; with that comes complexity; don't be worried that it takes a bit to come up to speed with it. To provide some pointers to how to do this...
Michael Miller
@Makuna
Dec 24 2016 20:48

Start with some animation state you need to track, since you are just blending (fading from and to black) this piece from a sample will hold that state for you

struct BlendAnimationState
{
    RgbColor StartingColor;
    RgbColor EndingColor;
};

Since you want to do this per word (not pixel), you need enough of these for maximum number of animations active at once; since I don't know exactly what you plan; lets just say one per word.

const uint8_t c_WordCount = 15;
BlendAnimationState wordAnimationStates[c_WordCount]; // one per word
NeoPixelAnimator animations(c_WordCount); // again one per word

You also need some way to track to WORD# to the actual list of pixels that are effected. I will assume you have this already.
Then your animation update call back it would do something like this (again taken from sample and modified lightly)

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

    RgbColor updatedColor = RgbColor::LinearBlend(
        wordAnimationStates[param.index].StartingColor,
        wordAnimationStates[param.index].EndingColor,
        param.progress);

    // apply the color to the strip
    for (uint16_t pixel = myWordIndexStartPixel(param.index); pixel < myWordIndexCountPixels(param.index); pixel++)
    {
        strip.SetPixelColor(pixel, updatedColor);
    }
}

Then when you want to fade a word in, you would start the animation like this...

        animationState[indexWord].StartingColor = OffColor;
        animationState[indexWord].EndingColor = OnColor;

        animations.StartAnimation(indexWord, 3000, BlendAnimUpdate); // three seconds
pippin88
@pippin88
Dec 24 2016 23:50
Michael, thanks a lot for the reply. I'm currently defining the words using topology (i.e. a matrix). Each word is a function, with a row variable, and an array containing the pixel numbers in that row.

For example, the first word on the top line is near. When appropriate, my clock display function calls near(ON).
void near (int state){
//this word's details
int iRow = 0;
int arrCols[] = {0,1,2,3};
int arrSize = (sizeof(arrCols)/sizeof(arrCols[0])); //find array size so we don't read random values
int& wstate = sNEAR; //int&

displayWord(iRow, arrCols, arrSize, wstate, state);
}

What I don't understand is how to pass the word location (the actual list of pixels that are effected) to the animation function.