// NeoPixelCylon // This example will move a Cylon Red Eye back and forth across the // the full collection of pixels on the strip. // // This will demonstrate the use of the NeoEase animation ease methods; that provide // simulated acceleration to the animations. // // #include #include const uint16_t PixelCount = 16; // make sure to set this to the number of pixels in your strip const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266 const RgbColor CylonEyeColor(HtmlColor(0x7f0000)); NeoPixelBus strip(PixelCount, PixelPin); // for esp8266 omit the pin //NeoPixelBus strip(PixelCount); NeoPixelAnimator animations(2); // only ever need 2 animations uint16_t lastPixel = 0; // track the eye position int8_t moveDir = 1; // track the direction of movement // uncomment one of the lines below to see the effects of // changing the ease function on the movement animation AnimEaseFunction moveEase = // NeoEase::Linear; // NeoEase::QuadraticInOut; // NeoEase::CubicInOut; NeoEase::QuarticInOut; // NeoEase::QuinticInOut; // NeoEase::SinusoidalInOut; // NeoEase::ExponentialInOut; // NeoEase::CircularInOut; void FadeAll(uint8_t darkenBy) { RgbColor color; for (uint16_t indexPixel = 0; indexPixel < strip.PixelCount(); indexPixel++) { color = strip.GetPixelColor(indexPixel); color.Darken(darkenBy); strip.SetPixelColor(indexPixel, color); } } void FadeAnimUpdate(const AnimationParam& param) { if (param.state == AnimationState_Completed) { FadeAll(10); animations.RestartAnimation(param.index); } } void MoveAnimUpdate(const AnimationParam& param) { // apply the movement animation curve float progress = moveEase(param.progress); // use the curved progress to calculate the pixel to effect uint16_t nextPixel; if (moveDir > 0) { nextPixel = progress * PixelCount; } else { nextPixel = (1.0f - progress) * PixelCount; } // if progress moves fast enough, we may move more than // one pixel, so we update all between the calculated and // the last if (lastPixel != nextPixel) { for (uint16_t i = lastPixel + moveDir; i != nextPixel; i += moveDir) { strip.SetPixelColor(i, CylonEyeColor); } } strip.SetPixelColor(nextPixel, CylonEyeColor); lastPixel = nextPixel; if (param.state == AnimationState_Completed) { // reverse direction of movement moveDir *= -1; // done, time to restart this position tracking animation/timer animations.RestartAnimation(param.index); } } void SetupAnimations() { // fade all pixels providing a tail that is longer the faster // the pixel moves. animations.StartAnimation(0, 5, FadeAnimUpdate); // take several seconds to move eye fron one side to the other animations.StartAnimation(1, 2000, MoveAnimUpdate); } void setup() { strip.Begin(); strip.Show(); SetupAnimations(); } void loop() { // this is all that is needed to keep it running // and avoiding using delay() is always a good thing for // any timing related routines animations.UpdateAnimations(); strip.Show(); }