Advertisement
nathancarter

Signal Disc

Dec 1st, 2022
979
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.14 KB | Source Code | 0 0
  1. #include <Adafruit_NeoPixel.h>
  2. #include <FastLED.h>
  3. #include <JC_Button.h>
  4.  
  5. #define COLOR_ORDER GRB
  6. #define CHIPSET     WS2812
  7.  
  8. #define MAIN_LEDS_TOTAL 122
  9. #define SEGMENT_START_1 0
  10. #define SEGMENT_COUNT_1 11
  11. #define SEGMENT_START_2 11
  12. #define SEGMENT_COUNT_2 15
  13. #define SEGMENT_START_3 26
  14. #define SEGMENT_COUNT_3 17
  15. #define SEGMENT_START_4 43
  16. #define SEGMENT_COUNT_4 18
  17. #define SEGMENT_START_5 61
  18. #define SEGMENT_COUNT_5 18
  19. #define SEGMENT_START_6 79
  20. #define SEGMENT_COUNT_6 17
  21. #define SEGMENT_START_7 96
  22. #define SEGMENT_COUNT_7 15
  23. #define SEGMENT_START_8 111
  24. #define SEGMENT_COUNT_8 11
  25.  
  26. #define MODE_BUTTON_PIN 15 // A1 on nano
  27. #define DATA_PIN 14 // A0 on nano
  28.  
  29. #define MODE_COUNT_MAXIMUM 9 // number of different lighting modes
  30.  
  31. #define DIM_YELLOW_COLOR 0xFFFF00
  32. #define BRIGHT_YELLOW_COLOR 0x999900
  33. #define BRIGHT_BLUE_COLOR 0x0000FF
  34. #define WHITE_COLOR 0X999999
  35. #define BRIGHT_RED_COLOR 0XFF0300
  36.  
  37.  
  38. #define BRIGHTNESS_NOMINAL 12
  39. #define BRIGHTNESS_MID 63
  40. #define BRIGHTNESS_MAX 255
  41.  
  42. #define FIRE_SPEED 50 // ms between fire refresh rate, higher is slower
  43. #define FIRE_COOLING 70
  44. #define FIRE_SPARKING 270
  45. // #define FIRE_ROW_LEDS 11
  46. // #define FIRE_ROW_COUNT 5
  47.  
  48. #define SPARKLE_SPEED 75 // ms between sparkle refresh rate, higher is slower
  49.  
  50. #define RAINBOW_SPEED 10 // ms between rainbow sweep movement, higher is slower
  51.  
  52. #define FADE_SPEED 1 // ms between fade steps, higher is slower
  53.  
  54. #define CONFETTI_SPEED 75 // ms to between confetti refresh rate, higher is slower
  55. #define CONFETTI_FADE 10 // cycles to fade confetti, higher is faster
  56.  
  57. Adafruit_NeoPixel MainStrip = Adafruit_NeoPixel(MAIN_LEDS_TOTAL, DATA_PIN, NEO_GRB + NEO_KHZ800);
  58.  
  59. Button ModeButton(MODE_BUTTON_PIN);       // define the button that increases brightness
  60.  
  61. CRGBPalette16 gPal;     // Palette color for flames
  62.  
  63.  
  64. unsigned long TimerMaster = 0; // master clock timer
  65. unsigned long TimerFire = 0; // fire update timer
  66. unsigned long TimerSparkle = 0; // sparkle update timer
  67. unsigned long TimerSweep = 0; // sweep update timer
  68. unsigned long TimerConfetti = 0; // confetti update timer
  69. unsigned long TimerFade = 0; // fade update timer
  70.  
  71. int ModeCounter = 1; // Lighting animation mode.
  72. // 1 = dim static yellow
  73. // 2 = sparkling yellow
  74. // 3 = rainbow sweep
  75. // 4 = orange fire
  76. // 5 = blue fire
  77. // 6 = sparkling blue
  78.  
  79. int ColorWheel = 0; // int to hold starting rainbow sweep color
  80. bool FadeToggle = 0; // bool to hold fading in or out
  81. int FadeValue = BRIGHTNESS_MID;
  82.  
  83. byte heat[MAIN_LEDS_TOTAL]; // global array of heat values
  84. CRGB leds[MAIN_LEDS_TOTAL]; // global array for confetti leds
  85.  
  86. void setup()
  87. {
  88.   delay(1500); // sanity delay
  89.   gPal = HeatColors_p;
  90.   MainStrip.begin(); // initialize fire strip
  91.   MainStrip.setBrightness(BRIGHTNESS_NOMINAL);
  92.   ModeButton.begin();
  93. }
  94.  
  95. void loop()
  96. {
  97.   TimerMaster = millis();
  98.  
  99.  
  100.   ModeButton.read();
  101.   if (ModeButton.wasPressed())
  102.   {
  103.     // If the button was pressed, increase to the next mode
  104.     ModeCounter++;
  105.     // If it reaches the end, reset to beginning
  106.     if (ModeCounter > MODE_COUNT_MAXIMUM)
  107.     {
  108.       ModeCounter = 1;
  109.     }
  110.     MainStrip.fill(0x000000);
  111.     MainStrip.show();
  112.   }
  113.  
  114.  
  115.  
  116.   // Mode 1:  Dim yellow
  117.   if (ModeCounter == 1)
  118.   {
  119.     // Set everything to dim yellow
  120.     MainStrip.setBrightness(BRIGHTNESS_NOMINAL);
  121.     MainStrip.fill(BRIGHT_YELLOW_COLOR);
  122.     MainStrip.show();
  123.   }
  124.  
  125.   // Mode 2:  Sparkling yellow
  126.   if (ModeCounter == 2)
  127.   {
  128.     MainStrip.setBrightness(BRIGHTNESS_MAX);
  129.  
  130.     if (TimerMaster >= TimerSparkle)
  131.     {
  132.       MainStrip.fill(BRIGHT_YELLOW_COLOR);
  133.       MainStrip.setPixelColor(random(MAIN_LEDS_TOTAL), 0xFFFFFF);
  134.       MainStrip.show();
  135.       TimerSparkle = (TimerMaster + SPARKLE_SPEED);
  136.     }
  137.   }
  138.  
  139.   // Mode 3: Rainbow sweep
  140.   if (ModeCounter == 3)
  141.   {
  142.     MainStrip.setBrightness(BRIGHTNESS_MAX);
  143.     if (TimerMaster >= TimerSweep)
  144.     {
  145.       if (ColorWheel >= 255)
  146.       {
  147.         ColorWheel = 0;
  148.       }
  149.       MainStrip.fill(Wheel(ColorWheel - 0), SEGMENT_START_1, SEGMENT_COUNT_1);
  150.       MainStrip.fill(Wheel(ColorWheel - 10), SEGMENT_START_2, SEGMENT_COUNT_2);
  151.       MainStrip.fill(Wheel(ColorWheel - 20), SEGMENT_START_3, SEGMENT_COUNT_3);
  152.       MainStrip.fill(Wheel(ColorWheel - 30), SEGMENT_START_4, SEGMENT_COUNT_4);
  153.       MainStrip.fill(Wheel(ColorWheel - 40), SEGMENT_START_5, SEGMENT_COUNT_5);
  154.       MainStrip.fill(Wheel(ColorWheel - 50), SEGMENT_START_6, SEGMENT_COUNT_6);
  155.       MainStrip.fill(Wheel(ColorWheel - 60), SEGMENT_START_7, SEGMENT_COUNT_7);
  156.       MainStrip.fill(Wheel(ColorWheel - 70), SEGMENT_START_8, SEGMENT_COUNT_8);
  157.       ColorWheel++;
  158.       MainStrip.show();
  159.       TimerSweep = (TimerMaster + RAINBOW_SPEED);
  160.     }
  161.   }
  162.  
  163.   // Mode 4: Orange fire
  164.   if (ModeCounter == 4 )
  165.   {
  166.     gPal = HeatColors_p;
  167.     MainStrip.setBrightness(BRIGHTNESS_MAX);
  168.     if (TimerMaster >= TimerFire)
  169.     {
  170.       Fire2022(SEGMENT_START_1, SEGMENT_COUNT_1, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  171.       Fire2022(SEGMENT_START_2, SEGMENT_COUNT_2, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  172.       Fire2022(SEGMENT_START_3, SEGMENT_COUNT_3, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  173.       Fire2022(SEGMENT_START_4, SEGMENT_COUNT_4, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  174.       Fire2022(SEGMENT_START_5, SEGMENT_COUNT_5, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  175.       Fire2022(SEGMENT_START_6, SEGMENT_COUNT_6, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  176.       Fire2022(SEGMENT_START_7, SEGMENT_COUNT_7, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  177.       Fire2022(SEGMENT_START_8, SEGMENT_COUNT_8, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  178.       TimerFire = (TimerMaster + FIRE_SPEED);
  179.       MainStrip.show();
  180.     }
  181.   }
  182.  
  183.  
  184.   // Mode 5: Blue fire
  185.   if (ModeCounter == 5 )
  186.   {
  187.     gPal = CRGBPalette16( CRGB::Black, CRGB::Blue, CRGB::Aqua,  CRGB::White);
  188.     MainStrip.setBrightness(BRIGHTNESS_MAX);
  189.     if (TimerMaster >= TimerFire)
  190.     {
  191.       Fire2022(SEGMENT_START_1, SEGMENT_COUNT_1, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  192.       Fire2022(SEGMENT_START_2, SEGMENT_COUNT_2, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  193.       Fire2022(SEGMENT_START_3, SEGMENT_COUNT_3, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  194.       Fire2022(SEGMENT_START_4, SEGMENT_COUNT_4, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  195.       Fire2022(SEGMENT_START_5, SEGMENT_COUNT_5, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  196.       Fire2022(SEGMENT_START_6, SEGMENT_COUNT_6, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  197.       Fire2022(SEGMENT_START_7, SEGMENT_COUNT_7, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  198.       Fire2022(SEGMENT_START_8, SEGMENT_COUNT_8, 0, random(FIRE_COOLING * 0.8, FIRE_COOLING * 1.2), random(FIRE_SPARKING * 0.8, FIRE_SPARKING * 1.2));
  199.       TimerFire = (TimerMaster + FIRE_SPEED);
  200.       MainStrip.show();
  201.     }
  202.   }
  203.  
  204.   // Mode 6:  Sparkling blue
  205.   if (ModeCounter == 6)
  206.   {
  207.     MainStrip.setBrightness(BRIGHTNESS_MAX);
  208.  
  209.     if (TimerMaster >= TimerSparkle)
  210.     {
  211.       MainStrip.fill(BRIGHT_BLUE_COLOR);
  212.       MainStrip.setPixelColor(random(MAIN_LEDS_TOTAL), 0xFFFFFF);
  213.       MainStrip.show();
  214.       TimerSparkle = (TimerMaster + SPARKLE_SPEED);
  215.     }
  216.   }
  217.  
  218.   // Mode 7:  Fading red
  219.   if (ModeCounter == 7 )
  220.   {
  221.     MainStrip.fill(BRIGHT_RED_COLOR);
  222.     if (TimerMaster >= TimerFade)
  223.     {
  224.       if (FadeToggle == 0)
  225.       {
  226.         FadeValue++;
  227.         if (FadeValue >= BRIGHTNESS_MAX)
  228.         {
  229.           FadeToggle = 1;
  230.         }
  231.       }
  232.       else
  233.       {
  234.         FadeValue--;
  235.         if (FadeValue <= BRIGHTNESS_MID)
  236.         {
  237.           FadeToggle = 0;
  238.         }
  239.        
  240.       }
  241.       MainStrip.setBrightness(FadeValue);
  242.       MainStrip.show();
  243.       TimerFade = (TimerMaster + FADE_SPEED);
  244.     }
  245.   }
  246.  
  247.   // Mode 8:  Sparkling white & red
  248.   if (ModeCounter == 8 )
  249.   {
  250.     MainStrip.setBrightness(BRIGHTNESS_MID);
  251.  
  252.     if (TimerMaster >= TimerSparkle)
  253.     {
  254.       MainStrip.fill(WHITE_COLOR);
  255.       MainStrip.setPixelColor(random(MAIN_LEDS_TOTAL), BRIGHT_RED_COLOR);
  256.       MainStrip.show();
  257.       TimerSparkle = (TimerMaster + SPARKLE_SPEED);
  258.     }
  259.   }
  260.  
  261.   // Mode 9:  Confetti
  262.   if (ModeCounter == 9 )
  263.   {
  264.     MainStrip.setBrightness(BRIGHTNESS_MAX);
  265.     gPal = RainbowColors_p;
  266.     if (TimerMaster >= TimerConfetti)
  267.     {
  268.       fadeToBlackBy(leds, MAIN_LEDS_TOTAL, CONFETTI_FADE);
  269.       leds[random8(MAIN_LEDS_TOTAL)] = Wheel(random8(255));
  270.       for ( int i = 0; i < MAIN_LEDS_TOTAL; i++)
  271.       {
  272.         MainStrip.setPixelColor(i, leds[i].r, leds[i].g, leds[i].b);
  273.       }
  274.       MainStrip.show();
  275.       TimerConfetti = (TimerMaster + CONFETTI_SPEED);
  276.     }
  277.   }
  278.  
  279. }
  280.  
  281.  
  282.  
  283. void Fire2022(int LED_START_NUM, int FIRE_ROW_LEDS, bool gReverseDirection, int cool, int spark)
  284. {
  285.   // Step 1.  Cool down every cell a little
  286.   for ( int i = LED_START_NUM; i < (FIRE_ROW_LEDS + LED_START_NUM); i++)
  287.   {
  288.     heat[i] = qsub8( heat[i],  random8(0, ((cool * 10) / FIRE_ROW_LEDS) + 2));
  289.   }
  290.  
  291.   // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  292.   for ( int k = (FIRE_ROW_LEDS + LED_START_NUM - 1) ; k >= (LED_START_NUM + 2); k--)
  293.   {
  294.     heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
  295.   }
  296.  
  297.   // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  298.   if ( random8() < spark )
  299.   {
  300.     int y = random8(3);
  301.     //int y = 0;
  302.     heat[LED_START_NUM + y] = qadd8( heat[LED_START_NUM + y], random8(160, 255) );
  303.   }
  304.  
  305.   // Step 4.  Map from heat cells to LED colors
  306.   for ( int j = LED_START_NUM; j < (FIRE_ROW_LEDS + LED_START_NUM); j++)
  307.   {
  308.     // CRGB color = HeatColor(min(150, heat[j]));
  309.     CRGB color = ColorFromPalette(gPal, min(150, heat[j]));
  310.     int pixelnumber;
  311.     if ( gReverseDirection )
  312.     {
  313.       pixelnumber = ((FIRE_ROW_LEDS + LED_START_NUM) - 1) - (j - LED_START_NUM);
  314.     }
  315.     else
  316.     {
  317.       pixelnumber = j;
  318.     }
  319.     MainStrip.setPixelColor(pixelnumber, color.r, color.g, color.b);
  320.   }
  321. }
  322.  
  323. // Input a value 0 to 255 to get a color value.
  324. // The colours are a transition r - g - b - back to r.
  325. uint32_t Wheel(byte WheelPos)
  326. {
  327.   WheelPos = 255 - WheelPos;
  328.   if (WheelPos < 85)
  329.   {
  330.     return MainStrip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  331.   }
  332.   else if (WheelPos < 170)
  333.   {
  334.     WheelPos -= 85;
  335.     return MainStrip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  336.   }
  337.   else
  338.   {
  339.     WheelPos -= 170;
  340.     return MainStrip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  341.   }
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement