Files
NeoPixelBus/examples/NeoPixelFunLoop/NeoPixelFunLoop.ino
Michael Miller eb77795f65 DotStar and NoPin NeoPixel
removed the need to provide the pin argument for Esp8266 NeoPixelBus
where it was ignored.
Added another DotStar color feature.
Fixed DotStar color features to use RgbColor when there is no need for
RgbwColor.
2016-09-02 10:32:10 -07:00

142 lines
4.8 KiB
C++

// NeoPixelFunLoop
// This example will move a trail of light around a series of pixels.
// A ring formation of pixels looks best.
// The trail will have a slowly fading tail.
//
// This will demonstrate the use of the NeoPixelAnimator.
// It shows the advanced use an animation to control the modification and
// starting of other animations.
// It also shows the normal use of animating colors.
// It also demonstrates the ability to share an animation channel rather than
// hard code them to pixels.
//
#include <NeoPixelBus.h>
#include <NeoPixelAnimator.h>
const uint16_t PixelCount = 16; // make sure to set this to the number of pixels in your strip
const uint16_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
const uint16_t AnimCount = PixelCount / 5 * 2 + 1; // we only need enough animations for the tail and one extra
const uint16_t PixelFadeDuration = 300; // third of a second
// one second divide by the number of pixels = loop once a second
const uint16_t NextPixelMoveDuration = 1000 / PixelCount; // how fast we move through the pixels
NeoGamma<NeoGammaTableMethod> colorGamma; // for any fade animations, best to correct gamma
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
// For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
// There are other Esp8266 alternative methods that provide more pin options, but also have
// other side effects.
//NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount);
//
// NeoEsp8266Uart800KbpsMethod uses GPI02 instead
// what is stored for state is specific to the need, in this case, the colors and
// the pixel to animate;
// basically what ever you need inside the animation update function
struct MyAnimationState
{
RgbColor StartingColor;
RgbColor EndingColor;
uint16_t IndexPixel; // which pixel this animation is effecting
};
NeoPixelAnimator animations(AnimCount); // NeoPixel animation management object
MyAnimationState animationState[AnimCount];
uint16_t frontPixel = 0; // the front of the loop
RgbColor frontColor; // the color at the front of the loop
void SetRandomSeed()
{
uint32_t seed;
// random works best with a seed that can use 31 bits
// analogRead on a unconnected pin tends toward less than four bits
seed = analogRead(0);
delay(1);
for (int shifts = 3; shifts < 31; shifts += 3)
{
seed ^= analogRead(0) << shifts;
delay(1);
}
// Serial.println(seed);
randomSeed(seed);
}
void FadeOutAnimUpdate(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(
animationState[param.index].StartingColor,
animationState[param.index].EndingColor,
param.progress);
// apply the color to the strip
strip.SetPixelColor(animationState[param.index].IndexPixel,
colorGamma.Correct(updatedColor));
}
void LoopAnimUpdate(const AnimationParam& param)
{
// wait for this animation to complete,
// we are using it as a timer of sorts
if (param.state == AnimationState_Completed)
{
// done, time to restart this position tracking animation/timer
animations.RestartAnimation(param.index);
// pick the next pixel inline to start animating
//
frontPixel = (frontPixel + 1) % PixelCount; // increment and wrap
if (frontPixel == 0)
{
// we looped, lets pick a new front color
frontColor = HslColor(random(360) / 360.0f, 1.0f, 0.25f);
}
uint16_t indexAnim;
// do we have an animation available to use to animate the next front pixel?
// if you see skipping, then either you are going to fast or need to increase
// the number of animation channels
if (animations.NextAvailableAnimation(&indexAnim, 1))
{
animationState[indexAnim].StartingColor = frontColor;
animationState[indexAnim].EndingColor = RgbColor(0, 0, 0);
animationState[indexAnim].IndexPixel = frontPixel;
animations.StartAnimation(indexAnim, PixelFadeDuration, FadeOutAnimUpdate);
}
}
}
void setup()
{
strip.Begin();
strip.Show();
SetRandomSeed();
// we use the index 0 animation to time how often we move to the next
// pixel in the strip
animations.StartAnimation(0, NextPixelMoveDuration, LoopAnimUpdate);
}
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();
}