NeoSegmentFade.ino 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // NeoSegmentBus
  2. // This example will demonstrate using the NeoSegmentBus which provides support for a
  3. // seven segment LED digit driven by three WS2811; connected in series with other digits
  4. //
  5. // See https://shop.idlehandsdev.com/products/addressable-7-segment-display for a hardware example
  6. //
  7. // This example will print current seconds since start of the Arduino
  8. // with a digit animating a circling path for each second
  9. //
  10. #include <NeoPixelSegmentBus.h>
  11. #include <NeoPixelAnimator.h>
  12. const uint16_t DigitCount = 5; // Max Digits, not segments, not pixels
  13. const uint8_t BusPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
  14. const uint16_t CycleDigit = 0;
  15. const uint16_t SecondsDigit = 1;
  16. #define brightness 128
  17. NeoPixelSegmentBus<SevenSegmentFeature, NeoWs2811Method> strip(DigitCount, BusPin);
  18. enum Animation
  19. {
  20. Animation_Cycle, // animation for the cycle indicator
  21. Animation_Fade, // animation for fade of seconds
  22. Animation_COUNT
  23. };
  24. NeoPixelAnimator animations(Animation_COUNT);
  25. void CycleAnimation(const AnimationParam& param)
  26. {
  27. // calculate which segment should be on using the animation progress
  28. uint8_t bitfield = 1 << ( static_cast<uint8_t>(param.progress * LedSegment_G) % LedSegment_G);
  29. // instant a digit with that segment on
  30. SevenSegDigit digit(bitfield, brightness);
  31. // apply it to the strip
  32. strip.SetPixelColor(CycleDigit, digit);
  33. }
  34. // for the animation of fading the new number in, we use
  35. // two digit DIBs (Device Independant Bitmaps) of SevenSegDigit to blend with;
  36. // each sized one less than the strip due to the first is a used for the cycle
  37. // animation.
  38. typedef NeoDib<SevenSegDigit> SevenSegDib;
  39. SevenSegDib StartingDigits(DigitCount - 1);
  40. SevenSegDib EndingDigits(DigitCount - 1);
  41. // shader class that will do the "string" blending
  42. //
  43. class DigitBlendShader
  44. {
  45. public:
  46. // this shader always renders and doesn't track a dirty state
  47. bool IsDirty() const
  48. {
  49. return true;
  50. }
  51. void ResetDirty()
  52. {
  53. }
  54. SevenSegDigit Apply(uint16_t indexDigit, SevenSegDigit digit)
  55. {
  56. // since we call EndingDigits.Render below, the digit argument is
  57. // from the EndingDigits so no need to call GetPixelColor to get it
  58. // create a digit that is a blend between the last seconds
  59. // value and the next seconds value using the BlendAmount
  60. SevenSegDigit blendDigit = SevenSegDigit::LinearBlend(
  61. StartingDigits.GetPixelColor(indexDigit),
  62. digit,
  63. BlendAmount);
  64. return blendDigit;
  65. }
  66. float BlendAmount;
  67. };
  68. // the instance of our shader class
  69. DigitBlendShader blendShader;
  70. void FadeAnimation(const AnimationParam& param)
  71. {
  72. // set the shader property BlendAmount to the animation progress
  73. blendShader.BlendAmount = param.progress;
  74. // apply it to the strip at the SecondsDigit location
  75. EndingDigits.Render<SevenSegmentFeature, DigitBlendShader>(strip,
  76. blendShader,
  77. SecondsDigit);
  78. }
  79. uint32_t lastSeconds;
  80. void setup()
  81. {
  82. lastSeconds = millis() / 1000;
  83. strip.Begin();
  84. strip.Show();
  85. // init animation Dibs as cleared
  86. StartingDigits.ClearTo(0);
  87. EndingDigits.ClearTo(0);
  88. }
  89. void loop()
  90. {
  91. uint32_t seconds = millis() / 1000;
  92. // when the seconds change, start animations for the update
  93. //
  94. if (seconds != lastSeconds)
  95. {
  96. // copy last animation ending digits as starting digits
  97. StartingDigits = EndingDigits;
  98. // format and display new value in ending digits dib
  99. String display(seconds);
  100. SevenSegDigit::SetString<SevenSegDib>(EndingDigits,
  101. 0,
  102. display.c_str(),
  103. brightness);
  104. // start the seconds fade animation
  105. animations.StartAnimation(Animation_Fade, 500, FadeAnimation);
  106. // start the cycle animation for the next second
  107. animations.StartAnimation(Animation_Cycle, 1000, CycleAnimation);
  108. lastSeconds = seconds;
  109. }
  110. if (animations.IsAnimating())
  111. {
  112. // the normal loop just needs these two to run the active animations
  113. animations.UpdateAnimations();
  114. strip.Show();
  115. }
  116. }