PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

274 lines
9.2KB

  1. #include <FastLED.h>
  2. #define LED_PIN 3
  3. #define BRIGHTNESS 96
  4. #define LED_TYPE WS2811
  5. #define COLOR_ORDER GRB
  6. const uint8_t kMatrixWidth = 16;
  7. const uint8_t kMatrixHeight = 16;
  8. const bool kMatrixSerpentineLayout = true;
  9. // This example combines two features of FastLED to produce a remarkable range of
  10. // effects from a relatively small amount of code. This example combines FastLED's
  11. // color palette lookup functions with FastLED's Perlin/simplex noise generator, and
  12. // the combination is extremely powerful.
  13. //
  14. // You might want to look at the "ColorPalette" and "Noise" examples separately
  15. // if this example code seems daunting.
  16. //
  17. //
  18. // The basic setup here is that for each frame, we generate a new array of
  19. // 'noise' data, and then map it onto the LED matrix through a color palette.
  20. //
  21. // Periodically, the color palette is changed, and new noise-generation parameters
  22. // are chosen at the same time. In this example, specific noise-generation
  23. // values have been selected to match the given color palettes; some are faster,
  24. // or slower, or larger, or smaller than others, but there's no reason these
  25. // parameters can't be freely mixed-and-matched.
  26. //
  27. // In addition, this example includes some fast automatic 'data smoothing' at
  28. // lower noise speeds to help produce smoother animations in those cases.
  29. //
  30. // The FastLED built-in color palettes (Forest, Clouds, Lava, Ocean, Party) are
  31. // used, as well as some 'hand-defined' ones, and some proceedurally generated
  32. // palettes.
  33. #define NUM_LEDS (kMatrixWidth * kMatrixHeight)
  34. #define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight)
  35. // The leds
  36. CRGB leds[kMatrixWidth * kMatrixHeight];
  37. // The 16 bit version of our coordinates
  38. static uint16_t x;
  39. static uint16_t y;
  40. static uint16_t z;
  41. // We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll
  42. // use the z-axis for "time". speed determines how fast time moves forward. Try
  43. // 1 for a very slow moving effect, or 60 for something that ends up looking like
  44. // water.
  45. uint16_t speed = 20; // speed is set dynamically once we've started up
  46. // Scale determines how far apart the pixels in our noise matrix are. Try
  47. // changing these values around to see how it affects the motion of the display. The
  48. // higher the value of scale, the more "zoomed out" the noise iwll be. A value
  49. // of 1 will be so zoomed in, you'll mostly see solid colors.
  50. uint16_t scale = 30; // scale is set dynamically once we've started up
  51. // This is the array that we keep our computed noise values in
  52. uint8_t noise[MAX_DIMENSION][MAX_DIMENSION];
  53. CRGBPalette16 currentPalette( PartyColors_p );
  54. uint8_t colorLoop = 1;
  55. void setup() {
  56. delay(3000);
  57. LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS);
  58. LEDS.setBrightness(BRIGHTNESS);
  59. // Initialize our coordinates to some random values
  60. x = random16();
  61. y = random16();
  62. z = random16();
  63. }
  64. // Fill the x/y array of 8-bit noise values using the inoise8 function.
  65. void fillnoise8() {
  66. // If we're runing at a low "speed", some 8-bit artifacts become visible
  67. // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing.
  68. // The amount of data smoothing we're doing depends on "speed".
  69. uint8_t dataSmoothing = 0;
  70. if( speed < 50) {
  71. dataSmoothing = 200 - (speed * 4);
  72. }
  73. for(int i = 0; i < MAX_DIMENSION; i++) {
  74. int ioffset = scale * i;
  75. for(int j = 0; j < MAX_DIMENSION; j++) {
  76. int joffset = scale * j;
  77. uint8_t data = inoise8(x + ioffset,y + joffset,z);
  78. // The range of the inoise8 function is roughly 16-238.
  79. // These two operations expand those values out to roughly 0..255
  80. // You can comment them out if you want the raw noise data.
  81. data = qsub8(data,16);
  82. data = qadd8(data,scale8(data,39));
  83. if( dataSmoothing ) {
  84. uint8_t olddata = noise[i][j];
  85. uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing);
  86. data = newdata;
  87. }
  88. noise[i][j] = data;
  89. }
  90. }
  91. z += speed;
  92. // apply slow drift to X and Y, just for visual variation.
  93. x += speed / 8;
  94. y -= speed / 16;
  95. }
  96. void mapNoiseToLEDsUsingPalette()
  97. {
  98. static uint8_t ihue=0;
  99. for(int i = 0; i < kMatrixWidth; i++) {
  100. for(int j = 0; j < kMatrixHeight; j++) {
  101. // We use the value at the (i,j) coordinate in the noise
  102. // array for our brightness, and the flipped value from (j,i)
  103. // for our pixel's index into the color palette.
  104. uint8_t index = noise[j][i];
  105. uint8_t bri = noise[i][j];
  106. // if this palette is a 'loop', add a slowly-changing base value
  107. if( colorLoop) {
  108. index += ihue;
  109. }
  110. // brighten up, as the color palette itself often contains the
  111. // light/dark dynamic range desired
  112. if( bri > 127 ) {
  113. bri = 255;
  114. } else {
  115. bri = dim8_raw( bri * 2);
  116. }
  117. CRGB color = ColorFromPalette( currentPalette, index, bri);
  118. leds[XY(i,j)] = color;
  119. }
  120. }
  121. ihue+=1;
  122. }
  123. void loop() {
  124. // Periodically choose a new palette, speed, and scale
  125. ChangePaletteAndSettingsPeriodically();
  126. // generate noise data
  127. fillnoise8();
  128. // convert the noise data to colors in the LED array
  129. // using the current palette
  130. mapNoiseToLEDsUsingPalette();
  131. LEDS.show();
  132. // delay(10);
  133. }
  134. // There are several different palettes of colors demonstrated here.
  135. //
  136. // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
  137. // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
  138. //
  139. // Additionally, you can manually define your own color palettes, or you can write
  140. // code that creates color palettes on the fly.
  141. // 1 = 5 sec per palette
  142. // 2 = 10 sec per palette
  143. // etc
  144. #define HOLD_PALETTES_X_TIMES_AS_LONG 1
  145. void ChangePaletteAndSettingsPeriodically()
  146. {
  147. uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60;
  148. static uint8_t lastSecond = 99;
  149. if( lastSecond != secondHand) {
  150. lastSecond = secondHand;
  151. if( secondHand == 0) { currentPalette = RainbowColors_p; speed = 20; scale = 30; colorLoop = 1; }
  152. if( secondHand == 5) { SetupPurpleAndGreenPalette(); speed = 10; scale = 50; colorLoop = 1; }
  153. if( secondHand == 10) { SetupBlackAndWhiteStripedPalette(); speed = 20; scale = 30; colorLoop = 1; }
  154. if( secondHand == 15) { currentPalette = ForestColors_p; speed = 8; scale =120; colorLoop = 0; }
  155. if( secondHand == 20) { currentPalette = CloudColors_p; speed = 4; scale = 30; colorLoop = 0; }
  156. if( secondHand == 25) { currentPalette = LavaColors_p; speed = 8; scale = 50; colorLoop = 0; }
  157. if( secondHand == 30) { currentPalette = OceanColors_p; speed = 20; scale = 90; colorLoop = 0; }
  158. if( secondHand == 35) { currentPalette = PartyColors_p; speed = 20; scale = 30; colorLoop = 1; }
  159. if( secondHand == 40) { SetupRandomPalette(); speed = 20; scale = 20; colorLoop = 1; }
  160. if( secondHand == 45) { SetupRandomPalette(); speed = 50; scale = 50; colorLoop = 1; }
  161. if( secondHand == 50) { SetupRandomPalette(); speed = 90; scale = 90; colorLoop = 1; }
  162. if( secondHand == 55) { currentPalette = RainbowStripeColors_p; speed = 30; scale = 20; colorLoop = 1; }
  163. }
  164. }
  165. // This function generates a random palette that's a gradient
  166. // between four different colors. The first is a dim hue, the second is
  167. // a bright hue, the third is a bright pastel, and the last is
  168. // another bright hue. This gives some visual bright/dark variation
  169. // which is more interesting than just a gradient of different hues.
  170. void SetupRandomPalette()
  171. {
  172. currentPalette = CRGBPalette16(
  173. CHSV( random8(), 255, 32),
  174. CHSV( random8(), 255, 255),
  175. CHSV( random8(), 128, 255),
  176. CHSV( random8(), 255, 255));
  177. }
  178. // This function sets up a palette of black and white stripes,
  179. // using code. Since the palette is effectively an array of
  180. // sixteen CRGB colors, the various fill_* functions can be used
  181. // to set them up.
  182. void SetupBlackAndWhiteStripedPalette()
  183. {
  184. // 'black out' all 16 palette entries...
  185. fill_solid( currentPalette, 16, CRGB::Black);
  186. // and set every fourth one to white.
  187. currentPalette[0] = CRGB::White;
  188. currentPalette[4] = CRGB::White;
  189. currentPalette[8] = CRGB::White;
  190. currentPalette[12] = CRGB::White;
  191. }
  192. // This function sets up a palette of purple and green stripes.
  193. void SetupPurpleAndGreenPalette()
  194. {
  195. CRGB purple = CHSV( HUE_PURPLE, 255, 255);
  196. CRGB green = CHSV( HUE_GREEN, 255, 255);
  197. CRGB black = CRGB::Black;
  198. currentPalette = CRGBPalette16(
  199. green, green, black, black,
  200. purple, purple, black, black,
  201. green, green, black, black,
  202. purple, purple, black, black );
  203. }
  204. //
  205. // Mark's xy coordinate mapping code. See the XYMatrix for more information on it.
  206. //
  207. uint16_t XY( uint8_t x, uint8_t y)
  208. {
  209. uint16_t i;
  210. if( kMatrixSerpentineLayout == false) {
  211. i = (y * kMatrixWidth) + x;
  212. }
  213. if( kMatrixSerpentineLayout == true) {
  214. if( y & 0x01) {
  215. // Odd rows run backwards
  216. uint8_t reverseX = (kMatrixWidth - 1) - x;
  217. i = (y * kMatrixWidth) + reverseX;
  218. } else {
  219. // Even rows run forwards
  220. i = (y * kMatrixWidth) + x;
  221. }
  222. }
  223. return i;
  224. }