atuline

Improved XY()

May 18th, 2021
535
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Improved XY() support of multiple LED layouts for FastLED.
  2.  
  3.   By: Sutaburosu
  4.  
  5.   Testing by: Andrew Tuline
  6.  
  7.   Original code:
  8.  
  9.   https://gist.github.com/sutaburosu/43d46240dc2b05683d1e98872885f8db#file-stream_serial-ino-L34-L55
  10.   https://github.com/sutaburosu/LEDpijp/blob/main/XYmatrix.h#L37-L58 (has a fix)
  11.  
  12.  
  13.   Other references:
  14.  
  15.   https://github.com/marcmerlin/ArduinoOnPc-FastLED-GFX-LEDMatrix
  16.   https://github.com/Jorgen-VikingGod/LEDMatrix
  17.   https://macetech.github.io/FastLED-XY-Map-Generator/
  18.   https://github.com/macetech/FastLED-XY-Map-Generator
  19.  
  20.  
  21.  
  22. // Helper functions for a two-dimensional XY matrix of pixels.
  23. //
  24. //     XY(x,y) takes x and y coordinates and returns an LED index number,
  25. //             for use like this:  leds[ XY(x,y) ] == CRGB::Red;
  26. //
  27. // If pixels are driven horizontally at the same end, like below, it's a (ROWMAJOR) layout:
  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. //
  44. // If pixels are driven horizontally and laid out back and forth, it's a (ROWMAJOR | SERPENTINE) layout:
  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.  
  58.   We have 5 orientation bits. The values are:
  59.  
  60.   XY_LAYOUT = SERPENTINE = 16, ROWMAJOR = 8, TRANSPOSE = 4, FLIPMAJOR = 2, FLIPMINOR = 1
  61.  
  62.   ROWMAJOR   - The x (or Major) value goes horizontal (otherwise vertical).
  63.   SERPENTINE - A serpentine layout (otherwise non-serpentine layout).
  64.   FLIPMAJOR  - Flip the major axis, ie top to bottom (otherwise not).
  65.   FLIPMINOR  - Flip the minor axis, ie left to right (otherwise not).
  66.   TRANSPOSE  - Swap the major and the minor axes (otherwise no swap). Don't use on non-square.
  67.  
  68. */
  69.  
  70.  
  71. // Here's a list of definitons to test. --------------------------------------------------------------------------------
  72.  
  73. #define XY_LAYOUT (ROWMAJOR | SERPENTINE)                // Serpentine with rows at top left. Wokwi standard. Good!
  74. // #define XY_LAYOUT (ROWMAJOR)                             // Non-serpentine with rows at top left. Good!
  75.  
  76. // #define XY_LAYOUT (ROWMAJOR | SERPENTINE | FLIPMAJOR)    // Serpentine, leds[0] is top right. Good!
  77. // #define XY_LAYOUT (ROWMAJOR | FLIPMAJOR)                 // Non-serpentine, leds[0] is top right. Good!
  78.  
  79. // #define XY_LAYOUT (ROWMAJOR | SERPENTINE | FLIPMINOR)    // Serpentine, leds[0] is bottom right. Good!
  80. // #define XY_LAYOUT (ROWMAJOR | FLIPMINOR)                 // Non-serpentine, leds[0] is bottom right. Good!
  81.  
  82. //#define XY_LAYOUT (ROWMAJOR | SERPENTINE | FLIPMAJOR | FLIPMINOR)    // Serpentine, leds[0] is bottom left. Good!
  83. //#define XY_LAYOUT (ROWMAJOR | FLIPMAJOR | FLIPMINOR)                 // Non-serpentine, leds[0] is bottom left. Good!
  84.  
  85. // #define XY_LAYOUT 0                                      // NOT ROWMAJOR and NOT SERPENTINE. Good!
  86. // #define XY_LAYOUT SERPENTINE                             // Not ROWMAJOR. Good!
  87. // Rest are untested.
  88.  
  89. // Have NOT tested when TRANSPOSE is set.                   // We'll get there.
  90.  
  91.  
  92.  
  93. #include <FastLED.h>
  94.  
  95. #define LED_PIN  12
  96.  
  97. const uint8_t matrixWidth = 16;
  98. const uint8_t matrixHeight = 16;
  99. #define NUM_LEDS matrixWidth * matrixHeight
  100.  
  101. CRGB leds[NUM_LEDS+1];                       // The +1 is for the out of bounds LED for any out of bound coordinates.
  102.  
  103. //const bool    matrixSerpentineLayout = true;
  104.  
  105.  
  106. enum XY_Layout {
  107.   SERPENTINE = 16, ROWMAJOR = 8, TRANSPOSE = 4, FLIPMAJOR = 2, FLIPMINOR = 1
  108. };
  109.  
  110.  
  111. void setup() {
  112.   Serial.begin(115200);
  113.   FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  114.   FastLED.setBrightness(64);
  115.   dolights();
  116. }
  117.  
  118.  
  119. void loop() {
  120. }
  121.  
  122. void dolights() {
  123.  
  124. // Raw LED writing to confirm physical layout.
  125.  /*   leds[0] = CRGB::Red;
  126.     leds[1] = CRGB::Green;
  127.     leds[2] = CRGB::Blue;
  128.     leds[31] = CRGB::Orange;
  129. */
  130.  
  131. // Layout based led's.
  132.   leds[XY(0, 0)] = CRGB::Red;
  133.   leds[XY(1, 0)] = CRGB::Green;
  134.   leds[XY(2, 0)] = CRGB::Blue;
  135.   leds[XY(0, 1)] = CRGB::Orange;
  136.  
  137.   FastLED.show();
  138. }
  139.  
  140.  
  141. // Advanced XY layout supports multiple orientations.
  142.  
  143. uint16_t XY(uint8_t x, uint8_t y) {                 // By: Sutaburosu
  144.   uint8_t major, minor, sz_major, sz_minor;
  145.   if (x >= matrixWidth || y >= matrixHeight)
  146.     return NUM_LEDS;
  147.   if (XY_LAYOUT & ROWMAJOR)
  148.     major = x, minor = y, sz_major = matrixWidth,  sz_minor = matrixHeight;
  149.   else
  150.     major = y, minor = x, sz_major = matrixHeight, sz_minor = matrixWidth;
  151.   if (((XY_LAYOUT & FLIPMAJOR) != 0) ^ (((minor & 1) != 0) && ((XY_LAYOUT & SERPENTINE) != 0)))    // A line of magic.
  152.     major = sz_major - 1 - major;
  153.   if (XY_LAYOUT & FLIPMINOR)
  154.     minor = sz_minor - 1 - minor;
  155.   if (XY_LAYOUT & TRANSPOSE)
  156.     return major * (uint16_t) sz_major + minor;
  157.   else
  158.     return minor * (uint16_t) sz_major + major;
  159. } // XY()
RAW Paste Data