Guest User

Untitled

a guest
Apr 8th, 2020
22,389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.14 KB | None | 0 0
  1. // reddit user /u/Procupine 4/7/2019
  2. //the time between transitions is hardcoded (sorry), but the color of the "rain" and speed of the rainbow should be easy to edit
  3. // This code is intended for three rows of LEDs
  4. // I tried my best to comment everything but feel free to pm if you have more questions
  5.  
  6. #include <FastLED.h>
  7.  
  8. #define LED_PIN 5 //digital pin 5
  9. #define NUM_LEDS 579
  10. #define BRIGHTNESS 255
  11. #define LED_TYPE WS2812
  12. #define COLOR_ORDER GRB
  13. CRGB leds[NUM_LEDS];
  14. CRGB colorsArray[NUM_LEDS]; //pregenerated rainbow to make the acutal rainbow less laggy
  15. #define FRAMES_PER_SECOND 50 //it takes ~20ms to push all the data to all 579 LEDs so the hard limit is ~50fps
  16. #define animationLength 15000 //milliseconds
  17. #define rainbowSpeed 100 //bigger = faster rainbow
  18. const int size = NUM_LEDS / 3; //size of the rainbow, divided by 3 for 3 rows of leds
  19. int frequency = 10; //frequency of rain and glitter flashes
  20. int rainColor[3] = {110,20,255}; //make sure each value is at least 1, that's how the program distinguishes between the rain and the rainbow
  21.  
  22.  
  23. void setup() {
  24. delay(50); //because life sucks
  25. FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  26. FastLED.setBrightness( BRIGHTNESS );
  27. //initial bias is arbitary and then normalized to the rainbow size. More bias will make the respective section of the rainbow larger
  28. int BRsize = 90; //section between 100% blue and 100% red
  29. int RGsize = 100; //section between 100% red and 100% green
  30. int GBsize = 80; //section between 100% green and 100% blue
  31. int biasSum = BRsize + RGsize + GBsize;
  32. BRsize = size * (float(BRsize) / float(biasSum)); //normalize bias
  33. RGsize = size * (float(RGsize) / float(biasSum)); //normalize bias
  34. GBsize = size * (float(GBsize) / float(biasSum)); //normalize bias
  35. biasSum = BRsize + RGsize + GBsize;
  36.  
  37. //makes the sum of the bias the same size as the rainbow, fixes "holes" caused by rounding
  38. if (biasSum < size) {
  39. BRsize ++;
  40. biasSum ++;
  41. if (biasSum < size) {
  42. RGsize ++;
  43. biasSum ++;
  44. if (biasSum < size) {
  45. GBsize ++;
  46. biasSum ++;
  47. }
  48. }
  49. }
  50. else if (biasSum > size) {
  51. BRsize --;
  52. biasSum --;
  53. if (biasSum > size) {
  54. RGsize --;
  55. biasSum --;
  56. if (biasSum > size) {
  57. GBsize --;
  58. biasSum --;
  59. }
  60. }
  61. }
  62.  
  63. //generate the rainbow. Uses linear interpolations between points set by the bias
  64. for (int i = 0; i < BRsize; i++) {
  65. colorsArray[i] = CRGB( int(round(255 * float(i) / float(BRsize))) ,
  66. 0 ,
  67. int(round(255 - 255 * float(i) / (BRsize) )));
  68. }
  69. for (int i = 0; i < RGsize; i++) {
  70. colorsArray[i + BRsize] = CRGB(int(round(255 - 255 * float(i) / float(RGsize))) , int(round(255 * (float(i) / float(RGsize)))) , 0 );
  71.  
  72. }
  73. for (int i = 0; i < GBsize; i++) {
  74. colorsArray[i + BRsize + RGsize] = CRGB(0, int(round(255 - 255 * float(i) / float(GBsize))) , int(round(255 * (float(i) / float(GBsize)))));
  75. }
  76.  
  77. //copy first row onto next two rows
  78. for (int i = 0; i < NUM_LEDS / 3; i++) {
  79. colorsArray[i + NUM_LEDS / 3] = colorsArray[i];
  80. colorsArray[i + 2 * NUM_LEDS / 3] = colorsArray[i];
  81. }
  82. }
  83.  
  84. void loop() {
  85. //a timer is used to set a maximum fps
  86. unsigned long start = millis(); //start timer
  87. FastLED.show();
  88.  
  89. if (millis() % animationLength < 5000) {
  90. rain(); //not really rain, just some LEDs that converge to the bottom and fade away
  91. }
  92. else if (millis() % animationLength < 10000) {
  93. glitter(); //randomly lights up LEDs in different colors
  94. }
  95. else {
  96. rainbow(); //generic scrolling rainbow
  97. }
  98.  
  99. unsigned long delta = millis() - start; //end of timer
  100. if ( 1000 / FRAMES_PER_SECOND > delta) { //adds pause to ensure that fps is at or below the defined fps
  101. FastLED.delay(1000 / FRAMES_PER_SECOND - delta);
  102. }
  103. }
  104.  
  105.  
  106. //not really rain, just some LEDs that converge to the bottom and fade away
  107. void rain() {
  108. //generates random LEDs to turn on
  109. frequency = 0.001 * (millis() % animationLength) + 7 ; //how many LEDs per update turn on, starts slow and builds up
  110. int topRow[frequency];
  111. for (int i = 0; i < frequency; i++) {
  112. topRow[i] = random16(2 * NUM_LEDS / 3, NUM_LEDS);
  113. }
  114.  
  115. // fades bottom row
  116. for (int i = 0; i < NUM_LEDS / 3; i++) {
  117. if (leds[i].red + leds[i].green + leds[i].blue != 255) { // make the rainbow now fade initially
  118. leds[i].fadeToBlackBy( 35 );
  119. }
  120. }
  121.  
  122. //turns off middle row and moves LEDs that were on down
  123. for (int i = NUM_LEDS / 3; i < 2 * NUM_LEDS / 3; i++) {
  124. if (i < 2 * NUM_LEDS / 3 && leds[i].red > 0 && leds[i].green > 0 && leds[i].blue > 0) {
  125. leds[i - NUM_LEDS / 3] = CRGB(rainColor[0], rainColor[1], rainColor[2]);
  126. leds[i] = CRGB(0, 0, 0);
  127. }
  128. }
  129.  
  130. //turns off top row, moves LEDs that were on down, turns on new random LEDs
  131. for (int i = 2 * NUM_LEDS / 3; i < NUM_LEDS; i++) { //toprow, turns random LEDs on, turns other LEDs off
  132. //turns off LEDs in the top row that were not just turned on, turns on LEDs in the second row below the LEDs that are being turned off
  133. if (leds[i].red > 0 && leds[i].green > 0 && leds[i].blue > 0) {
  134. leds[i - NUM_LEDS / 3] = CRGB(rainColor[0], rainColor[1], rainColor[2]);
  135. leds[i] = CRGB(0, 0, 0);
  136. }
  137. }
  138. for (int i = 0; i < frequency; i++) {
  139. leds[topRow[i]] = CRGB(rainColor[0], rainColor[1], rainColor[2]);
  140. }
  141. }
  142.  
  143. //randomly lights up LEDs in different colors
  144. void glitter() {
  145. frequency = 2 * pow(float(millis() % animationLength - 5000) / 1000, 4) + 10; //frequency is how much "glitter" there is. Starts out at basically 10 and then grows exponentially (^4)
  146. int ledOffset = millis() * rainbowSpeed / FRAMES_PER_SECOND / 100 % NUM_LEDS ; // 0 - NUM_LEDS, calculates how far the generated table should be offset from the starting position for the given cycle count
  147.  
  148. int lightToTurnOn[frequency]; //randomly generates which LEDs to turn on
  149. for (int i = 0; i < frequency; i++) {
  150. lightToTurnOn[i] = random16(0, NUM_LEDS);
  151. }
  152.  
  153. int fade = 35 - pow((((millis() % animationLength) / 1000) - 5), 1.25); //lights fade less quickly over time to more smoothly transition to the full rainbow
  154. for (int i = 0; i < NUM_LEDS; i++) {
  155. leds[i].fadeToBlackBy(fade);
  156. }
  157.  
  158. for (int i = 0; i < frequency; i++) { //turns on LEDs that were selected
  159. if (random8() + 60 > (millis() % animationLength - 5000) * 0.09 ) { //initial glitter will be rain colored, then quickly become rainbow colored
  160. leds[lightToTurnOn[i]] = CRGB(rainColor[0], rainColor[1], rainColor[2]); //rain colored
  161. }
  162. else {
  163. leds[lightToTurnOn[i]] = colorsArray[(lightToTurnOn[i] + ledOffset) % NUM_LEDS]; //rainbow colored
  164. }
  165. }
  166. }
  167.  
  168. //generic scrolling rainbow
  169. void rainbow() {
  170. int ledOffset = millis() * rainbowSpeed / FRAMES_PER_SECOND / 100 % NUM_LEDS ; // 0 - NUM_LEDS, calculates how far the generated table should be offset from the starting position for the given time
  171.  
  172. //writes the led array based on the pre-generated table
  173. for (int i = 0; i < NUM_LEDS; i++) {
  174. leds[i] = colorsArray[(i + ledOffset) % NUM_LEDS];
  175. }
  176.  
  177. }
Advertisement
Add Comment
Please, Sign In to add comment