PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include <FastLED.h>
  2. #define LED_PIN 3
  3. #define COLOR_ORDER GRB
  4. #define CHIPSET WS2811
  5. #define BRIGHTNESS 64
  6. // Helper functions for an two-dimensional XY matrix of pixels.
  7. // Simple 2-D demo code is included as well.
  8. //
  9. // XY(x,y) takes x and y coordinates and returns an LED index number,
  10. // for use like this: leds[ XY(x,y) ] == CRGB::Red;
  11. // No error checking is performed on the ranges of x and y.
  12. //
  13. // XYsafe(x,y) takes x and y coordinates and returns an LED index number,
  14. // for use like this: leds[ XY(x,y) ] == CRGB::Red;
  15. // Error checking IS performed on the ranges of x and y, and an
  16. // index of "-1" is returned. Special instructions below
  17. // explain how to use this without having to do your own error
  18. // checking every time you use this function.
  19. // This is a slightly more advanced technique, and
  20. // it REQUIRES SPECIAL ADDITIONAL setup, described below.
  21. // Params for width and height
  22. const uint8_t kMatrixWidth = 16;
  23. const uint8_t kMatrixHeight = 16;
  24. // Param for different pixel layouts
  25. const bool kMatrixSerpentineLayout = true;
  26. // Set 'kMatrixSerpentineLayout' to false if your pixels are
  27. // laid out all running the same way, like this:
  28. //
  29. // 0 > 1 > 2 > 3 > 4
  30. // |
  31. // .----<----<----<----'
  32. // |
  33. // 5 > 6 > 7 > 8 > 9
  34. // |
  35. // .----<----<----<----'
  36. // |
  37. // 10 > 11 > 12 > 13 > 14
  38. // |
  39. // .----<----<----<----'
  40. // |
  41. // 15 > 16 > 17 > 18 > 19
  42. //
  43. // Set 'kMatrixSerpentineLayout' to true if your pixels are
  44. // laid out back-and-forth, like this:
  45. //
  46. // 0 > 1 > 2 > 3 > 4
  47. // |
  48. // |
  49. // 9 < 8 < 7 < 6 < 5
  50. // |
  51. // |
  52. // 10 > 11 > 12 > 13 > 14
  53. // |
  54. // |
  55. // 19 < 18 < 17 < 16 < 15
  56. //
  57. // Bonus vocabulary word: anything that goes one way
  58. // in one row, and then backwards in the next row, and so on
  59. // is call "boustrophedon", meaning "as the ox plows."
  60. // This function will return the right 'led index number' for
  61. // a given set of X and Y coordinates on your matrix.
  62. // IT DOES NOT CHECK THE COORDINATE BOUNDARIES.
  63. // That's up to you. Don't pass it bogus values.
  64. //
  65. // Use the "XY" function like this:
  66. //
  67. // for( uint8_t x = 0; x < kMatrixWidth; x++) {
  68. // for( uint8_t y = 0; y < kMatrixHeight; y++) {
  69. //
  70. // // Here's the x, y to 'led index' in action:
  71. // leds[ XY( x, y) ] = CHSV( random8(), 255, 255);
  72. //
  73. // }
  74. // }
  75. //
  76. //
  77. uint16_t XY( uint8_t x, uint8_t y)
  78. {
  79. uint16_t i;
  80. if( kMatrixSerpentineLayout == false) {
  81. i = (y * kMatrixWidth) + x;
  82. }
  83. if( kMatrixSerpentineLayout == true) {
  84. if( y & 0x01) {
  85. // Odd rows run backwards
  86. uint8_t reverseX = (kMatrixWidth - 1) - x;
  87. i = (y * kMatrixWidth) + reverseX;
  88. } else {
  89. // Even rows run forwards
  90. i = (y * kMatrixWidth) + x;
  91. }
  92. }
  93. return i;
  94. }
  95. // Once you've gotten the basics working (AND NOT UNTIL THEN!)
  96. // here's a helpful technique that can be tricky to set up, but
  97. // then helps you avoid the needs for sprinkling array-bound-checking
  98. // throughout your code.
  99. //
  100. // It requires a careful attention to get it set up correctly, but
  101. // can potentially make your code smaller and faster.
  102. //
  103. // Suppose you have an 8 x 5 matrix of 40 LEDs. Normally, you'd
  104. // delcare your leds array like this:
  105. // CRGB leds[40];
  106. // But instead of that, declare an LED buffer with one extra pixel in
  107. // it, "leds_plus_safety_pixel". Then declare "leds" as a pointer to
  108. // that array, but starting with the 2nd element (id=1) of that array:
  109. // CRGB leds_with_safety_pixel[41];
  110. // CRGB* const leds( leds_plus_safety_pixel + 1);
  111. // Then you use the "leds" array as you normally would.
  112. // Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]",
  113. // AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0].
  114. // leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel".
  115. //
  116. // Now instead of using the XY function above, use the one below, "XYsafe".
  117. //
  118. // If the X and Y values are 'in bounds', this function will return an index
  119. // into the visible led array, same as "XY" does.
  120. // HOWEVER -- and this is the trick -- if the X or Y values
  121. // are out of bounds, this function will return an index of -1.
  122. // And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0],
  123. // it's a totally safe and legal place to access. And since the 'safety pixel'
  124. // falls 'outside' the visible part of the LED array, anything you write
  125. // there is hidden from view automatically.
  126. // Thus, this line of code is totally safe, regardless of the actual size of
  127. // your matrix:
  128. // leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255);
  129. //
  130. // The only catch here is that while this makes it safe to read from and
  131. // write to 'any pixel', there's really only ONE 'safety pixel'. No matter
  132. // what out-of-bounds coordinates you write to, you'll really be writing to
  133. // that one safety pixel. And if you try to READ from the safety pixel,
  134. // you'll read whatever was written there last, reglardless of what coordinates
  135. // were supplied.
  136. #define NUM_LEDS (kMatrixWidth * kMatrixHeight)
  137. CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
  138. CRGB* const leds( leds_plus_safety_pixel + 1);
  139. uint16_t XYsafe( uint8_t x, uint8_t y)
  140. {
  141. if( x >= kMatrixWidth) return -1;
  142. if( y >= kMatrixHeight) return -1;
  143. return XY(x,y);
  144. }
  145. // Demo that USES "XY" follows code below
  146. void loop()
  147. {
  148. uint32_t ms = millis();
  149. int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));
  150. int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));
  151. DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
  152. if( ms < 5000 ) {
  153. FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
  154. } else {
  155. FastLED.setBrightness(BRIGHTNESS);
  156. }
  157. FastLED.show();
  158. }
  159. void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
  160. {
  161. byte lineStartHue = startHue8;
  162. for( byte y = 0; y < kMatrixHeight; y++) {
  163. lineStartHue += yHueDelta8;
  164. byte pixelHue = lineStartHue;
  165. for( byte x = 0; x < kMatrixWidth; x++) {
  166. pixelHue += xHueDelta8;
  167. leds[ XY(x, y)] = CHSV( pixelHue, 255, 255);
  168. }
  169. }
  170. }
  171. void setup() {
  172. FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  173. FastLED.setBrightness( BRIGHTNESS );
  174. }