FastLED 3.10.6
Loading...
Searching...
No Matches
XYMatrix.ino
Go to the documentation of this file.
1
4
5// @filter: (board is not ATtiny1604)
6
7#include <FastLED.h>
8
9#define LED_PIN 3
10
11#define COLOR_ORDER GRB
12#define CHIPSET WS2811
13
14#define BRIGHTNESS 64
15
16// Helper functions for an two-dimensional XY matrix of pixels.
17// Simple 2-D demo code is included as well.
18//
19// XY(x,y) takes x and y coordinates and returns an LED index number,
20// for use like this: leds[ XY(x,y) ] == CRGB::Red;
21// No error checking is performed on the ranges of x and y.
22//
23// XYsafe(x,y) takes x and y coordinates and returns an LED index number,
24// for use like this: leds[ XYsafe(x,y) ] == CRGB::Red;
25// Error checking IS performed on the ranges of x and y, and an
26// index of "-1" is returned. Special instructions below
27// explain how to use this without having to do your own error
28// checking every time you use this function.
29// This is a slightly more advanced technique, and
30// it REQUIRES SPECIAL ADDITIONAL setup, described below.
31
32
33// Params for width and height
34#if FL_PLATFORM_HAS_TINY_MEMORY
35// A 16x16 CRGB matrix uses 768 B before controller state and stack.
36const uint8_t kMatrixWidth = 4;
37const uint8_t kMatrixHeight = 4;
38#else
41#endif
42
43// Param for different pixel layouts
44const bool kMatrixSerpentineLayout = true;
45const bool kMatrixVertical = false;
46
47// Set 'kMatrixSerpentineLayout' to false if your pixels are
48// laid out all running the same way, like this:
49//
50// 0 > 1 > 2 > 3 > 4
51// |
52// .----<----<----<----'
53// |
54// 5 > 6 > 7 > 8 > 9
55// |
56// .----<----<----<----'
57// |
58// 10 > 11 > 12 > 13 > 14
59// |
60// .----<----<----<----'
61// |
62// 15 > 16 > 17 > 18 > 19
63//
64// Set 'kMatrixSerpentineLayout' to true if your pixels are
65// laid out back-and-forth, like this:
66//
67// 0 > 1 > 2 > 3 > 4
68// |
69// |
70// 9 < 8 < 7 < 6 < 5
71// |
72// |
73// 10 > 11 > 12 > 13 > 14
74// |
75// |
76// 19 < 18 < 17 < 16 < 15
77//
78// Bonus vocabulary word: anything that goes one way
79// in one row, and then backwards in the next row, and so on
80// is call "boustrophedon", meaning "as the ox plows."
81
82
83// This function will return the right 'led index number' for
84// a given set of X and Y coordinates on your matrix.
85// IT DOES NOT CHECK THE COORDINATE BOUNDARIES.
86// That's up to you. Don't pass it bogus values.
87//
88// Use the "XY" function like this:
89//
90// for( uint8_t x = 0; x < kMatrixWidth; x++) {
91// for( uint8_t y = 0; y < kMatrixHeight; y++) {
92//
93// // Here's the x, y to 'led index' in action:
94// leds[ XY( x, y) ] = CHSV( random8(), 255, 255);
95//
96// }
97// }
98//
99//
101{
102 uint16_t i;
103
104 if( kMatrixSerpentineLayout == false) {
105 if (kMatrixVertical == false) {
106 i = (y * kMatrixWidth) + x;
107 } else {
108 i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
109 }
110 }
111
112 if( kMatrixSerpentineLayout == true) {
113 if (kMatrixVertical == false) {
114 if( y & 0x01) {
115 // Odd rows run backwards
116 uint8_t reverseX = (kMatrixWidth - 1) - x;
117 i = (y * kMatrixWidth) + reverseX;
118 } else {
119 // Even rows run forwards
120 i = (y * kMatrixWidth) + x;
121 }
122 } else { // vertical positioning
123 if ( x & 0x01) {
124 i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
125 } else {
126 i = kMatrixHeight * (kMatrixWidth - x) - (y+1);
127 }
128 }
129 }
130
131 return i;
132}
133
134
135// Once you've gotten the basics working (AND NOT UNTIL THEN!)
136// here's a helpful technique that can be tricky to set up, but
137// then helps you avoid the needs for sprinkling array-bound-checking
138// throughout your code.
139//
140// It requires a careful attention to get it set up correctly, but
141// can potentially make your code smaller and faster.
142//
143// Suppose you have an 8 x 5 matrix of 40 LEDs. Normally, you'd
144// delcare your leds array like this:
145// CRGB leds[40];
146// But instead of that, declare an LED buffer with one extra pixel in
147// it, "leds_plus_safety_pixel". Then declare "leds" as a pointer to
148// that array, but starting with the 2nd element (id=1) of that array:
149// CRGB leds_with_safety_pixel[41];
150// CRGB* const leds( leds_plus_safety_pixel + 1);
151// Then you use the "leds" array as you normally would.
152// Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]",
153// AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0].
154// leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel".
155//
156// Now instead of using the XY function above, use the one below, "XYsafe".
157//
158// If the X and Y values are 'in bounds', this function will return an index
159// into the visible led array, same as "XY" does.
160// HOWEVER -- and this is the trick -- if the X or Y values
161// are out of bounds, this function will return an index of -1.
162// And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0],
163// it's a totally safe and legal place to access. And since the 'safety pixel'
164// falls 'outside' the visible part of the LED array, anything you write
165// there is hidden from view automatically.
166// Thus, this line of code is totally safe, regardless of the actual size of
167// your matrix:
168// leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255);
169//
170// The only catch here is that while this makes it safe to read from and
171// write to 'any pixel', there's really only ONE 'safety pixel'. No matter
172// what out-of-bounds coordinates you write to, you'll really be writing to
173// that one safety pixel. And if you try to READ from the safety pixel,
174// you'll read whatever was written there last, reglardless of what coordinates
175// were supplied.
176
177#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
180
181// NOTE: the return type must be SIGNED. Returning -1 from a uint16_t makes the
182// value 65535, which only behaves like -1 where int is 16 bits wide (AVR). On a
183// 32-bit board it promotes to the int 65535, so leds[XYsafe(...)] indexes far
184// past the array instead of landing on the safety pixel.
185//
186// `int` rather than `int16_t` so that on 32-bit boards the type stays wide
187// enough for any matrix a board that size can actually hold.
189{
190 if( x >= kMatrixWidth) return -1;
191 if( y >= kMatrixHeight) return -1;
192 return XY(x,y);
193}
194
195
196void DrawOneFrame( uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
197{
198 uint8_t lineStartHue = startHue8;
199 for( uint8_t y = 0; y < kMatrixHeight; y++) {
200 lineStartHue += yHueDelta8;
201 uint8_t pixelHue = lineStartHue;
202 for( uint8_t x = 0; x < kMatrixWidth; x++) {
203 pixelHue += xHueDelta8;
204 leds[ XY(x, y)] = CHSV( pixelHue, 255, 255);
205 }
206 }
207}
208
209
210void setup() {
211 FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
212 FastLED.setBrightness( BRIGHTNESS );
213}
214
215
216// Demo that USES "XY" follows code below
217
218void loop()
219{
220 uint32_t ms = millis();
221 int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));
222 int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));
223 DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
224 if( ms < 5000 ) {
225 FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
226 } else {
227 FastLED.setBrightness(BRIGHTNESS);
228 }
229 FastLED.show();
230}
231
CRGB leds[1]
void setup()
void loop()
#define COLOR_ORDER
#define NUM_LEDS
#define LED_PIN
#define BRIGHTNESS
int y
Definition simple.h:93
int x
Definition simple.h:92
#define CHIPSET
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
#define kMatrixSerpentineLayout
#define kMatrixHeight
#define kMatrixWidth
const bool kMatrixVertical
Definition XYMatrix.ino:45
void DrawOneFrame(uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
Definition XYMatrix.ino:196
int XYsafe(uint8_t x, uint8_t y)
Definition XYMatrix.ino:188
CRGB leds_plus_safety_pixel[NUM_LEDS+1]
Definition XYMatrix.ino:178
FL_OPTIMIZATION_LEVEL_O3_BEGIN fl::u16 XY(fl::u8 x, fl::u8 y) FL_LINK_WEAK
Definition blur.cpp.hpp:35
@ TypicalSMD5050
Typical values for SMD5050 LEDs.
Definition color.h:13
fl::hsv8 CHSV
Definition chsv.h:11
fl::CRGB CRGB
Definition crgb.h:25
unsigned char uint8_t
Definition stdint.h:208
fl::u32 uint32_t
Definition stdint.h:218
signed char int8_t
Definition stdint.h:209
fl::i32 int32_t
Definition stdint.h:219
fl::u16 uint16_t
Definition stdint.h:213