Tasmota/lib/NeoPixelBus-2.2.9/examples/animations/NeoPixelFunFadeInOut/NeoPixelFunFadeInOut.ino

133 lines
3.9 KiB
C++

// NeoPixelFunFadeInOut
// This example will randomly pick a color and fade all pixels to that color, then
// it will fade them to black and restart over
//
// This example demonstrates the use of a single animation channel to animate all
// the pixels at once.
//
#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 uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
const uint8_t AnimationChannels = 1; // we only need one as all the pixels are animated at once
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
NeoPixelAnimator animations(AnimationChannels); // NeoPixel animation management object
uint16_t effectState = 0; // general purpose variable used to store effect state
// what is stored for state is specific to the need, in this case, the colors.
// basically what ever you need inside the animation update function
struct MyAnimationState
{
RgbColor StartingColor;
RgbColor EndingColor;
};
// one entry per pixel to match the animation timing manager
MyAnimationState animationState[AnimationChannels];
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);
}
randomSeed(seed);
}
// simple 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
RgbColor updatedColor = RgbColor::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);
}
}
void FadeInFadeOutRinseRepeat(float luminance)
{
if (effectState == 0)
{
// 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
RgbColor target = HslColor(random(360) / 360.0f, 1.0f, luminance);
uint16_t time = random(800, 2000);
animationState[0].StartingColor = strip.GetPixelColor(0);
animationState[0].EndingColor = target;
animations.StartAnimation(0, time, BlendAnimUpdate);
}
else if (effectState == 1)
{
// fade to black
uint16_t time = random(600, 700);
animationState[0].StartingColor = strip.GetPixelColor(0);
animationState[0].EndingColor = RgbColor(0);
animations.StartAnimation(0, time, BlendAnimUpdate);
}
// toggle to the next effect state
effectState = (effectState + 1) % 2;
}
void setup()
{
strip.Begin();
strip.Show();
SetRandomSeed();
}
void loop()
{
if (animations.IsAnimating())
{
// the normal loop just needs these two to run the active animations
animations.UpdateAnimations();
strip.Show();
}
else
{
// no animation runnning, start some
//
FadeInFadeOutRinseRepeat(0.2f); // 0.0 = black, 0.25 is normal, 0.5 is bright
}
}