| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // NeoSegmentBus
- // This example will demonstrate using the NeoSegmentBus which provides support for a
- // seven segment LED digit driven by three WS2811; connected in series with other digits
- //
- // See https://shop.idlehandsdev.com/products/addressable-7-segment-display for a hardware example
- //
- // This example will print current seconds since start of the Arduino
- // with a digit animating a circling path for each second
- //
- #include <NeoPixelSegmentBus.h>
- #include <NeoPixelAnimator.h>
- const uint16_t DigitCount = 5; // Max Digits, not segments, not pixels
- const uint8_t BusPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
- const uint16_t CycleDigit = 0;
- const uint16_t SecondsDigit = 1;
- #define brightness 128
- NeoPixelSegmentBus<SevenSegmentFeature, NeoWs2811Method> strip(DigitCount, BusPin);
- enum Animation
- {
- Animation_Cycle, // animation for the cycle indicator
- Animation_Fade, // animation for fade of seconds
- Animation_COUNT
- };
- NeoPixelAnimator animations(Animation_COUNT);
- void CycleAnimation(const AnimationParam& param)
- {
- // calculate which segment should be on using the animation progress
- uint8_t bitfield = 1 << ( static_cast<uint8_t>(param.progress * LedSegment_G) % LedSegment_G);
- // instant a digit with that segment on
- SevenSegDigit digit(bitfield, brightness);
- // apply it to the strip
- strip.SetPixelColor(CycleDigit, digit);
- }
- // for the animation of fading the new number in, we use
- // two digit DIBs (Device Independant Bitmaps) of SevenSegDigit to blend with;
- // each sized one less than the strip due to the first is a used for the cycle
- // animation.
- typedef NeoDib<SevenSegDigit> SevenSegDib;
- SevenSegDib StartingDigits(DigitCount - 1);
- SevenSegDib EndingDigits(DigitCount - 1);
- // shader class that will do the "string" blending
- //
- class DigitBlendShader
- {
- public:
- // this shader always renders and doesn't track a dirty state
- bool IsDirty() const
- {
- return true;
- }
- void ResetDirty()
- {
- }
- SevenSegDigit Apply(uint16_t indexDigit, SevenSegDigit digit)
- {
- // since we call EndingDigits.Render below, the digit argument is
- // from the EndingDigits so no need to call GetPixelColor to get it
- // create a digit that is a blend between the last seconds
- // value and the next seconds value using the BlendAmount
- SevenSegDigit blendDigit = SevenSegDigit::LinearBlend(
- StartingDigits.GetPixelColor(indexDigit),
- digit,
- BlendAmount);
- return blendDigit;
- }
- float BlendAmount;
- };
- // the instance of our shader class
- DigitBlendShader blendShader;
- void FadeAnimation(const AnimationParam& param)
- {
- // set the shader property BlendAmount to the animation progress
- blendShader.BlendAmount = param.progress;
- // apply it to the strip at the SecondsDigit location
- EndingDigits.Render<SevenSegmentFeature, DigitBlendShader>(strip,
- blendShader,
- SecondsDigit);
- }
- uint32_t lastSeconds;
- void setup()
- {
- lastSeconds = millis() / 1000;
- strip.Begin();
- strip.Show();
- // init animation Dibs as cleared
- StartingDigits.ClearTo(0);
- EndingDigits.ClearTo(0);
- }
- void loop()
- {
- uint32_t seconds = millis() / 1000;
-
- // when the seconds change, start animations for the update
- //
- if (seconds != lastSeconds)
- {
- // copy last animation ending digits as starting digits
- StartingDigits = EndingDigits;
-
- // format and display new value in ending digits dib
- String display(seconds);
- SevenSegDigit::SetString<SevenSegDib>(EndingDigits,
- 0,
- display.c_str(),
- brightness);
- // start the seconds fade animation
- animations.StartAnimation(Animation_Fade, 500, FadeAnimation);
- // start the cycle animation for the next second
- animations.StartAnimation(Animation_Cycle, 1000, CycleAnimation);
- lastSeconds = seconds;
- }
- if (animations.IsAnimating())
- {
- // the normal loop just needs these two to run the active animations
- animations.UpdateAnimations();
- strip.Show();
- }
- }
|