├── Commands.h
├── GradientPalettes.h
├── LICENSE
├── Life.h
├── Noise.h
├── README.md
├── Twinkles.h
└── fibonacci-v3d.ino
/Commands.h:
--------------------------------------------------------------------------------
1 | /*
2 | Fibonacci v3D: https://github.com/evilgeniuslabs/fibonacci-v3d
3 | Copyright (C) 2014-2016 Jason Coon, Evil Genius Labs
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef IrCodes_H
20 | #define IrCodes_H
21 |
22 | enum class InputCommand {
23 | None,
24 | Up,
25 | Down,
26 | Left,
27 | Right,
28 | Select,
29 | Brightness,
30 | PlayMode,
31 | Palette,
32 | Power,
33 | BrightnessUp,
34 | BrightnessDown,
35 |
36 | Pattern1,
37 | Pattern2,
38 | Pattern3,
39 | Pattern4,
40 | Pattern5,
41 | Pattern6,
42 | Pattern7,
43 | Pattern8,
44 | Pattern9,
45 | Pattern10,
46 | Pattern11,
47 | Pattern12,
48 |
49 | RedUp,
50 | RedDown,
51 | GreenUp,
52 | GreenDown,
53 | BlueUp,
54 | BlueDown,
55 |
56 | Red,
57 | RedOrange,
58 | Orange,
59 | YellowOrange,
60 | Yellow,
61 |
62 | Green,
63 | Lime,
64 | Aqua,
65 | Teal,
66 | Navy,
67 |
68 | Blue,
69 | RoyalBlue,
70 | Purple,
71 | Indigo,
72 | Magenta,
73 |
74 | White,
75 | Pink,
76 | LightPink,
77 | BabyBlue,
78 | LightBlue,
79 | };
80 |
81 | // IR Raw Key Codes for SparkFun remote
82 | #define IRCODE_SPARKFUN_POWER 0x10EFD827 // 284153895
83 | #define IRCODE_SPARKFUN_A 0x10EFF807 //
84 | #define IRCODE_SPARKFUN_B 0x10EF7887
85 | #define IRCODE_SPARKFUN_C 0x10EF58A7
86 | #define IRCODE_SPARKFUN_UP 0x10EFA05F // 284139615
87 | #define IRCODE_SPARKFUN_LEFT 0x10EF10EF
88 | #define IRCODE_SPARKFUN_SELECT 0x10EF20DF
89 | #define IRCODE_SPARKFUN_RIGHT 0x10EF807F
90 | #define IRCODE_SPARKFUN_DOWN 0x10EF00FF
91 | #define IRCODE_SPARKFUN_HELD 0xFFFFFFFF
92 |
93 | // IR Raw Key Codes for Adafruit remote
94 | #define IRCODE_ADAFRUIT_HELD 0x7FFFFFFF // 4294967295
95 | #define IRCODE_ADAFRUIT_VOLUME_UP 0x00FD40BF // 16597183
96 | #define IRCODE_ADAFRUIT_PLAY_PAUSE 0x00FD807F // 16613503
97 | #define IRCODE_ADAFRUIT_VOLUME_DOWN 0x00FD00FF // 16580863
98 | #define IRCODE_ADAFRUIT_SETUP 0x00FD20DF // 16589023
99 | #define IRCODE_ADAFRUIT_UP 0x00FDA05F // 16621663
100 | #define IRCODE_ADAFRUIT_STOP_MODE 0x00FD609F // 16605343
101 | #define IRCODE_ADAFRUIT_LEFT 0x00FD10EF // 16584943
102 | #define IRCODE_ADAFRUIT_ENTER_SAVE 0x00FD906F // 16617583
103 | #define IRCODE_ADAFRUIT_RIGHT 0x00FD50AF // 16601263
104 | #define IRCODE_ADAFRUIT_0_10_PLUS 0x00FD30CF // 16593103
105 | #define IRCODE_ADAFRUIT_DOWN 0x00FDB04F // 16625743
106 | #define IRCODE_ADAFRUIT_BACK 0x00FD708F // 16609423
107 | #define IRCODE_ADAFRUIT_1 0x00FD08F7 // 16582903
108 | #define IRCODE_ADAFRUIT_2 0x00FD8877 // 16615543
109 | #define IRCODE_ADAFRUIT_3 0x00FD48B7 // 16599223
110 | #define IRCODE_ADAFRUIT_4 0x00FD28D7 // 16591063
111 | #define IRCODE_ADAFRUIT_5 0x00FDA857 // 16623703
112 | #define IRCODE_ADAFRUIT_6 0x00FD6897 // 16607383
113 | #define IRCODE_ADAFRUIT_7 0x00FD18E7 // 16586983
114 | #define IRCODE_ADAFRUIT_8 0x00FD9867 // 16619623
115 | #define IRCODE_ADAFRUIT_9 0x00FD58A7 // 16603303
116 |
117 | // IR Raw Key Codes for eTopxizu 44Key IR Remote Controller for 5050 3528 RGB LED Light Strip
118 | #define IRCODE_ETOPXIZU_HELD 0x7FFFFFFF // 4294967295
119 | #define IRCODE_ETOPXIZU_POWER 16712445
120 | #define IRCODE_ETOPXIZU_PLAY_PAUSE 16745085
121 | #define IRCODE_ETOPXIZU_BRIGHTNESS_UP 16726725
122 | #define IRCODE_ETOPXIZU_BRIGHTNESS_DOWN 16759365
123 |
124 | #define IRCODE_ETOPXIZU_DIY1 16724175
125 | #define IRCODE_ETOPXIZU_DIY2 16756815
126 | #define IRCODE_ETOPXIZU_DIY3 16740495
127 | #define IRCODE_ETOPXIZU_DIY4 16716015
128 | #define IRCODE_ETOPXIZU_DIY5 16748655
129 | #define IRCODE_ETOPXIZU_DIY6 16732335
130 |
131 | #define IRCODE_ETOPXIZU_JUMP3 16720095
132 | #define IRCODE_ETOPXIZU_JUMP7 16752735
133 | #define IRCODE_ETOPXIZU_FADE3 16736415
134 | #define IRCODE_ETOPXIZU_FADE7 16769055
135 | #define IRCODE_ETOPXIZU_FLASH 16764975
136 | #define IRCODE_ETOPXIZU_AUTO 16773135
137 |
138 | #define IRCODE_ETOPXIZU_QUICK 16771095
139 | #define IRCODE_ETOPXIZU_SLOW 16762935
140 |
141 | #define IRCODE_ETOPXIZU_RED_UP 16722135
142 | #define IRCODE_ETOPXIZU_RED_DOWN 16713975
143 |
144 | #define IRCODE_ETOPXIZU_GREEN_UP 16754775
145 | #define IRCODE_ETOPXIZU_GREEN_DOWN 16746615
146 |
147 | #define IRCODE_ETOPXIZU_BLUE_UP 16738455
148 | #define IRCODE_ETOPXIZU_BLUE_DOWN 16730295
149 |
150 | #define IRCODE_ETOPXIZU_RED 16718565
151 | #define IRCODE_ETOPXIZU_RED_ORANGE 16722645
152 | #define IRCODE_ETOPXIZU_ORANGE 16714485
153 | #define IRCODE_ETOPXIZU_YELLOW_ORANGE 16726215
154 | #define IRCODE_ETOPXIZU_YELLOW 16718055
155 |
156 | #define IRCODE_ETOPXIZU_GREEN 16751205
157 | #define IRCODE_ETOPXIZU_LIME 16755285
158 | #define IRCODE_ETOPXIZU_AQUA 16747125
159 | #define IRCODE_ETOPXIZU_TEAL 16758855
160 | #define IRCODE_ETOPXIZU_NAVY 16750695
161 |
162 | #define IRCODE_ETOPXIZU_BLUE 16753245
163 | #define IRCODE_ETOPXIZU_ROYAL_BLUE 16749165
164 | #define IRCODE_ETOPXIZU_PURPLE 16757325
165 | #define IRCODE_ETOPXIZU_INDIGO 16742535
166 | #define IRCODE_ETOPXIZU_MAGENTA 16734375
167 |
168 | #define IRCODE_ETOPXIZU_WHITE 16720605
169 | #define IRCODE_ETOPXIZU_PINK 16716525
170 | #define IRCODE_ETOPXIZU_LIGHT_PINK 16724685
171 | #define IRCODE_ETOPXIZU_BABY_BLUE 16775175
172 | #define IRCODE_ETOPXIZU_LIGHT_BLUE 16767015
173 |
174 | bool sparkfunRemoteEnabled = false;
175 | bool adafruitRemoteEnabled = true;
176 | bool etopxizuRemoteEnabled = true;
177 |
178 | // Dumps out the decode_results structure.
179 | // Call this after IRrecv::decode()
180 | // void * to work around compiler issue
181 | //void dump(void *v) {
182 | // decode_results *results = (decode_results *)v
183 | void dump(decode_results *results) {
184 | int count = results->rawlen;
185 | if (results->decode_type == UNKNOWN) {
186 | Serial.print("Unknown encoding: ");
187 | }
188 | else if (results->decode_type == NEC) {
189 | Serial.print("Decoded NEC: ");
190 | }
191 | else if (results->decode_type == SONY) {
192 | Serial.print("Decoded SONY: ");
193 | }
194 | else if (results->decode_type == RC5) {
195 | Serial.print("Decoded RC5: ");
196 | }
197 | else if (results->decode_type == RC6) {
198 | Serial.print("Decoded RC6: ");
199 | }
200 | else if (results->decode_type == PANASONIC) {
201 | Serial.print("Decoded PANASONIC - Address: ");
202 | Serial.print(results->panasonicAddress,HEX);
203 | Serial.print(" Value: ");
204 | }
205 | else if (results->decode_type == JVC) {
206 | Serial.print("Decoded JVC: ");
207 | }
208 | Serial.print(results->value, HEX);
209 | Serial.print(" (");
210 | Serial.print(results->bits, DEC);
211 | Serial.println(" bits)");
212 | Serial.print("Raw (");
213 | Serial.print(count, DEC);
214 | Serial.print("): ");
215 |
216 | for (int i = 0; i < count; i++) {
217 | if ((i % 2) == 1) {
218 | Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
219 | }
220 | else {
221 | Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
222 | }
223 | Serial.print(" ");
224 | }
225 | Serial.println("");
226 | }
227 |
228 | // Low level IR code reading function
229 | // Function will return 0 if no IR code available
230 | unsigned long decodeIRCode() {
231 |
232 | decode_results results;
233 |
234 | results.value = 0;
235 |
236 | // Attempt to read an IR code ?
237 | if (irReceiver.decode(&results)) {
238 | delay(20);
239 |
240 | if (results.value != 0)
241 | Serial.println(results.value);
242 |
243 | dump(&results);
244 |
245 | // Prepare to receive the next IR code
246 | irReceiver.resume();
247 | }
248 |
249 | return results.value;
250 | }
251 |
252 | // Read an IR code
253 | // Function will return 0 if no IR code available
254 | unsigned long readIRCode() {
255 |
256 | // Is there an IR code to read ?
257 | unsigned long code = decodeIRCode();
258 | if (code == 0) {
259 | // No code so return 0
260 | return 0;
261 | }
262 |
263 | // Keep reading until code changes
264 | while (decodeIRCode() == code) {
265 | ;
266 | }
267 | // Serial.println(code);
268 | return code;
269 | }
270 |
271 | unsigned long lastIrCode = 0;
272 |
273 | unsigned int holdStartTime = 0;
274 | unsigned int defaultHoldDelay = 500;
275 | bool isHolding = false;
276 |
277 | unsigned int zeroStartTime = 0;
278 | unsigned int zeroDelay = 120;
279 |
280 | unsigned long readIRCode(unsigned int holdDelay) {
281 | // read the raw code from the sensor
282 | unsigned long irCode = readIRCode();
283 |
284 | //Serial.print(millis());
285 | //Serial.print("\t");
286 | //Serial.println(irCode);
287 |
288 | // don't return a short click until we know it's not a long hold
289 | // we'll have to wait for holdDelay ms to pass before returning a non-zero IR code
290 | // then, after that delay, as long as the button is held, we can keep returning the code
291 | // every time until it's released
292 |
293 | // the ir remote only sends codes every 107 ms or so (avg 106.875, max 111, min 102),
294 | // so the ir sensor will return 0 even if a button is held
295 | // so we have to wait longer than that before returning a non-zero code
296 | // in order to detect that a button has been released and is no longer held
297 |
298 | // only reset after we've gotten 0 back for more than the ir remote send interval
299 | unsigned int zeroTime = 0;
300 |
301 | if (irCode == 0) {
302 | zeroTime = millis() - zeroStartTime;
303 | if (zeroTime >= zeroDelay && lastIrCode != 0) {
304 | //Serial.println(F("zero delay has elapsed, returning last ir code"));
305 | // the button has been released for longer than the zero delay
306 | // start over delays over and return the last code
307 | irCode = lastIrCode;
308 | lastIrCode = 0;
309 | return irCode;
310 | }
311 |
312 | return 0;
313 | }
314 |
315 | // reset the zero timer every time a non-zero code is read
316 | zeroStartTime = millis();
317 |
318 | unsigned int heldTime = 0;
319 |
320 | if (irCode == IRCODE_SPARKFUN_HELD || irCode == IRCODE_ADAFRUIT_HELD) {
321 | // has the hold delay passed?
322 | heldTime = millis() - holdStartTime;
323 | if (heldTime >= holdDelay) {
324 | isHolding = true;
325 | //Serial.println(F("hold delay has elapsed, returning last ir code"));
326 | return lastIrCode;
327 | }
328 | else if (holdStartTime == 0) {
329 | isHolding = false;
330 | holdStartTime = millis();
331 | }
332 | }
333 | else {
334 | // not zero, not IRCODE_SPARKFUN_HELD
335 | // store it for use later, until the hold and zero delays have elapsed
336 | holdStartTime = millis();
337 | isHolding = false;
338 | lastIrCode = irCode;
339 | return 0;
340 | }
341 |
342 | return 0;
343 | }
344 |
345 | void heldButtonHasBeenHandled() {
346 | lastIrCode = 0;
347 | isHolding = false;
348 | holdStartTime = 0;
349 | }
350 |
351 | unsigned long waitForIRCode() {
352 |
353 | unsigned long irCode = readIRCode();
354 | while ((irCode == 0) || (irCode == 0xFFFFFFFF)) {
355 | delay(200);
356 | irCode = readIRCode();
357 | }
358 | return irCode;
359 | }
360 |
361 | InputCommand getCommand(unsigned long input) {
362 | if (adafruitRemoteEnabled) {
363 | switch (input) {
364 | case IRCODE_ADAFRUIT_UP:
365 | return InputCommand::Up;
366 |
367 | case IRCODE_ADAFRUIT_DOWN:
368 | return InputCommand::Down;
369 |
370 | case IRCODE_ADAFRUIT_LEFT:
371 | return InputCommand::Left;
372 |
373 | case IRCODE_ADAFRUIT_RIGHT:
374 | return InputCommand::Right;
375 |
376 | case IRCODE_ADAFRUIT_ENTER_SAVE:
377 | return InputCommand::Select;
378 |
379 | case IRCODE_ADAFRUIT_STOP_MODE:
380 | case IRCODE_ADAFRUIT_1:
381 | return InputCommand::PlayMode;
382 |
383 | case IRCODE_ADAFRUIT_2:
384 | return InputCommand::Palette;
385 |
386 | case IRCODE_ADAFRUIT_PLAY_PAUSE:
387 | return InputCommand::Power;
388 |
389 | case IRCODE_ADAFRUIT_VOLUME_UP:
390 | return InputCommand::BrightnessUp;
391 |
392 | case IRCODE_ADAFRUIT_VOLUME_DOWN:
393 | return InputCommand::BrightnessDown;
394 | }
395 | }
396 |
397 | if (sparkfunRemoteEnabled) {
398 | switch (input) {
399 | case IRCODE_SPARKFUN_UP:
400 | return InputCommand::Up;
401 |
402 | case IRCODE_SPARKFUN_DOWN:
403 | return InputCommand::Down;
404 |
405 | case IRCODE_SPARKFUN_LEFT:
406 | return InputCommand::Left;
407 |
408 | case IRCODE_SPARKFUN_RIGHT:
409 | return InputCommand::Right;
410 |
411 | case IRCODE_SPARKFUN_SELECT:
412 | return InputCommand::Select;
413 |
414 | case IRCODE_SPARKFUN_POWER:
415 | return InputCommand::Brightness;
416 |
417 | case IRCODE_SPARKFUN_A:
418 | return InputCommand::PlayMode;
419 |
420 | case IRCODE_SPARKFUN_B:
421 | return InputCommand::Palette;
422 | }
423 | }
424 |
425 | if (etopxizuRemoteEnabled) {
426 | switch (input) {
427 | case IRCODE_ETOPXIZU_QUICK:
428 | return InputCommand::Up;
429 |
430 | case IRCODE_ETOPXIZU_SLOW:
431 | return InputCommand::Down;
432 |
433 | case IRCODE_ETOPXIZU_PLAY_PAUSE:
434 | return InputCommand::PlayMode;
435 |
436 | case IRCODE_ETOPXIZU_POWER:
437 | return InputCommand::Power;
438 |
439 | case IRCODE_ETOPXIZU_BRIGHTNESS_UP:
440 | return InputCommand::BrightnessUp;
441 | case IRCODE_ETOPXIZU_BRIGHTNESS_DOWN:
442 | return InputCommand::BrightnessDown;
443 |
444 | case IRCODE_ETOPXIZU_DIY1:
445 | return InputCommand::Pattern1;
446 | case IRCODE_ETOPXIZU_DIY2:
447 | return InputCommand::Pattern2;
448 | case IRCODE_ETOPXIZU_DIY3:
449 | return InputCommand::Pattern3;
450 | case IRCODE_ETOPXIZU_DIY4:
451 | return InputCommand::Pattern4;
452 | case IRCODE_ETOPXIZU_DIY5:
453 | return InputCommand::Pattern5;
454 | case IRCODE_ETOPXIZU_DIY6:
455 | return InputCommand::Pattern6;
456 | case IRCODE_ETOPXIZU_JUMP3:
457 | return InputCommand::Pattern7;
458 | case IRCODE_ETOPXIZU_JUMP7:
459 | return InputCommand::Pattern8;
460 | case IRCODE_ETOPXIZU_FADE3:
461 | return InputCommand::Pattern9;
462 | case IRCODE_ETOPXIZU_FADE7:
463 | return InputCommand::Pattern10;
464 | case IRCODE_ETOPXIZU_FLASH:
465 | return InputCommand::Pattern11;
466 | case IRCODE_ETOPXIZU_AUTO:
467 | return InputCommand::Pattern12;
468 |
469 | case IRCODE_ETOPXIZU_RED_UP:
470 | return InputCommand::RedUp;
471 | case IRCODE_ETOPXIZU_RED_DOWN:
472 | return InputCommand::RedDown;
473 |
474 | case IRCODE_ETOPXIZU_GREEN_UP:
475 | return InputCommand::GreenUp;
476 | case IRCODE_ETOPXIZU_GREEN_DOWN:
477 | return InputCommand::GreenDown;
478 |
479 | case IRCODE_ETOPXIZU_BLUE_UP:
480 | return InputCommand::BlueUp;
481 | case IRCODE_ETOPXIZU_BLUE_DOWN:
482 | return InputCommand::BlueDown;
483 |
484 | case IRCODE_ETOPXIZU_RED:
485 | return InputCommand::Red;
486 | case IRCODE_ETOPXIZU_RED_ORANGE:
487 | return InputCommand::RedOrange;
488 | case IRCODE_ETOPXIZU_ORANGE:
489 | return InputCommand::Orange;
490 | case IRCODE_ETOPXIZU_YELLOW_ORANGE:
491 | return InputCommand::YellowOrange;
492 | case IRCODE_ETOPXIZU_YELLOW:
493 | return InputCommand::Yellow;
494 |
495 | case IRCODE_ETOPXIZU_GREEN:
496 | return InputCommand::Green;
497 | case IRCODE_ETOPXIZU_LIME:
498 | return InputCommand::Lime;
499 | case IRCODE_ETOPXIZU_AQUA:
500 | return InputCommand::Aqua;
501 | case IRCODE_ETOPXIZU_TEAL:
502 | return InputCommand::Teal;
503 | case IRCODE_ETOPXIZU_NAVY:
504 | return InputCommand::Navy;
505 |
506 | case IRCODE_ETOPXIZU_BLUE:
507 | return InputCommand::Blue;
508 | case IRCODE_ETOPXIZU_ROYAL_BLUE:
509 | return InputCommand::RoyalBlue;
510 | case IRCODE_ETOPXIZU_PURPLE:
511 | return InputCommand::Purple;
512 | case IRCODE_ETOPXIZU_INDIGO:
513 | return InputCommand::Indigo;
514 | case IRCODE_ETOPXIZU_MAGENTA:
515 | return InputCommand::Magenta;
516 |
517 | case IRCODE_ETOPXIZU_WHITE:
518 | return InputCommand::White;
519 | case IRCODE_ETOPXIZU_PINK:
520 | return InputCommand::Pink;
521 | case IRCODE_ETOPXIZU_LIGHT_PINK:
522 | return InputCommand::LightPink;
523 | case IRCODE_ETOPXIZU_BABY_BLUE:
524 | return InputCommand::BabyBlue;
525 | case IRCODE_ETOPXIZU_LIGHT_BLUE:
526 | return InputCommand::LightBlue;
527 | }
528 | }
529 |
530 | return InputCommand::None;
531 | }
532 |
533 | InputCommand readCommand() {
534 | return getCommand(readIRCode());
535 | }
536 |
537 | InputCommand readCommand(unsigned int holdDelay) {
538 | return getCommand(readIRCode(holdDelay));
539 | }
540 |
541 | #endif
542 |
--------------------------------------------------------------------------------
/GradientPalettes.h:
--------------------------------------------------------------------------------
1 | // From ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
2 |
3 | // Gradient Color Palette definitions for 33 different cpt-city color palettes.
4 | // 956 bytes of PROGMEM for all of the palettes together,
5 | // +618 bytes of PROGMEM for gradient palette code (AVR).
6 | // 1,494 bytes total for all 34 color palettes and associated code.
7 |
8 | // Gradient palette "ib_jul01_gp", originally from
9 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ing/xmas/tn/ib_jul01.png.index.html
10 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
11 | // Size: 16 bytes of program space.
12 |
13 | DEFINE_GRADIENT_PALETTE( ib_jul01_gp ) {
14 | 0, 194, 1, 1,
15 | 94, 1, 29, 18,
16 | 132, 57,131, 28,
17 | 255, 113, 1, 1};
18 |
19 | // Gradient palette "es_vintage_57_gp", originally from
20 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_57.png.index.html
21 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
22 | // Size: 20 bytes of program space.
23 |
24 | DEFINE_GRADIENT_PALETTE( es_vintage_57_gp ) {
25 | 0, 2, 1, 1,
26 | 53, 18, 1, 0,
27 | 104, 69, 29, 1,
28 | 153, 167,135, 10,
29 | 255, 46, 56, 4};
30 |
31 | // Gradient palette "es_vintage_01_gp", originally from
32 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_01.png.index.html
33 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
34 | // Size: 32 bytes of program space.
35 |
36 | DEFINE_GRADIENT_PALETTE( es_vintage_01_gp ) {
37 | 0, 4, 1, 1,
38 | 51, 16, 0, 1,
39 | 76, 97,104, 3,
40 | 101, 255,131, 19,
41 | 127, 67, 9, 4,
42 | 153, 16, 0, 1,
43 | 229, 4, 1, 1,
44 | 255, 4, 1, 1};
45 |
46 | // Gradient palette "es_rivendell_15_gp", originally from
47 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/rivendell/tn/es_rivendell_15.png.index.html
48 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
49 | // Size: 20 bytes of program space.
50 |
51 | DEFINE_GRADIENT_PALETTE( es_rivendell_15_gp ) {
52 | 0, 1, 14, 5,
53 | 101, 16, 36, 14,
54 | 165, 56, 68, 30,
55 | 242, 150,156, 99,
56 | 255, 150,156, 99};
57 |
58 | // Gradient palette "rgi_15_gp", originally from
59 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ds/rgi/tn/rgi_15.png.index.html
60 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
61 | // Size: 36 bytes of program space.
62 |
63 | DEFINE_GRADIENT_PALETTE( rgi_15_gp ) {
64 | 0, 4, 1, 31,
65 | 31, 55, 1, 16,
66 | 63, 197, 3, 7,
67 | 95, 59, 2, 17,
68 | 127, 6, 2, 34,
69 | 159, 39, 6, 33,
70 | 191, 112, 13, 32,
71 | 223, 56, 9, 35,
72 | 255, 22, 6, 38};
73 |
74 | // Gradient palette "retro2_16_gp", originally from
75 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ma/retro2/tn/retro2_16.png.index.html
76 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
77 | // Size: 8 bytes of program space.
78 |
79 | DEFINE_GRADIENT_PALETTE( retro2_16_gp ) {
80 | 0, 188,135, 1,
81 | 255, 46, 7, 1};
82 |
83 | // Gradient palette "Analogous_1_gp", originally from
84 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/red/tn/Analogous_1.png.index.html
85 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
86 | // Size: 20 bytes of program space.
87 |
88 | DEFINE_GRADIENT_PALETTE( Analogous_1_gp ) {
89 | 0, 3, 0,255,
90 | 63, 23, 0,255,
91 | 127, 67, 0,255,
92 | 191, 142, 0, 45,
93 | 255, 255, 0, 0};
94 |
95 | // Gradient palette "es_pinksplash_08_gp", originally from
96 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/pink_splash/tn/es_pinksplash_08.png.index.html
97 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
98 | // Size: 20 bytes of program space.
99 |
100 | DEFINE_GRADIENT_PALETTE( es_pinksplash_08_gp ) {
101 | 0, 126, 11,255,
102 | 127, 197, 1, 22,
103 | 175, 210,157,172,
104 | 221, 157, 3,112,
105 | 255, 157, 3,112};
106 |
107 | // Gradient palette "es_pinksplash_07_gp", originally from
108 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/pink_splash/tn/es_pinksplash_07.png.index.html
109 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
110 | // Size: 28 bytes of program space.
111 |
112 | DEFINE_GRADIENT_PALETTE( es_pinksplash_07_gp ) {
113 | 0, 229, 1, 1,
114 | 61, 242, 4, 63,
115 | 101, 255, 12,255,
116 | 127, 249, 81,252,
117 | 153, 255, 11,235,
118 | 193, 244, 5, 68,
119 | 255, 232, 1, 5};
120 |
121 | // Gradient palette "Coral_reef_gp", originally from
122 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/other/tn/Coral_reef.png.index.html
123 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
124 | // Size: 24 bytes of program space.
125 |
126 | DEFINE_GRADIENT_PALETTE( Coral_reef_gp ) {
127 | 0, 40,199,197,
128 | 50, 10,152,155,
129 | 96, 1,111,120,
130 | 96, 43,127,162,
131 | 139, 10, 73,111,
132 | 255, 1, 34, 71};
133 |
134 | // Gradient palette "es_ocean_breeze_068_gp", originally from
135 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/ocean_breeze/tn/es_ocean_breeze_068.png.index.html
136 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
137 | // Size: 24 bytes of program space.
138 |
139 | DEFINE_GRADIENT_PALETTE( es_ocean_breeze_068_gp ) {
140 | 0, 100,156,153,
141 | 51, 1, 99,137,
142 | 101, 1, 68, 84,
143 | 104, 35,142,168,
144 | 178, 0, 63,117,
145 | 255, 1, 10, 10};
146 |
147 | // Gradient palette "es_ocean_breeze_036_gp", originally from
148 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/ocean_breeze/tn/es_ocean_breeze_036.png.index.html
149 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
150 | // Size: 16 bytes of program space.
151 |
152 | DEFINE_GRADIENT_PALETTE( es_ocean_breeze_036_gp ) {
153 | 0, 1, 6, 7,
154 | 89, 1, 99,111,
155 | 153, 144,209,255,
156 | 255, 0, 73, 82};
157 |
158 | // Gradient palette "departure_gp", originally from
159 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/mjf/tn/departure.png.index.html
160 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
161 | // Size: 88 bytes of program space.
162 |
163 | DEFINE_GRADIENT_PALETTE( departure_gp ) {
164 | 0, 8, 3, 0,
165 | 42, 23, 7, 0,
166 | 63, 75, 38, 6,
167 | 84, 169, 99, 38,
168 | 106, 213,169,119,
169 | 116, 255,255,255,
170 | 138, 135,255,138,
171 | 148, 22,255, 24,
172 | 170, 0,255, 0,
173 | 191, 0,136, 0,
174 | 212, 0, 55, 0,
175 | 255, 0, 55, 0};
176 |
177 | // Gradient palette "es_landscape_64_gp", originally from
178 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_64.png.index.html
179 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
180 | // Size: 36 bytes of program space.
181 |
182 | DEFINE_GRADIENT_PALETTE( es_landscape_64_gp ) {
183 | 0, 0, 0, 0,
184 | 37, 2, 25, 1,
185 | 76, 15,115, 5,
186 | 127, 79,213, 1,
187 | 128, 126,211, 47,
188 | 130, 188,209,247,
189 | 153, 144,182,205,
190 | 204, 59,117,250,
191 | 255, 1, 37,192};
192 |
193 | // Gradient palette "es_landscape_33_gp", originally from
194 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_33.png.index.html
195 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
196 | // Size: 24 bytes of program space.
197 |
198 | DEFINE_GRADIENT_PALETTE( es_landscape_33_gp ) {
199 | 0, 1, 5, 0,
200 | 19, 32, 23, 1,
201 | 38, 161, 55, 1,
202 | 63, 229,144, 1,
203 | 66, 39,142, 74,
204 | 255, 1, 4, 1};
205 |
206 | // Gradient palette "rainbowsherbet_gp", originally from
207 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ma/icecream/tn/rainbowsherbet.png.index.html
208 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
209 | // Size: 28 bytes of program space.
210 |
211 | DEFINE_GRADIENT_PALETTE( rainbowsherbet_gp ) {
212 | 0, 255, 33, 4,
213 | 43, 255, 68, 25,
214 | 86, 255, 7, 25,
215 | 127, 255, 82,103,
216 | 170, 255,255,242,
217 | 209, 42,255, 22,
218 | 255, 87,255, 65};
219 |
220 | // Gradient palette "gr65_hult_gp", originally from
221 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/hult/tn/gr65_hult.png.index.html
222 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
223 | // Size: 24 bytes of program space.
224 |
225 | DEFINE_GRADIENT_PALETTE( gr65_hult_gp ) {
226 | 0, 247,176,247,
227 | 48, 255,136,255,
228 | 89, 220, 29,226,
229 | 160, 7, 82,178,
230 | 216, 1,124,109,
231 | 255, 1,124,109};
232 |
233 | // Gradient palette "gr64_hult_gp", originally from
234 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/hult/tn/gr64_hult.png.index.html
235 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
236 | // Size: 32 bytes of program space.
237 |
238 | DEFINE_GRADIENT_PALETTE( gr64_hult_gp ) {
239 | 0, 1,124,109,
240 | 66, 1, 93, 79,
241 | 104, 52, 65, 1,
242 | 130, 115,127, 1,
243 | 150, 52, 65, 1,
244 | 201, 1, 86, 72,
245 | 239, 0, 55, 45,
246 | 255, 0, 55, 45};
247 |
248 | // Gradient palette "GMT_drywet_gp", originally from
249 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/gmt/tn/GMT_drywet.png.index.html
250 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
251 | // Size: 28 bytes of program space.
252 |
253 | DEFINE_GRADIENT_PALETTE( GMT_drywet_gp ) {
254 | 0, 47, 30, 2,
255 | 42, 213,147, 24,
256 | 84, 103,219, 52,
257 | 127, 3,219,207,
258 | 170, 1, 48,214,
259 | 212, 1, 1,111,
260 | 255, 1, 7, 33};
261 |
262 | // Gradient palette "ib15_gp", originally from
263 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ing/general/tn/ib15.png.index.html
264 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
265 | // Size: 24 bytes of program space.
266 |
267 | DEFINE_GRADIENT_PALETTE( ib15_gp ) {
268 | 0, 113, 91,147,
269 | 72, 157, 88, 78,
270 | 89, 208, 85, 33,
271 | 107, 255, 29, 11,
272 | 141, 137, 31, 39,
273 | 255, 59, 33, 89};
274 |
275 | // Gradient palette "Fuschia_7_gp", originally from
276 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ds/fuschia/tn/Fuschia-7.png.index.html
277 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
278 | // Size: 20 bytes of program space.
279 |
280 | DEFINE_GRADIENT_PALETTE( Fuschia_7_gp ) {
281 | 0, 43, 3,153,
282 | 63, 100, 4,103,
283 | 127, 188, 5, 66,
284 | 191, 161, 11,115,
285 | 255, 135, 20,182};
286 |
287 | // Gradient palette "es_emerald_dragon_08_gp", originally from
288 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/emerald_dragon/tn/es_emerald_dragon_08.png.index.html
289 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
290 | // Size: 16 bytes of program space.
291 |
292 | DEFINE_GRADIENT_PALETTE( es_emerald_dragon_08_gp ) {
293 | 0, 97,255, 1,
294 | 101, 47,133, 1,
295 | 178, 13, 43, 1,
296 | 255, 2, 10, 1};
297 |
298 | // Gradient palette "lava_gp", originally from
299 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/neota/elem/tn/lava.png.index.html
300 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
301 | // Size: 52 bytes of program space.
302 |
303 | DEFINE_GRADIENT_PALETTE( lava_gp ) {
304 | 0, 0, 0, 0,
305 | 46, 18, 0, 0,
306 | 96, 113, 0, 0,
307 | 108, 142, 3, 1,
308 | 119, 175, 17, 1,
309 | 146, 213, 44, 2,
310 | 174, 255, 82, 4,
311 | 188, 255,115, 4,
312 | 202, 255,156, 4,
313 | 218, 255,203, 4,
314 | 234, 255,255, 4,
315 | 244, 255,255, 71,
316 | 255, 255,255,255};
317 |
318 | // Gradient palette "fire_gp", originally from
319 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/neota/elem/tn/fire.png.index.html
320 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
321 | // Size: 28 bytes of program space.
322 |
323 | DEFINE_GRADIENT_PALETTE( fire_gp ) {
324 | 0, 1, 1, 0,
325 | 76, 32, 5, 0,
326 | 146, 192, 24, 0,
327 | 197, 220,105, 5,
328 | 240, 252,255, 31,
329 | 250, 252,255,111,
330 | 255, 255,255,255};
331 |
332 | // Gradient palette "Colorfull_gp", originally from
333 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Colorfull.png.index.html
334 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
335 | // Size: 44 bytes of program space.
336 |
337 | DEFINE_GRADIENT_PALETTE( Colorfull_gp ) {
338 | 0, 10, 85, 5,
339 | 25, 29,109, 18,
340 | 60, 59,138, 42,
341 | 93, 83, 99, 52,
342 | 106, 110, 66, 64,
343 | 109, 123, 49, 65,
344 | 113, 139, 35, 66,
345 | 116, 192,117, 98,
346 | 124, 255,255,137,
347 | 168, 100,180,155,
348 | 255, 22,121,174};
349 |
350 | // Gradient palette "Magenta_Evening_gp", originally from
351 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Magenta_Evening.png.index.html
352 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
353 | // Size: 28 bytes of program space.
354 |
355 | DEFINE_GRADIENT_PALETTE( Magenta_Evening_gp ) {
356 | 0, 71, 27, 39,
357 | 31, 130, 11, 51,
358 | 63, 213, 2, 64,
359 | 70, 232, 1, 66,
360 | 76, 252, 1, 69,
361 | 108, 123, 2, 51,
362 | 255, 46, 9, 35};
363 |
364 | // Gradient palette "Pink_Purple_gp", originally from
365 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Pink_Purple.png.index.html
366 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
367 | // Size: 44 bytes of program space.
368 |
369 | DEFINE_GRADIENT_PALETTE( Pink_Purple_gp ) {
370 | 0, 19, 2, 39,
371 | 25, 26, 4, 45,
372 | 51, 33, 6, 52,
373 | 76, 68, 62,125,
374 | 102, 118,187,240,
375 | 109, 163,215,247,
376 | 114, 217,244,255,
377 | 122, 159,149,221,
378 | 149, 113, 78,188,
379 | 183, 128, 57,155,
380 | 255, 146, 40,123};
381 |
382 | // Gradient palette "Sunset_Real_gp", originally from
383 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png.index.html
384 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
385 | // Size: 28 bytes of program space.
386 |
387 | DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) {
388 | 0, 120, 0, 0,
389 | 22, 179, 22, 0,
390 | 51, 255,104, 0,
391 | 85, 167, 22, 18,
392 | 135, 100, 0,103,
393 | 198, 16, 0,130,
394 | 255, 0, 0,160};
395 |
396 | // Gradient palette "es_autumn_19_gp", originally from
397 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/autumn/tn/es_autumn_19.png.index.html
398 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
399 | // Size: 52 bytes of program space.
400 |
401 | DEFINE_GRADIENT_PALETTE( es_autumn_19_gp ) {
402 | 0, 26, 1, 1,
403 | 51, 67, 4, 1,
404 | 84, 118, 14, 1,
405 | 104, 137,152, 52,
406 | 112, 113, 65, 1,
407 | 122, 133,149, 59,
408 | 124, 137,152, 52,
409 | 135, 113, 65, 1,
410 | 142, 139,154, 46,
411 | 163, 113, 13, 1,
412 | 204, 55, 3, 1,
413 | 249, 17, 1, 1,
414 | 255, 17, 1, 1};
415 |
416 | // Gradient palette "BlacK_Blue_Magenta_White_gp", originally from
417 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Blue_Magenta_White.png.index.html
418 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
419 | // Size: 28 bytes of program space.
420 |
421 | DEFINE_GRADIENT_PALETTE( BlacK_Blue_Magenta_White_gp ) {
422 | 0, 0, 0, 0,
423 | 42, 0, 0, 45,
424 | 84, 0, 0,255,
425 | 127, 42, 0,255,
426 | 170, 255, 0,255,
427 | 212, 255, 55,255,
428 | 255, 255,255,255};
429 |
430 | // Gradient palette "BlacK_Magenta_Red_gp", originally from
431 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Magenta_Red.png.index.html
432 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
433 | // Size: 20 bytes of program space.
434 |
435 | DEFINE_GRADIENT_PALETTE( BlacK_Magenta_Red_gp ) {
436 | 0, 0, 0, 0,
437 | 63, 42, 0, 45,
438 | 127, 255, 0,255,
439 | 191, 255, 0, 45,
440 | 255, 255, 0, 0};
441 |
442 | // Gradient palette "BlacK_Red_Magenta_Yellow_gp", originally from
443 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Red_Magenta_Yellow.png.index.html
444 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
445 | // Size: 28 bytes of program space.
446 |
447 | DEFINE_GRADIENT_PALETTE( BlacK_Red_Magenta_Yellow_gp ) {
448 | 0, 0, 0, 0,
449 | 42, 42, 0, 0,
450 | 84, 255, 0, 0,
451 | 127, 255, 0, 45,
452 | 170, 255, 0,255,
453 | 212, 255, 55, 45,
454 | 255, 255,255, 0};
455 |
456 | // Gradient palette "Blue_Cyan_Yellow_gp", originally from
457 | // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Blue_Cyan_Yellow.png.index.html
458 | // converted for FastLED with gammas (2.6, 2.2, 2.5)
459 | // Size: 20 bytes of program space.
460 |
461 | DEFINE_GRADIENT_PALETTE( Blue_Cyan_Yellow_gp ) {
462 | 0, 0, 0,255,
463 | 63, 0, 55,255,
464 | 127, 0,255,255,
465 | 191, 42,255, 45,
466 | 255, 255,255, 0};
467 |
468 |
469 | // Single array of defined cpt-city color palettes.
470 | // This will let us programmatically choose one based on
471 | // a number, rather than having to activate each explicitly
472 | // by name every time.
473 | // Since it is const, this array could also be moved
474 | // into PROGMEM to save SRAM, but for simplicity of illustration
475 | // we'll keep it in a regular SRAM array.
476 | //
477 | // This list of color palettes acts as a "playlist"; you can
478 | // add or delete, or re-arrange as you wish.
479 | const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
480 | Sunset_Real_gp,
481 | es_rivendell_15_gp,
482 | es_ocean_breeze_036_gp,
483 | rgi_15_gp,
484 | retro2_16_gp,
485 | Analogous_1_gp,
486 | es_pinksplash_08_gp,
487 | Coral_reef_gp,
488 | es_ocean_breeze_068_gp,
489 | es_pinksplash_07_gp,
490 | es_vintage_01_gp,
491 | departure_gp,
492 | es_landscape_64_gp,
493 | es_landscape_33_gp,
494 | rainbowsherbet_gp,
495 | gr65_hult_gp,
496 | gr64_hult_gp,
497 | GMT_drywet_gp,
498 | ib_jul01_gp,
499 | es_vintage_57_gp,
500 | ib15_gp,
501 | Fuschia_7_gp,
502 | es_emerald_dragon_08_gp,
503 | lava_gp,
504 | fire_gp,
505 | Colorfull_gp,
506 | Magenta_Evening_gp,
507 | Pink_Purple_gp,
508 | es_autumn_19_gp,
509 | BlacK_Blue_Magenta_White_gp,
510 | BlacK_Magenta_Red_gp,
511 | BlacK_Red_Magenta_Yellow_gp,
512 | Blue_Cyan_Yellow_gp };
513 |
514 |
515 | // Count of how many cpt-city gradients are defined:
516 | const uint8_t gGradientPaletteCount =
517 | sizeof( gGradientPalettes) / sizeof( TProgmemRGBGradientPalettePtr );
518 |
519 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Life.h:
--------------------------------------------------------------------------------
1 | /*
2 | Fibonacci v3D: https://github.com/evilgeniuslabs/fibonacci-v3d
3 | Copyright (C) 2014-2016 Jason Coon, Evil Genius Labs
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | class Cell
20 | {
21 | public:
22 | byte alive = 1;
23 | byte prev = 1;
24 | byte hue = 6;
25 | byte brightness;
26 | };
27 |
28 | Cell world[kMatrixWidth][kMatrixHeight];
29 |
30 | uint8_t neighbors(uint8_t x, uint8_t y)
31 | {
32 | return (world[(x + 1) % kMatrixWidth][y].prev) +
33 | (world[x][(y + 1) % kMatrixHeight].prev) +
34 | (world[(x + kMatrixWidth - 1) % kMatrixWidth][y].prev) +
35 | (world[x][(y + kMatrixHeight - 1) % kMatrixHeight].prev) +
36 | (world[(x + 1) % kMatrixWidth][(y + 1) % kMatrixHeight].prev) +
37 | (world[(x + kMatrixWidth - 1) % kMatrixWidth][(y + 1) % kMatrixHeight].prev) +
38 | (world[(x + kMatrixWidth - 1) % kMatrixWidth][(y + kMatrixHeight - 1) % kMatrixHeight].prev) +
39 | (world[(x + 1) % kMatrixWidth][(y + kMatrixHeight - 1) % kMatrixHeight].prev);
40 | }
41 |
42 | void randomFillWorld()
43 | {
44 | static uint8_t lifeDensity = 10;
45 |
46 | for (uint8_t i = 0; i < kMatrixWidth; i++) {
47 | for (uint8_t j = 0; j < kMatrixHeight; j++) {
48 | if (random(100) < lifeDensity) {
49 | world[i][j].alive = 1;
50 | world[i][j].brightness = 255;
51 | }
52 | else {
53 | world[i][j].alive = 0;
54 | world[i][j].brightness = 0;
55 | }
56 | world[i][j].prev = world[i][j].alive;
57 | world[i][j].hue = 0;
58 | }
59 | }
60 | }
61 |
62 | uint8_t life()
63 | {
64 | static uint8_t generation = 0;
65 |
66 | // Display current generation
67 | for (uint8_t i = 0; i < kMatrixWidth; i++)
68 | {
69 | for (uint8_t j = 0; j < kMatrixHeight; j++)
70 | {
71 | setPixelXY(i, j, ColorFromPalette(currentPalette, world[i][j].hue * 4, world[i][j].brightness, LINEARBLEND));
72 | }
73 | }
74 |
75 | uint8_t liveCells = 0;
76 |
77 | // Birth and death cycle
78 | for (uint8_t x = 0; x < kMatrixWidth; x++)
79 | {
80 | for (uint8_t y = 0; y < kMatrixHeight; y++)
81 | {
82 | // Default is for cell to stay the same
83 | if (world[x][y].brightness > 0 && world[x][y].prev == 0)
84 | world[x][y].brightness *= 0.5;
85 |
86 | uint8_t count = neighbors(x, y);
87 |
88 | if (count == 3 && world[x][y].prev == 0)
89 | {
90 | // A new cell is born
91 | world[x][y].alive = 1;
92 | world[x][y].hue += 2;
93 | world[x][y].brightness = 255;
94 | }
95 | else if ((count < 2 || count > 3) && world[x][y].prev == 1)
96 | {
97 | // Cell dies
98 | world[x][y].alive = 0;
99 | }
100 |
101 | if (world[x][y].alive)
102 | liveCells++;
103 | }
104 | }
105 |
106 | // Copy next generation into place
107 | for (uint8_t x = 0; x < kMatrixWidth; x++)
108 | {
109 | for (uint8_t y = 0; y < kMatrixHeight; y++)
110 | {
111 | world[x][y].prev = world[x][y].alive;
112 | }
113 | }
114 |
115 | if (liveCells < 4 || generation >= 128)
116 | {
117 | fill_solid(leds, NUM_LEDS, CRGB::Black);
118 |
119 | randomFillWorld();
120 |
121 | generation = 0;
122 | }
123 | else
124 | {
125 | generation++;
126 | }
127 |
128 | return 60;
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/Noise.h:
--------------------------------------------------------------------------------
1 | /*
2 | Fibonacci v3D: https://github.com/evilgeniuslabs/fibonacci-v3d
3 | Copyright (C) 2014-2016 Jason Coon, Evil Genius Labs
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 | #define MATRIX_WIDTH 32
19 | #define MATRIX_HEIGHT 32
20 |
21 | #define MAX_DIMENSION ((MATRIX_WIDTH > MATRIX_HEIGHT) ? MATRIX_WIDTH : MATRIX_HEIGHT)
22 |
23 | // The 16 bit version of our coordinates
24 | uint16_t noisex;
25 | uint16_t noisey;
26 | uint16_t noisez;
27 |
28 | // We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll
29 | // use the z-axis for "time". speed determines how fast time moves forward. Try
30 | // 1 for a very slow moving effect, or 60 for something that ends up looking like
31 | // water.
32 | int noisespeedx = 0;
33 | int noisespeedy = 1;
34 | int noisespeedz = 0;
35 |
36 | // Scale determines how far apart the pixels in our noise matrix are. Try
37 | // changing these values around to see how it affects the motion of the display. The
38 | // higher the value of scale, the more "zoomed out" the noise will be. A value
39 | // of 1 will be so zoomed in, you'll mostly see solid colors.
40 | uint16_t noisescale = 1; // scale is set dynamically once we've started up
41 |
42 | // This is the array that we keep our computed noise values in
43 | uint8_t noise[MAX_DIMENSION][MAX_DIMENSION];
44 |
45 | uint8_t colorLoop = 0;
46 |
47 | CRGBPalette16 blackAndWhiteStripedPalette;
48 |
49 | // This function sets up a palette of black and white stripes,
50 | // using code. Since the palette is effectively an array of
51 | // sixteen CRGB colors, the various fill_* functions can be used
52 | // to set them up.
53 | void SetupBlackAndWhiteStripedPalette()
54 | {
55 | // 'black out' all 16 palette entries...
56 | fill_solid( blackAndWhiteStripedPalette, 16, CRGB::Black);
57 | // and set every fourth one to white.
58 | blackAndWhiteStripedPalette[0] = CRGB::White;
59 | blackAndWhiteStripedPalette[4] = CRGB::White;
60 | blackAndWhiteStripedPalette[8] = CRGB::White;
61 | blackAndWhiteStripedPalette[12] = CRGB::White;
62 |
63 | }
64 |
65 | CRGBPalette16 blackAndBlueStripedPalette;
66 |
67 | // This function sets up a palette of black and blue stripes,
68 | // using code. Since the palette is effectively an array of
69 | // sixteen CRGB colors, the various fill_* functions can be used
70 | // to set them up.
71 | void SetupBlackAndBlueStripedPalette()
72 | {
73 | // 'black out' all 16 palette entries...
74 | fill_solid( blackAndBlueStripedPalette, 16, CRGB::Black);
75 |
76 | for(uint8_t i = 0; i < 6; i++) {
77 | blackAndBlueStripedPalette[i] = CRGB::Blue;
78 | }
79 | }
80 |
81 | // There are several different palettes of colors demonstrated here.
82 | //
83 | // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
84 | // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
85 | //
86 | // Additionally, you can manually define your own color palettes, or you can write
87 | // code that creates color palettes on the fly.
88 |
89 | uint8_t drawNoise(CRGBPalette16 palette, uint8_t hueReduce = 0)
90 | {
91 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
92 | uint8_t j = physicalToFibonacciOrder[i];
93 |
94 | uint8_t x = coordsX[j];
95 | uint8_t y = coordsY[j];
96 |
97 | int xoffset = noisescale * x;
98 | int yoffset = noisescale * y;
99 |
100 | uint8_t data = inoise8(x + xoffset + noisex, y + yoffset + noisey, noisez);
101 |
102 | // The range of the inoise8 function is roughly 16-238.
103 | // These two operations expand those values out to roughly 0..255
104 | // You can comment them out if you want the raw noise data.
105 | data = qsub8(data, 16);
106 | data = qadd8(data, scale8(data, 39));
107 |
108 | leds[i] = ColorFromPalette(palette, data, 255, LINEARBLEND);
109 | }
110 |
111 | noisex += noisespeedx;
112 | noisey += noisespeedy;
113 | noisez += noisespeedz;
114 |
115 | return 8;
116 | }
117 |
118 | uint8_t rainbowNoise() {
119 | noisespeedx = 0;
120 | noisespeedy = 2;
121 | noisespeedz = 0;
122 | noisescale = 0;
123 | colorLoop = 0;
124 | return drawNoise(RainbowColors_p);
125 | }
126 |
127 | uint8_t rainbowStripeNoise() {
128 | noisespeedx = 0;
129 | noisespeedy = 2;
130 | noisespeedz = 0;
131 | noisescale = 0;
132 | colorLoop = 0;
133 | return drawNoise(RainbowStripeColors_p);
134 | }
135 |
136 | uint8_t partyNoise() {
137 | noisespeedx = 9;
138 | noisespeedy = 0;
139 | noisespeedz = 0;
140 | noisescale = 1;
141 | colorLoop = 0;
142 | return drawNoise(PartyColors_p);
143 | }
144 |
145 | uint8_t forestNoise() {
146 | noisespeedx = 9;
147 | noisespeedy = 0;
148 | noisespeedz = 0;
149 | noisescale = 1;
150 | colorLoop = 0;
151 | return drawNoise(ForestColors_p);
152 | }
153 |
154 | uint8_t cloudNoise() {
155 | noisespeedx = 2;
156 | noisespeedy = 0;
157 | noisespeedz = 0;
158 | noisescale = 0;
159 | colorLoop = 0;
160 | return drawNoise(CloudColors_p);
161 | }
162 |
163 | uint8_t fireNoise() {
164 | noisespeedx = 0; // 24;
165 | noisespeedy = 64;
166 | noisespeedz = 0;
167 | noisescale = 4;
168 | colorLoop = 0;
169 | return drawNoise(HeatColors_p, 60);
170 | }
171 |
172 | uint8_t fireNoise2() {
173 | noisespeedx = 0;
174 | noisespeedy = 8;
175 | noisespeedz = 4;
176 | noisescale = 1;
177 | colorLoop = 0;
178 | return drawNoise(HeatColors_p);
179 | }
180 |
181 | uint8_t lavaNoise() {
182 | noisespeedx = 0;
183 | noisespeedy = -1;
184 | noisespeedz = 2;
185 | noisescale = 0;
186 | colorLoop = 0;
187 | return drawNoise(LavaColors_p);
188 | }
189 |
190 | uint8_t oceanNoise() {
191 | noisespeedx = 2;
192 | noisespeedy = 0;
193 | noisespeedz = 4;
194 | noisescale = 0;
195 | colorLoop = 0;
196 | return drawNoise(OceanColors_p);
197 | }
198 |
199 | uint8_t blackAndWhiteNoise() {
200 | SetupBlackAndWhiteStripedPalette();
201 | noisespeedx = 12;
202 | noisespeedy = 0;
203 | noisespeedz = 0;
204 | noisescale = 0;
205 | colorLoop = 0;
206 | return drawNoise(blackAndWhiteStripedPalette);
207 | }
208 |
209 | uint8_t blackAndBlueNoise() {
210 | SetupBlackAndBlueStripedPalette();
211 | noisespeedx = 0;
212 | noisespeedy = -8;
213 | noisespeedz = 0;
214 | noisescale = 1;
215 | colorLoop = 0;
216 | return drawNoise(blackAndBlueStripedPalette);
217 | }
218 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Fibonacci v3D
2 |
3 | [Demo Videos](https://youtu.be/eBLh7yvzN-Y?list=PLUYGVM-2vDxJLjAv6qwl_FOBu8xzAoJL4):
4 |
5 | [](https://youtu.be/eBLh7yvzN-Y?list=PLUYGVM-2vDxJLjAv6qwl_FOBu8xzAoJL4)
6 |
7 | Built with [100 x WS2811 RGB LEDs](https://www.adafruit.com/products/322), controlled with a [Teensy](https://www.pjrc.com/teensy) using the [FastLED library](https://github.com/FastLED/FastLED).
8 |
9 | Fully open-source, and programmable via a micro USB cable.
10 |
11 | Build your own, or buy one (finished or kit) from [Evil Genius Labs](http://www.evilgeniuslabs.org): http://www.evilgeniuslabs.org
12 |
13 | Controlled via a wireless infrared remote control.
14 |
15 | Build pics, videos, and more details: https://goo.gl/photos/ijtXuzpKviSNW9Kv7
--------------------------------------------------------------------------------
/Twinkles.h:
--------------------------------------------------------------------------------
1 | // based on ColorTwinkles by Mark Kriegsman: https://gist.github.com/kriegsman/5408ecd397744ba0393e
2 |
3 | #define STARTING_BRIGHTNESS 64
4 | #define FADE_IN_SPEED 32
5 | #define FADE_OUT_SPEED 20
6 | #define DENSITY 255
7 |
8 | enum { GETTING_DARKER = 0, GETTING_BRIGHTER = 1 };
9 |
10 | CRGB makeBrighter( const CRGB& color, fract8 howMuchBrighter)
11 | {
12 | CRGB incrementalColor = color;
13 | incrementalColor.nscale8( howMuchBrighter);
14 | return color + incrementalColor;
15 | }
16 |
17 | CRGB makeDarker( const CRGB& color, fract8 howMuchDarker)
18 | {
19 | CRGB newcolor = color;
20 | newcolor.nscale8( 255 - howMuchDarker);
21 | return newcolor;
22 | }
23 |
24 | // Compact implementation of
25 | // the directionFlags array, using just one BIT of RAM
26 | // per pixel. This requires a bunch of bit wrangling,
27 | // but conserves precious RAM. The cost is a few
28 | // cycles and about 100 bytes of flash program memory.
29 | uint8_t directionFlags[ (NUM_LEDS + 7) / 8];
30 |
31 | bool getPixelDirection( uint16_t i)
32 | {
33 | uint16_t index = i / 8;
34 | uint8_t bitNum = i & 0x07;
35 |
36 | uint8_t andMask = 1 << bitNum;
37 | return (directionFlags[index] & andMask) != 0;
38 | }
39 |
40 | void setPixelDirection( uint16_t i, bool dir)
41 | {
42 | uint16_t index = i / 8;
43 | uint8_t bitNum = i & 0x07;
44 |
45 | uint8_t orMask = 1 << bitNum;
46 | uint8_t andMask = 255 - orMask;
47 | uint8_t value = directionFlags[index] & andMask;
48 | if ( dir ) {
49 | value += orMask;
50 | }
51 | directionFlags[index] = value;
52 | }
53 |
54 | void brightenOrDarkenEachPixel( fract8 fadeUpAmount, fract8 fadeDownAmount)
55 | {
56 | for ( uint16_t i = 0; i < NUM_LEDS; i++) {
57 | if ( getPixelDirection(i) == GETTING_DARKER) {
58 | // This pixel is getting darker
59 | leds[i] = makeDarker( leds[i], fadeDownAmount);
60 | } else {
61 | // This pixel is getting brighter
62 | leds[i] = makeBrighter( leds[i], fadeUpAmount);
63 | // now check to see if we've maxxed out the brightness
64 | if ( leds[i].r == 255 || leds[i].g == 255 || leds[i].b == 255) {
65 | // if so, turn around and start getting darker
66 | setPixelDirection(i, GETTING_DARKER);
67 | }
68 | }
69 | }
70 | }
71 |
72 | void colortwinkles()
73 | {
74 | // Make each pixel brighter or darker, depending on
75 | // its 'direction' flag.
76 | brightenOrDarkenEachPixel( FADE_IN_SPEED, FADE_OUT_SPEED);
77 |
78 | // Now consider adding a new random twinkle
79 | if ( random8() < DENSITY ) {
80 | int pos = random16(NUM_LEDS);
81 | if ( !leds[pos]) {
82 | leds[pos] = ColorFromPalette( gCurrentPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
83 | setPixelDirection(pos, GETTING_BRIGHTER);
84 | }
85 | }
86 | }
87 |
88 | uint8_t cloudTwinkles()
89 | {
90 | gCurrentPalette = CloudColors_p; // Blues and whites!
91 | colortwinkles();
92 | return 20;
93 | }
94 |
95 | uint8_t rainbowTwinkles()
96 | {
97 | gCurrentPalette = RainbowColors_p;
98 | colortwinkles();
99 | return 20;
100 | }
101 |
102 | uint8_t snowTwinkles()
103 | {
104 | CRGB w(85, 85, 85), W(CRGB::White);
105 |
106 | gCurrentPalette = CRGBPalette16( W, W, W, W, w, w, w, w, w, w, w, w, w, w, w, w );
107 | colortwinkles();
108 | return 20;
109 | }
110 |
111 | uint8_t incandescentTwinkles()
112 | {
113 | CRGB l(0xE1A024);
114 |
115 | gCurrentPalette = CRGBPalette16( l, l, l, l, l, l, l, l, l, l, l, l, l, l, l, l );
116 | colortwinkles();
117 | return 20;
118 | }
119 |
120 |
--------------------------------------------------------------------------------
/fibonacci-v3d.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Fibonacci v3D: https://github.com/evilgeniuslabs/fibonacci-v3d
3 | Copyright (C) 2014-2016 Jason Coon, Evil Genius Labs
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #define IR_RECV_PIN 12
24 |
25 | IRrecv irReceiver(IR_RECV_PIN);
26 |
27 | #include "Commands.h"
28 | #include "GradientPalettes.h"
29 |
30 | #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
31 |
32 | #define DATA_PIN 0
33 | // #define COLOR_ORDER RGB
34 | #define LED_TYPE WS2811
35 | #define NUM_LEDS 100
36 |
37 | CRGB leds[NUM_LEDS];
38 |
39 | const uint8_t brightnessCount = 5;
40 | uint8_t brightnessMap[brightnessCount] = { 16, 32, 64, 128, 255 };
41 | uint8_t brightness = brightnessMap[0];
42 |
43 | int patternIndex = 0;
44 | CRGB solidColor = CRGB::Red;
45 |
46 | uint8_t gHue = 0; // rotating "base color" used by many of the patterns
47 |
48 | int autoPlayDurationSeconds = 10;
49 | unsigned int autoPlayTimout = 0;
50 | bool autoplayEnabled = false;
51 |
52 | InputCommand command;
53 |
54 | CRGBPalette16 IceColors_p = CRGBPalette16(CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White);
55 |
56 | uint8_t paletteIndex = 0;
57 |
58 | // List of palettes to cycle through.
59 | CRGBPalette16 palettes[] =
60 | {
61 | RainbowColors_p,
62 | RainbowStripeColors_p,
63 | CloudColors_p,
64 | OceanColors_p,
65 | ForestColors_p,
66 | HeatColors_p,
67 | LavaColors_p,
68 | PartyColors_p,
69 | IceColors_p,
70 | };
71 |
72 | uint8_t paletteCount = ARRAY_SIZE(palettes);
73 |
74 | CRGBPalette16 currentPalette(CRGB::Black);
75 | CRGBPalette16 targetPalette = palettes[paletteIndex];
76 |
77 | // ten seconds per color palette makes a good demo
78 | // 20-120 is better for deployment
79 | #define SECONDS_PER_PALETTE 10
80 |
81 | ///////////////////////////////////////////////////////////////////////
82 |
83 | // Forward declarations of an array of cpt-city gradient palettes, and
84 | // a count of how many there are. The actual color palette definitions
85 | // are at the bottom of this file.
86 | extern const TProgmemRGBGradientPalettePtr gGradientPalettes[];
87 | extern const uint8_t gGradientPaletteCount;
88 |
89 | // Current palette number from the 'playlist' of color palettes
90 | uint8_t gCurrentPaletteNumber = 0;
91 |
92 | CRGBPalette16 gCurrentPalette( CRGB::Black);
93 | CRGBPalette16 gTargetPalette( gGradientPalettes[0] );
94 |
95 | uint8_t fibonacciToPhysicalOrder[100] = {
96 | 99, 97, 98, 96, 92, 95, 91, 93, 89, 84,
97 | 94, 90, 85, 88, 83, 86, 81, 76, 87, 82,
98 | 77, 80, 75, 78, 73, 68, 79, 74, 69, 72,
99 | 67, 70, 65, 60, 71, 66, 61, 64, 59, 62,
100 | 57, 52, 63, 58, 53, 56, 51, 54, 48, 41,
101 | 55, 50, 43, 47, 40, 45, 49, 42, 46, 39,
102 | 44, 36, 28, 33, 38, 30, 35, 27, 32, 37,
103 | 29, 34, 26, 31, 23, 15, 20, 25, 17, 22,
104 | 14, 19, 24, 16, 21, 13, 18, 10, 2, 7,
105 | 12, 4, 9, 1, 6, 11, 3, 8, 0, 5
106 | };
107 |
108 | uint8_t physicalToFibonacciOrder[100] = {
109 | 98, 93, 88, 96, 91, 99, 94, 89, 97, 92,
110 | 87, 95, 90, 85, 80, 75, 83, 78, 86, 81,
111 | 76, 84, 79, 74, 82, 77, 72, 67, 62, 70,
112 | 65, 73, 68, 63, 71, 66, 61, 69, 64, 59,
113 | 54, 49, 57, 52, 60, 55, 58, 53, 48, 56,
114 | 51, 46, 41, 44, 47, 50, 45, 40, 43, 38,
115 | 33, 36, 39, 42, 37, 32, 35, 30, 25, 28,
116 | 31, 34, 29, 24, 27, 22, 17, 20, 23, 26,
117 | 21, 16, 19, 14, 9, 12, 15, 18, 13, 8,
118 | 11, 6, 4, 7, 10, 5, 3, 1, 2, 0
119 | };
120 |
121 | // Params for width and height
122 | const uint8_t kMatrixWidth = 32;
123 | const uint8_t kMatrixHeight = 32;
124 |
125 | const uint8_t maxX = kMatrixWidth - 1;
126 | const uint8_t maxY = kMatrixHeight - 1;
127 |
128 | const uint8_t coordsX10[NUM_LEDS] = { 5, 4, 5, 5, 4, 5, 4, 4, 6, 3, 5, 5, 3, 6, 4, 4, 6, 3, 6, 4, 3, 7, 3, 5, 6, 2, 7, 4, 4, 7, 2, 6, 5, 2, 7, 3, 5, 6, 2, 7, 4, 3, 7, 2, 6, 6, 2, 8, 3, 4, 7, 1, 7, 5, 2, 8, 2, 5, 6, 1, 8, 3, 3, 8, 1, 6, 5, 1, 8, 2, 4, 7, 1, 7, 4, 2, 8, 1, 6, 6, 1, 8, 3, 3, 8, 0, 7, 5, 1, 9, 1, 5, 7, 0, 8, 3, 2, 9, 0, 6 };
129 |
130 | const uint8_t coordsY10[NUM_LEDS] = { 5, 4, 5, 4, 5, 5, 3, 6, 4, 4, 6, 3, 5, 5, 3, 6, 3, 4, 6, 2, 6, 4, 3, 7, 3, 5, 5, 2, 7, 3, 4, 7, 2, 6, 5, 3, 7, 2, 5, 6, 2, 7, 4, 3, 7, 2, 6, 5, 2, 8, 3, 4, 7, 1, 7, 4, 2, 8, 2, 5, 6, 1, 8, 3, 3, 8, 1, 7, 5, 2, 8, 2, 5, 7, 1, 8, 4, 2, 8, 1, 6, 6, 1, 8, 2, 4, 8, 0, 7, 5, 1, 9, 1, 5, 7, 0, 8, 3, 3, 9 };
131 |
132 | const uint8_t coordsX32[NUM_LEDS] = { 17, 15, 16, 18, 13, 19, 15, 14, 20, 11, 18, 18, 11, 22, 12, 15, 21, 9, 21, 16, 11, 23, 10, 18, 20, 8, 24, 13, 13, 24, 7, 21, 18, 9, 25, 9, 16, 23, 6, 24, 14, 10, 26, 6, 20, 20, 6, 27, 10, 14, 25, 4, 24, 16, 8, 28, 7, 18, 23, 4, 27, 12, 11, 28, 4, 22, 19, 5, 29, 8, 15, 26, 2, 26, 15, 8, 30, 4, 20, 23, 2, 30, 10, 12, 29, 1, 25, 18, 4, 31, 5, 17, 26, 0, 29, 12, 8, 31, 1, 22 };
133 |
134 | const uint8_t coordsY32[NUM_LEDS] = { 16, 15, 19, 14, 17, 18, 12, 20, 14, 14, 21, 11, 19, 17, 11, 22, 12, 16, 21, 9, 22, 15, 12, 24, 9, 18, 20, 8, 24, 12, 14, 24, 7, 22, 17, 9, 26, 9, 17, 22, 6, 25, 13, 11, 26, 6, 21, 19, 6, 27, 9, 15, 25, 4, 25, 15, 8, 28, 6, 19, 22, 4, 28, 11, 12, 28, 3, 23, 18, 5, 30, 7, 16, 25, 2, 27, 13, 8, 30, 3, 21, 21, 3, 30, 8, 13, 28, 1, 26, 16, 5, 31, 4, 18, 25, 1, 30, 11, 9, 31 };
135 |
136 | const uint8_t coordsX[NUM_LEDS] = { 137, 116, 130, 143, 101, 154, 119, 112, 164, 91, 146, 141, 88, 175, 100, 121, 168, 74, 168, 125, 90, 188, 77, 142, 160, 66, 189, 102, 105, 190, 59, 167, 141, 69, 204, 75, 128, 181, 48, 193, 113, 83, 210, 52, 158, 161, 48, 213, 82, 109, 203, 36, 189, 131, 61, 225, 53, 142, 184, 30, 216, 97, 85, 223, 30, 177, 154, 39, 234, 61, 120, 208, 17, 211, 117, 60, 240, 31, 159, 180, 19, 237, 77, 94, 231, 11, 198, 142, 35, 251, 40, 135, 207, 4, 232, 99, 66, 250, 11, 179 };
137 |
138 | const uint8_t coordsY[NUM_LEDS] = { 128, 117, 148, 109, 133, 144, 96, 160, 115, 113, 166, 86, 151, 138, 88, 179, 94, 126, 167, 71, 173, 120, 93, 189, 72, 148, 156, 65, 193, 95, 110, 189, 55, 174, 134, 71, 206, 69, 135, 177, 47, 199, 106, 89, 209, 47, 166, 154, 50, 217, 75, 116, 200, 33, 196, 123, 66, 225, 46, 150, 178, 31, 221, 88, 93, 221, 26, 186, 146, 43, 237, 53, 129, 202, 17, 218, 107, 68, 239, 25, 169, 172, 22, 242, 67, 103, 226, 7, 208, 132, 42, 252, 31, 146, 199, 5, 239, 88, 75, 247 };
139 |
140 | const uint8_t ledAngles[NUM_LEDS] = { 0, 158, 60, 219, 121, 23, 181, 84, 242, 144, 46, 204, 107, 9, 167, 69, 227, 130, 32, 190, 92, 251, 153, 55, 213, 115, 18, 176, 78, 236, 139, 41, 199, 101, 3, 162, 64, 222, 124, 26, 185, 87, 245, 147, 50, 208, 110, 12, 170, 73, 231, 133, 35, 193, 96, 254, 156, 58, 217, 119, 21, 179, 81, 240, 142, 44, 202, 105, 7, 165, 67, 225, 128, 30, 188, 90, 248, 151, 53, 211, 113, 16, 174, 76, 234, 136, 39, 197, 99, 1, 160, 62, 220, 122, 24, 183, 85, 243, 145, 47 };
141 |
142 | const uint8_t ledRadii[NUM_LEDS] = { 0, 3, 5, 8, 10, 13, 15, 18, 20, 23, 26, 28, 31, 33, 36, 38, 41, 44, 46, 49, 51, 54, 56, 59, 61, 64, 67, 69, 72, 74, 77, 79, 82, 84, 87, 90, 92, 95, 97, 100, 102, 105, 108, 110, 113, 115, 118, 120, 123, 125, 128, 131, 133, 136, 138, 141, 143, 146, 148, 151, 154, 156, 159, 161, 164, 166, 169, 172, 174, 177, 179, 182, 184, 187, 189, 192, 195, 197, 200, 202, 205, 207, 210, 212, 215, 218, 220, 223, 225, 228, 230, 233, 236, 238, 241, 243, 246, 248, 251, 253 };
143 |
144 | void setPixelA(uint8_t angle, uint8_t dAngle, CRGB color)
145 | {
146 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
147 | uint8_t o = physicalToFibonacciOrder[i];
148 |
149 | uint8_t ao = ledAngles[o];
150 |
151 | if (ao <= qadd8(angle, dAngle) && ao >= qsub8(angle, dAngle)) {
152 | leds[i] = color;
153 | }
154 | }
155 | }
156 |
157 | void setPixelAR(uint8_t angle, uint8_t radius, uint8_t dAngle, uint8_t dRadius, CRGB color)
158 | {
159 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
160 | uint8_t o = physicalToFibonacciOrder[i];
161 |
162 | uint8_t ao = ledAngles[o];
163 |
164 | if (ao <= qadd8(angle, dAngle) && ao >= qsub8(angle, dAngle)) {
165 | uint8_t ro = ledRadii[o];
166 |
167 | if (ro <= qadd8(radius, dRadius) && ro >= qsub8(radius, dRadius)) {
168 | leds[i] = color;
169 | }
170 | }
171 | }
172 | }
173 |
174 | void setPixelXY10(uint8_t x, uint8_t y, CRGB color)
175 | {
176 | if ((x >= 10) || (y >= 10)) {
177 | return;
178 | }
179 |
180 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
181 | uint8_t o = physicalToFibonacciOrder[i];
182 |
183 | if (coordsX10[o] == x && coordsY10[o] == y) {
184 | leds[i] = color;
185 | }
186 | }
187 | }
188 |
189 | void setPixelXY(uint8_t x, uint8_t y, CRGB color)
190 | {
191 | if ((x >= kMatrixWidth) || (y >= kMatrixHeight)) {
192 | return;
193 | }
194 |
195 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
196 | uint8_t o = physicalToFibonacciOrder[i];
197 |
198 | if (coordsX32[o] == x && coordsY32[o] == y) {
199 | leds[i] = color;
200 | return;
201 | }
202 | }
203 | }
204 |
205 | void powerOff()
206 | {
207 | // clear the display
208 | // fill_solid(leds, NUM_LEDS, CRGB::Black);
209 | for (int i = 0; i < NUM_LEDS; i++) {
210 | leds[i] = CRGB::Black;
211 | FastLED.show(); // display this frame
212 | delay(1);
213 | }
214 |
215 | FastLED.show(); // display this frame
216 |
217 | while (true) {
218 | InputCommand command = readCommand();
219 | if (command == InputCommand::Power ||
220 | command == InputCommand::Brightness)
221 | return;
222 |
223 | // go idle for a while, converve power
224 | delay(250);
225 | }
226 | }
227 |
228 | int getBrightnessLevel() {
229 | int level = 0;
230 | for (int i = 0; i < brightnessCount; i++) {
231 | if (brightnessMap[i] >= brightness) {
232 | level = i;
233 | break;
234 | }
235 | }
236 | return level;
237 | }
238 |
239 | void adjustBrightness(int delta) {
240 | int level = getBrightnessLevel();
241 |
242 | level += delta;
243 | if (level < 0)
244 | level = brightnessCount - 1;
245 | if (level >= brightnessCount)
246 | level = 0;
247 |
248 | brightness = brightnessMap[level];
249 | FastLED.setBrightness(brightness);
250 |
251 | EEPROM.write(0, brightness);
252 | }
253 |
254 | uint8_t cycleBrightness() {
255 | adjustBrightness(1);
256 |
257 | if (brightness == brightnessMap[0])
258 | return 8;
259 |
260 | return brightness;
261 | }
262 |
263 | // algorithm from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
264 | void drawCircle(uint8_t x0, uint8_t y0, uint8_t radius, const CRGB color)
265 | {
266 | int a = radius, b = 0;
267 | int radiusError = 1 - a;
268 |
269 | if (radius == 0) {
270 | setPixelXY(x0, y0, color);
271 | return;
272 | }
273 |
274 | while (a >= b)
275 | {
276 | setPixelXY(a + x0, b + y0, color);
277 | setPixelXY(b + x0, a + y0, color);
278 | setPixelXY(-a + x0, b + y0, color);
279 | setPixelXY(-b + x0, a + y0, color);
280 | setPixelXY(-a + x0, -b + y0, color);
281 | setPixelXY(-b + x0, -a + y0, color);
282 | setPixelXY(a + x0, -b + y0, color);
283 | setPixelXY(b + x0, -a + y0, color);
284 |
285 | b++;
286 | if (radiusError < 0)
287 | radiusError += 2 * b + 1;
288 | else
289 | {
290 | a--;
291 | radiusError += 2 * (b - a + 1);
292 | }
293 | }
294 | }
295 |
296 | // scale the brightness of all pixels down
297 | void dimAll(byte value)
298 | {
299 | for (int i = 0; i < NUM_LEDS; i++) {
300 | leds[i].nscale8(value);
301 | }
302 | }
303 |
304 | // Patterns from FastLED example DemoReel100: https://github.com/FastLED/FastLED/blob/master/examples/DemoReel100/DemoReel100.ino
305 |
306 | uint8_t rainbow()
307 | {
308 | // FastLED's built-in rainbow generator
309 | fill_rainbow( leds, NUM_LEDS, gHue, 255 / NUM_LEDS);
310 | return 8;
311 | }
312 |
313 | void addGlitter( uint8_t chanceOfGlitter)
314 | {
315 | if ( random8() < chanceOfGlitter) {
316 | leds[ random16(NUM_LEDS) ] += CRGB::White;
317 | }
318 | }
319 |
320 | uint8_t rainbowWithGlitter()
321 | {
322 | // built-in FastLED rainbow, plus some random sparkly glitter
323 | rainbow();
324 | addGlitter(80);
325 | return 8;
326 | }
327 |
328 | uint8_t rainbowSolid()
329 | {
330 | fill_solid(leds, NUM_LEDS, CHSV(gHue, 255, 255));
331 | return 8;
332 | }
333 |
334 | uint8_t confetti()
335 | {
336 | // random colored speckles that blink in and fade smoothly
337 | fadeToBlackBy( leds, NUM_LEDS, 10);
338 | int pos = random16(NUM_LEDS);
339 | leds[pos] += CHSV( gHue + random8(64), 200, 255);
340 | return 8;
341 | }
342 |
343 | uint8_t sinelon1()
344 | {
345 | // a colored dot sweeping back and forth, with fading trails
346 | fadeToBlackBy( leds, NUM_LEDS, 20);
347 | int pos = beatsin16(13, 0, NUM_LEDS);
348 | leds[fibonacciToPhysicalOrder[pos]] += CHSV( gHue, 255, 192);
349 | return 8;
350 | }
351 |
352 | uint8_t sinelon2()
353 | {
354 | // a colored dot sweeping back and forth, with fading trails
355 | fadeToBlackBy( leds, NUM_LEDS, 20);
356 | int pos = beatsin16(13, 0, NUM_LEDS);
357 | leds[pos] += CHSV( gHue, 255, 192);
358 | return 8;
359 | }
360 |
361 | uint8_t bpm1()
362 | {
363 | // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
364 | uint8_t BeatsPerMinute = 62;
365 | uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
366 | for ( int i = 0; i < NUM_LEDS; i++) { //9948
367 | leds[fibonacciToPhysicalOrder[i]] = ColorFromPalette(currentPalette, gHue + (i * 2), beat - gHue + (i * 10));
368 | }
369 |
370 | return 8;
371 | }
372 |
373 | uint8_t bpm2()
374 | {
375 | // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
376 | uint8_t BeatsPerMinute = 62;
377 | uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
378 | for ( int i = 0; i < NUM_LEDS; i++) { //9948
379 | leds[i] = ColorFromPalette(currentPalette, gHue + (i * 2), beat - gHue + (i * 10));
380 | }
381 |
382 | return 8;
383 | }
384 |
385 | uint8_t juggle() {
386 | // eight colored dots, weaving in and out of sync with each other
387 | fadeToBlackBy( leds, NUM_LEDS, 20);
388 | byte dothue = 0;
389 | uint8_t dotcount = 3;
390 | for ( int i = 0; i < dotcount; i++) {
391 | leds[beatsin16(i + (dotcount - 1), 0, NUM_LEDS)] |= CHSV(dothue, 200, 255);
392 | dothue += (256 / dotcount);
393 | }
394 |
395 | return 8;
396 | }
397 |
398 | uint8_t juggle2()
399 | {
400 | static uint8_t numdots = 4; // Number of dots in use.
401 | static uint8_t faderate = 2; // How long should the trails be. Very low value = longer trails.
402 | static uint8_t hueinc = 255 / numdots - 1; // Incremental change in hue between each dot.
403 | static uint8_t thishue = 0; // Starting hue.
404 | static uint8_t curhue = 0; // The current hue
405 | static uint8_t thissat = 255; // Saturation of the colour.
406 | static uint8_t thisbright = 255; // How bright should the LED/display be.
407 | static uint8_t basebeat = 5; // Higher = faster movement.
408 |
409 | static uint8_t lastSecond = 99; // Static variable, means it's only defined once. This is our 'debounce' variable.
410 | uint8_t secondHand = (millis() / 1000) % 30; // IMPORTANT!!! Change '30' to a different value to change duration of the loop.
411 |
412 | if (lastSecond != secondHand) { // Debounce to make sure we're not repeating an assignment.
413 | lastSecond = secondHand;
414 | switch (secondHand) {
415 | case 0: numdots = 1; basebeat = 20; hueinc = 16; faderate = 2; thishue = 0; break; // You can change values here, one at a time , or altogether.
416 | case 10: numdots = 4; basebeat = 10; hueinc = 16; faderate = 8; thishue = 128; break;
417 | case 20: numdots = 8; basebeat = 3; hueinc = 0; faderate = 8; thishue = random8(); break; // Only gets called once, and not continuously for the next several seconds. Therefore, no rainbows.
418 | case 30: break;
419 | }
420 | }
421 |
422 | // Several colored dots, weaving in and out of sync with each other
423 | curhue = thishue; // Reset the hue values.
424 | fadeToBlackBy(leds, NUM_LEDS, faderate);
425 | for ( int i = 0; i < numdots; i++) {
426 | //beat16 is a FastLED 3.1 function
427 | leds[beatsin16(basebeat + i + numdots, 0, NUM_LEDS)] += CHSV(gHue + curhue, thissat, thisbright);
428 | curhue += hueinc;
429 | }
430 |
431 | return 8;
432 | }
433 |
434 | // based on FastLED example Fire2012WithPalette: https://github.com/FastLED/FastLED/blob/master/examples/Fire2012WithPalette/Fire2012WithPalette.ino
435 | void heatMap(CRGBPalette16 palette, bool up)
436 | {
437 | fill_solid(leds, NUM_LEDS, CRGB::Black);
438 |
439 | // Add entropy to random number generator; we use a lot of it.
440 | random16_add_entropy(random(256));
441 |
442 | // COOLING: How much does the air cool as it rises?
443 | // Less cooling = taller flames. More cooling = shorter flames.
444 | // Default 55, suggested range 20-100
445 | uint8_t cooling = 55;
446 |
447 | // SPARKING: What chance (out of 255) is there that a new spark will be lit?
448 | // Higher chance = more roaring fire. Lower chance = more flickery fire.
449 | // Default 120, suggested range 50-200.
450 | uint8_t sparking = 120;
451 |
452 | // Array of temperature readings at each simulation cell
453 | static byte heat[kMatrixWidth + 3][kMatrixHeight + 3];
454 |
455 | for (int x = 0; x < 10; x++)
456 | {
457 | // Step 1. Cool down every cell a little
458 | for (int y = 0; y < 10; y++)
459 | {
460 | heat[x][y] = qsub8(heat[x][y], random8(0, ((cooling * 10) / kMatrixHeight) + 2));
461 | }
462 |
463 | // Step 2. Heat from each cell drifts 'up' and diffuses a little
464 | for (int y = 0; y < kMatrixHeight; y++)
465 | {
466 | heat[x][y] = (heat[x][y + 1] + heat[x][y + 2] + heat[x][y + 2]) / 3;
467 | }
468 |
469 | // Step 2. Randomly ignite new 'sparks' of heat
470 | if (random8() < sparking)
471 | {
472 | heat[x][maxY] = qadd8(heat[x][maxY], random8(160, 255));
473 | }
474 |
475 | // Step 4. Map from heat cells to LED colors
476 | for (int y = 0; y < kMatrixHeight; y++)
477 | {
478 | uint8_t colorIndex = 0;
479 |
480 | if (up)
481 | colorIndex = heat[x][y];
482 | else
483 | colorIndex = heat[x][(maxY) - y];
484 |
485 | // Recommend that you use values 0-240 rather than
486 | // the usual 0-255, as the last 15 colors will be
487 | // 'wrapping around' from the hot end to the cold end,
488 | // which looks wrong.
489 | colorIndex = scale8(colorIndex, 240);
490 |
491 | // override color 0 to ensure a black background
492 | if (colorIndex != 0)
493 | {
494 | setPixelXY10(x, y, ColorFromPalette(palette, colorIndex, 255, LINEARBLEND));
495 | }
496 | }
497 | }
498 | }
499 |
500 | uint8_t fire()
501 | {
502 | heatMap(HeatColors_p, true);
503 |
504 | return 30;
505 | }
506 |
507 | uint8_t water()
508 | {
509 | heatMap(IceColors_p, false);
510 |
511 | return 30;
512 | }
513 |
514 | uint8_t showSolidColor()
515 | {
516 | fill_solid(leds, NUM_LEDS, solidColor);
517 |
518 | return 30;
519 | }
520 |
521 | uint8_t incrementalDrift() {
522 | uint8_t stepwidth = 256 * (20 - 1) / NUM_LEDS;
523 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
524 | uint8_t bri = beatsin88(1 * 256 + (NUM_LEDS - i) * stepwidth, 0, 256);
525 | leds[fibonacciToPhysicalOrder[i]] = ColorFromPalette(gCurrentPalette, 2.5 * i + gHue, bri, LINEARBLEND);
526 | }
527 |
528 | return 8;
529 | }
530 |
531 | // Pride2015 by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5
532 | // This function draws rainbows with an ever-changing,
533 | // widely-varying set of parameters.
534 | uint8_t pride(bool useFibonacciOrder) {
535 | static uint16_t sPseudotime = 0;
536 | static uint16_t sLastMillis = 0;
537 | static uint16_t sHue16 = 0;
538 |
539 | uint8_t sat8 = beatsin88( 87, 220, 250);
540 | uint8_t brightdepth = beatsin88( 341, 96, 224);
541 | uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
542 | uint8_t msmultiplier = beatsin88(147, 23, 60);
543 |
544 | uint16_t hue16 = sHue16;//gHue * 256;
545 | uint16_t hueinc16 = beatsin88(113, 1, 3000);
546 |
547 | uint16_t ms = millis();
548 | uint16_t deltams = ms - sLastMillis ;
549 | sLastMillis = ms;
550 | sPseudotime += deltams * msmultiplier;
551 | sHue16 += deltams * beatsin88( 400, 5, 9);
552 | uint16_t brightnesstheta16 = sPseudotime;
553 |
554 | for ( uint16_t i = 0 ; i < NUM_LEDS; i++) {
555 | hue16 += hueinc16;
556 | uint8_t hue8 = hue16 / 256;
557 |
558 | brightnesstheta16 += brightnessthetainc16;
559 | uint16_t b16 = sin16( brightnesstheta16 ) + 32768;
560 |
561 | uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
562 | uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
563 | bri8 += (255 - brightdepth);
564 |
565 | CRGB newcolor = CHSV( hue8, sat8, bri8);
566 |
567 | uint16_t pixelnumber = i;
568 |
569 | if (useFibonacciOrder) {
570 | pixelnumber = fibonacciToPhysicalOrder[(NUM_LEDS - 1) - pixelnumber];
571 | }
572 |
573 | nblend(leds[pixelnumber], newcolor, 64);
574 | }
575 |
576 | return 15;
577 | }
578 |
579 | uint8_t pride1()
580 | {
581 | return pride(true);
582 | }
583 |
584 | uint8_t pride2()
585 | {
586 | return pride(false);
587 | }
588 |
589 | uint8_t radialPaletteShift()
590 | {
591 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
592 | // leds[i] = ColorFromPalette( currentPalette, gHue + sin8(i*16), brightness);
593 | uint8_t index = fibonacciToPhysicalOrder[(NUM_LEDS - 1) - i];
594 |
595 | leds[index] = ColorFromPalette(gCurrentPalette, i + gHue, 255, LINEARBLEND);
596 | }
597 |
598 | return 8;
599 | }
600 |
601 | uint8_t horizontalPaletteBlend()
602 | {
603 | uint8_t offset = 0;
604 |
605 | for (uint8_t x = 0; x <= kMatrixWidth; x++)
606 | {
607 | CRGB color = ColorFromPalette(currentPalette, gHue + offset, 255, LINEARBLEND);
608 |
609 | for (uint8_t y = 0; y <= kMatrixHeight; y++)
610 | {
611 | setPixelXY(x, y, color);
612 | }
613 |
614 | offset++;
615 | }
616 |
617 | return 15;
618 | }
619 |
620 | uint8_t verticalPaletteBlend()
621 | {
622 | uint8_t offset = 0;
623 |
624 | for (uint8_t y = 0; y <= kMatrixHeight; y++)
625 | {
626 | CRGB color = ColorFromPalette(currentPalette, gHue + offset, 255, LINEARBLEND);
627 |
628 | for (uint8_t x = 0; x <= kMatrixWidth; x++)
629 | {
630 | setPixelXY(x, y, color);
631 | }
632 |
633 | offset++;
634 | }
635 |
636 | return 15;
637 | }
638 |
639 | uint8_t nyan()
640 | {
641 | static uint8_t offset = 0;
642 |
643 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
644 | uint8_t j = physicalToFibonacciOrder[i];
645 | leds[i] = ColorFromPalette(gCurrentPalette, ledRadii[j] + offset, ledAngles[j] - offset);
646 | // leds[i] = CHSV(255 - ledRadii[j], 255, ledAngles[j] - offset);
647 | }
648 |
649 | EVERY_N_MILLISECONDS(15) { offset++; };
650 |
651 | return 8;
652 | }
653 |
654 | uint8_t radialWavesWithCircular()
655 | {
656 | dimAll(253);
657 |
658 | static uint8_t prevB = 0;
659 | static bool spiral = false;
660 |
661 | uint8_t b = beatsin8(8);
662 |
663 | if(b < prevB){
664 | random16_add_entropy(random());
665 | if(random8() > 254) {
666 | spiral = true;
667 | }
668 | }
669 |
670 | prevB = b;
671 |
672 | // EVERY_N_SECONDS(5) { spiral = true; }
673 |
674 | if(spiral) {
675 | static uint8_t angle = random8();
676 | static uint8_t radius = 255;
677 |
678 | setPixelAR(angle, radius, 24, 20, CRGB::White);
679 |
680 | if(radius < 1) {
681 | spiral = false;
682 | radius = 255;
683 | angle = random8();
684 | }
685 |
686 | radius -= 1;
687 | angle -= 2;
688 | }
689 |
690 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
691 | uint8_t j = physicalToFibonacciOrder[i];
692 | leds[i] |= ColorFromPalette(gCurrentPalette, ledRadii[j] - b);
693 | }
694 |
695 | return 1;
696 | }
697 |
698 | uint8_t circular()
699 | {
700 | dimAll(253);
701 |
702 | static uint8_t offset = 0;
703 |
704 | uint8_t angle = beat8(60);
705 | uint8_t radius = beatsin8(16);
706 |
707 | setPixelAR(angle, radius, 24, 20, ColorFromPalette(gCurrentPalette, offset));
708 | // setPixelAR(angle, radius, 24, 20, CHSV(offset, 255, 255));
709 |
710 | EVERY_N_MILLISECONDS(15) { offset++; };
711 |
712 | return 8;
713 | }
714 |
715 | uint8_t radar()
716 | {
717 | dimAll(253);
718 | static uint8_t offset = 0;
719 |
720 | // uint8_t a = sin8(offset);
721 | // uint8_t r = cos8(offset);
722 |
723 | setPixelA(offset, 24, CRGB::Red);
724 |
725 | EVERY_N_MILLISECONDS(15) { offset++; };
726 |
727 | return 1;
728 | }
729 |
730 | uint8_t angular()
731 | {
732 | static uint8_t offset = 0;
733 |
734 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
735 | uint8_t j = physicalToFibonacciOrder[i];
736 | leds[i] = ColorFromPalette(gCurrentPalette, ledAngles[j] + offset);
737 | // leds[i] = CHSV(ledAngles[j] + offset, 255, 255);
738 | }
739 |
740 | EVERY_N_MILLISECONDS(15) { offset++; };
741 |
742 | return 8;
743 | }
744 |
745 | uint8_t angular2()
746 | {
747 | static uint8_t offset = 0;
748 |
749 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
750 | uint8_t j = physicalToFibonacciOrder[i];
751 | leds[i] = ColorFromPalette(gCurrentPalette, ledAngles[j] + offset, ledRadii[j]);
752 | // leds[i] = CHSV(ledAngles[j] + offset, 255, 255 - ledRadii[j]);
753 | }
754 |
755 | EVERY_N_MILLISECONDS(15) { offset++; };
756 |
757 | return 8;
758 | }
759 |
760 | uint8_t radial()
761 | {
762 | static uint8_t offset = 0;
763 |
764 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
765 | uint8_t j = physicalToFibonacciOrder[i];
766 | leds[i] = ColorFromPalette(gCurrentPalette, ledRadii[j] + offset);
767 | // leds[i] = CHSV(ledRadii[j] + offset, 255, 255);
768 | }
769 |
770 | EVERY_N_MILLISECONDS(15) { offset++; };
771 |
772 | return 8;
773 | }
774 |
775 | uint8_t radial2()
776 | {
777 | static uint8_t offset = 0;
778 |
779 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
780 | uint8_t j = physicalToFibonacciOrder[i];
781 | leds[i] = ColorFromPalette(gCurrentPalette, ledRadii[j] - offset);
782 | // leds[i] = CHSV(ledRadii[j] + offset, ledAngles[j], 255);
783 | }
784 |
785 | EVERY_N_MILLISECONDS(15) { offset++; };
786 |
787 | return 8;
788 | }
789 |
790 | uint8_t radialWaves()
791 | {
792 | static uint8_t offset = 0;
793 |
794 | uint8_t b = beatsin8(8);
795 |
796 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
797 | uint8_t j = physicalToFibonacciOrder[i];
798 | leds[i] = ColorFromPalette(gCurrentPalette, ledRadii[j] - b);
799 | // leds[i] = CHSV(ledRadii[j] + offset, ledAngles[j], 255);
800 | }
801 |
802 | EVERY_N_MILLISECONDS(15) { offset++; };
803 |
804 | return 1;
805 | }
806 |
807 | uint8_t radial3()
808 | {
809 | static uint8_t offset = 0;
810 |
811 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
812 | uint8_t j = physicalToFibonacciOrder[i];
813 | leds[i] = ColorFromPalette(gCurrentPalette, ledRadii[j] + offset, ledAngles[j] - offset);
814 | // leds[i] = CHSV(ledRadii[j] + offset, 255, ledAngles[j]);
815 | }
816 |
817 | EVERY_N_MILLISECONDS(15) { offset++; };
818 |
819 | return 8;
820 | }
821 |
822 | CRGB scrollingHorizontalWashColor( uint8_t x, uint8_t y, unsigned long timeInMillis)
823 | {
824 | return CHSV( x + (timeInMillis / 10), 255, 255);
825 | }
826 |
827 | uint8_t horizontalRainbow()
828 | {
829 | unsigned long t = millis();
830 |
831 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
832 | uint8_t j = physicalToFibonacciOrder[i];
833 | leds[i] = scrollingHorizontalWashColor(coordsX[j], coordsY[j], t);
834 | }
835 |
836 | return 8;
837 | }
838 |
839 | CRGB scrollingVerticalWashColor( uint8_t x, uint8_t y, unsigned long timeInMillis)
840 | {
841 | return CHSV( y + (timeInMillis / 10), 255, 255);
842 | }
843 |
844 | uint8_t verticalRainbow()
845 | {
846 | unsigned long t = millis();
847 |
848 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
849 | uint8_t j = physicalToFibonacciOrder[i];
850 | leds[i] = scrollingVerticalWashColor(coordsX[j], coordsY[j], t);
851 | }
852 |
853 | return 8;
854 | }
855 |
856 | CRGB scrollingDiagonalWashColor( uint8_t x, uint8_t y, unsigned long timeInMillis)
857 | {
858 | return CHSV( x + y + (timeInMillis / 10), 255, 255);
859 | }
860 |
861 | uint8_t diagonalRainbow()
862 | {
863 | unsigned long t = millis();
864 |
865 | for (uint8_t i = 0; i < NUM_LEDS; i++) {
866 | uint8_t j = physicalToFibonacciOrder[i];
867 | leds[i] = scrollingDiagonalWashColor(coordsX[j], coordsY[j], t);
868 | }
869 |
870 | return 8;
871 | }
872 |
873 | uint8_t wave()
874 | {
875 | const uint8_t scale = 256 / kMatrixWidth;
876 |
877 | static uint8_t rotation = 0;
878 | static uint8_t theta = 0;
879 | static uint8_t waveCount = 1;
880 |
881 | uint8_t n = 0;
882 |
883 | switch (rotation) {
884 | case 0:
885 | for (int x = 0; x < kMatrixWidth; x++) {
886 | n = quadwave8(x * 2 + theta) / scale;
887 | setPixelXY(x, n, ColorFromPalette(currentPalette, x + gHue, 255, LINEARBLEND));
888 | if (waveCount == 2)
889 | setPixelXY(x, maxY - n, ColorFromPalette(currentPalette, x + gHue, 255, LINEARBLEND));
890 | }
891 | break;
892 |
893 | case 1:
894 | for (int y = 0; y < kMatrixHeight; y++) {
895 | n = quadwave8(y * 2 + theta) / scale;
896 | setPixelXY(n, y, ColorFromPalette(currentPalette, y + gHue, 255, LINEARBLEND));
897 | if (waveCount == 2)
898 | setPixelXY(maxX - n, y, ColorFromPalette(currentPalette, y + gHue, 255, LINEARBLEND));
899 | }
900 | break;
901 |
902 | case 2:
903 | for (int x = 0; x < kMatrixWidth; x++) {
904 | n = quadwave8(x * 2 - theta) / scale;
905 | setPixelXY(x, n, ColorFromPalette(currentPalette, x + gHue));
906 | if (waveCount == 2)
907 | setPixelXY(x, maxY - n, ColorFromPalette(currentPalette, x + gHue, 255, LINEARBLEND));
908 | }
909 | break;
910 |
911 | case 3:
912 | for (int y = 0; y < kMatrixHeight; y++) {
913 | n = quadwave8(y * 2 - theta) / scale;
914 | setPixelXY(n, y, ColorFromPalette(currentPalette, y + gHue, 255, LINEARBLEND));
915 | if (waveCount == 2)
916 | setPixelXY(maxX - n, y, ColorFromPalette(currentPalette, y + gHue, 255, LINEARBLEND));
917 | }
918 | break;
919 | }
920 |
921 | dimAll(255);
922 |
923 | EVERY_N_SECONDS(10)
924 | {
925 | rotation = random(0, 4);
926 | // waveCount = random(1, 3);
927 | };
928 |
929 | EVERY_N_MILLISECONDS(7) {
930 | theta++;
931 | }
932 |
933 | return 8;
934 | }
935 |
936 | uint8_t pulse()
937 | {
938 | dimAll(200);
939 |
940 | uint8_t maxSteps = 16;
941 | static uint8_t step = maxSteps;
942 | static uint8_t centerX = 0;
943 | static uint8_t centerY = 0;
944 | float fadeRate = 0.8;
945 |
946 | if (step >= maxSteps)
947 | {
948 | centerX = random(kMatrixWidth);
949 | centerY = random(kMatrixWidth);
950 | step = 0;
951 | }
952 |
953 | if (step == 0)
954 | {
955 | drawCircle(centerX, centerY, step, ColorFromPalette(currentPalette, gHue, 255, LINEARBLEND));
956 | step++;
957 | }
958 | else
959 | {
960 | if (step < maxSteps)
961 | {
962 | // initial pulse
963 | drawCircle(centerX, centerY, step, ColorFromPalette(currentPalette, gHue, pow(fadeRate, step - 2) * 255, LINEARBLEND));
964 |
965 | // secondary pulse
966 | if (step > 3) {
967 | drawCircle(centerX, centerY, step - 3, ColorFromPalette(currentPalette, gHue, pow(fadeRate, step - 2) * 255, LINEARBLEND));
968 | }
969 |
970 | step++;
971 | }
972 | else
973 | {
974 | step = -1;
975 | }
976 | }
977 |
978 | return 30;
979 | }
980 |
981 | // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
982 | // This function draws color waves with an ever-changing,
983 | // widely-varying set of parameters, using a color palette.
984 | void colorwaves( CRGB* ledarray, uint16_t numleds, CRGBPalette16& palette, bool useFibonacciOrder)
985 | {
986 | static uint16_t sPseudotime = 0;
987 | static uint16_t sLastMillis = 0;
988 | static uint16_t sHue16 = 0;
989 |
990 | // uint8_t sat8 = beatsin88( 87, 220, 250);
991 | uint8_t brightdepth = beatsin88( 341, 96, 224);
992 | uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
993 | uint8_t msmultiplier = beatsin88(147, 23, 60);
994 |
995 | uint16_t hue16 = sHue16;//gHue * 256;
996 | uint16_t hueinc16 = beatsin88(113, 300, 1500);
997 |
998 | uint16_t ms = millis();
999 | uint16_t deltams = ms - sLastMillis ;
1000 | sLastMillis = ms;
1001 | sPseudotime += deltams * msmultiplier;
1002 | sHue16 += deltams * beatsin88( 400, 5, 9);
1003 | uint16_t brightnesstheta16 = sPseudotime;
1004 |
1005 | for ( uint16_t i = 0 ; i < numleds; i++) {
1006 | hue16 += hueinc16;
1007 | uint8_t hue8 = hue16 / 256;
1008 | uint16_t h16_128 = hue16 >> 7;
1009 | if ( h16_128 & 0x100) {
1010 | hue8 = 255 - (h16_128 >> 1);
1011 | } else {
1012 | hue8 = h16_128 >> 1;
1013 | }
1014 |
1015 | brightnesstheta16 += brightnessthetainc16;
1016 | uint16_t b16 = sin16( brightnesstheta16 ) + 32768;
1017 |
1018 | uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
1019 | uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
1020 | bri8 += (255 - brightdepth);
1021 |
1022 | uint8_t index = hue8;
1023 | //index = triwave8( index);
1024 | index = scale8( index, 240);
1025 |
1026 | CRGB newcolor = ColorFromPalette( palette, index, bri8);
1027 |
1028 | uint16_t pixelnumber = i;
1029 |
1030 | if (useFibonacciOrder) {
1031 | pixelnumber = fibonacciToPhysicalOrder[(numleds - 1) - pixelnumber];
1032 | }
1033 |
1034 | nblend( ledarray[pixelnumber], newcolor, 128);
1035 | }
1036 | }
1037 |
1038 | uint8_t colorWaves1()
1039 | {
1040 | colorwaves( leds, NUM_LEDS, gCurrentPalette, true);
1041 | return 20;
1042 | }
1043 |
1044 | uint8_t colorWaves2()
1045 | {
1046 | colorwaves( leds, NUM_LEDS, gCurrentPalette, false);
1047 | return 20;
1048 | }
1049 |
1050 | // Alternate rendering function just scrolls the current palette
1051 | // across the defined LED strip.
1052 | void palettetest( CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrentPalette)
1053 | {
1054 | static uint8_t startindex = 0;
1055 | startindex--;
1056 | fill_palette( ledarray, numleds, startindex, (256 / NUM_LEDS) + 1, gCurrentPalette, 255, LINEARBLEND);
1057 | }
1058 |
1059 | typedef uint8_t (*SimplePattern)();
1060 | typedef SimplePattern SimplePatternList[];
1061 |
1062 | // List of patterns to cycle through. Each is defined as a separate function below.
1063 |
1064 | #include "Life.h"
1065 | #include "Twinkles.h"
1066 | #include "Noise.h"
1067 |
1068 | const SimplePatternList patterns = {
1069 | // Fibonacci patterns
1070 | pride1,
1071 | pride2,
1072 | colorWaves1,
1073 | colorWaves2,
1074 | incrementalDrift,
1075 |
1076 | // palette shifting/blending patterns
1077 | radialPaletteShift,
1078 | verticalPaletteBlend,
1079 | horizontalPaletteBlend,
1080 | horizontalRainbow,
1081 | verticalRainbow,
1082 | diagonalRainbow,
1083 |
1084 | // noise patterns
1085 | fireNoise,
1086 | fireNoise2,
1087 | lavaNoise,
1088 | rainbowNoise,
1089 | rainbowStripeNoise,
1090 | partyNoise,
1091 | forestNoise,
1092 | cloudNoise,
1093 | oceanNoise,
1094 | blackAndWhiteNoise,
1095 | blackAndBlueNoise,
1096 |
1097 | // radial patterns
1098 | radialWavesWithCircular,
1099 | radialWaves,
1100 | radial,
1101 | radial2,
1102 | radial3,
1103 | nyan,
1104 | circular,
1105 | angular,
1106 | angular2,
1107 |
1108 | // 2D XY patterns
1109 | wave,
1110 | life,
1111 | pulse,
1112 | fire,
1113 | water,
1114 |
1115 | // 1D patterns
1116 | rainbow,
1117 | rainbowWithGlitter,
1118 | rainbowSolid,
1119 | sinelon1,
1120 | sinelon2,
1121 | bpm1,
1122 | bpm2,
1123 | juggle,
1124 | juggle2,
1125 | confetti,
1126 | rainbowTwinkles,
1127 | snowTwinkles,
1128 | cloudTwinkles,
1129 | incandescentTwinkles,
1130 |
1131 | showSolidColor,
1132 | };
1133 |
1134 | int patternCount = ARRAY_SIZE(patterns);
1135 |
1136 | void moveTo(int index) {
1137 | patternIndex = index;
1138 |
1139 | if (patternIndex >= patternCount)
1140 | patternIndex = 0;
1141 | else if (patternIndex < 0)
1142 | patternIndex = patternCount - 1;
1143 |
1144 | fill_solid(leds, NUM_LEDS, CRGB::Black);
1145 |
1146 | EEPROM.write(1, patternIndex);
1147 | }
1148 |
1149 | void move(int delta) {
1150 | moveTo(patternIndex + delta);
1151 | }
1152 |
1153 | void loadSettings() {
1154 | // load settings from EEPROM
1155 |
1156 | // brightness
1157 | brightness = EEPROM.read(0);
1158 | if (brightness < 1)
1159 | brightness = 1;
1160 | else if (brightness > 255)
1161 | brightness = 255;
1162 |
1163 | // patternIndex
1164 | patternIndex = EEPROM.read(1);
1165 | if (patternIndex < 0)
1166 | patternIndex = 0;
1167 | else if (patternIndex >= patternCount)
1168 | patternIndex = patternCount - 1;
1169 |
1170 | // solidColor
1171 | solidColor.r = EEPROM.read(2);
1172 | solidColor.g = EEPROM.read(3);
1173 | solidColor.b = EEPROM.read(4);
1174 |
1175 | if (solidColor.r == 0 && solidColor.g == 0 && solidColor.b == 0)
1176 | solidColor = CRGB::White;
1177 | }
1178 |
1179 | void setSolidColor(CRGB color) {
1180 | solidColor = color;
1181 |
1182 | EEPROM.write(2, solidColor.r);
1183 | EEPROM.write(3, solidColor.g);
1184 | EEPROM.write(4, solidColor.b);
1185 |
1186 | moveTo(patternCount - 1);
1187 | }
1188 |
1189 | void handleInput(unsigned int requestedDelay) {
1190 | unsigned int requestedDelayTimeout = millis() + requestedDelay;
1191 |
1192 | while (true) {
1193 | command = readCommand(defaultHoldDelay);
1194 |
1195 | if (command != InputCommand::None) {
1196 | Serial.print("command: ");
1197 | Serial.println((int) command);
1198 | }
1199 |
1200 | if (command == InputCommand::Up) {
1201 | move(1);
1202 | break;
1203 | }
1204 | else if (command == InputCommand::Down) {
1205 | move(-1);
1206 | break;
1207 | }
1208 | else if (command == InputCommand::Brightness) {
1209 | if (isHolding || cycleBrightness() == 0) {
1210 | heldButtonHasBeenHandled();
1211 | powerOff();
1212 | break;
1213 | }
1214 | }
1215 | else if (command == InputCommand::Power) {
1216 | powerOff();
1217 | break;
1218 | }
1219 | else if (command == InputCommand::BrightnessUp) {
1220 | adjustBrightness(1);
1221 | }
1222 | else if (command == InputCommand::BrightnessDown) {
1223 | adjustBrightness(-1);
1224 | }
1225 | else if (command == InputCommand::PlayMode) { // toggle pause/play
1226 | autoplayEnabled = !autoplayEnabled;
1227 | }
1228 | //else if (command == InputCommand::Palette) { // cycle color pallete
1229 | // effects.CyclePalette();
1230 | //}
1231 |
1232 | // pattern buttons
1233 |
1234 | else if (command == InputCommand::Pattern1) {
1235 | moveTo(0);
1236 | break;
1237 | }
1238 | else if (command == InputCommand::Pattern2) {
1239 | moveTo(1);
1240 | break;
1241 | }
1242 | else if (command == InputCommand::Pattern3) {
1243 | moveTo(2);
1244 | break;
1245 | }
1246 | else if (command == InputCommand::Pattern4) {
1247 | moveTo(3);
1248 | break;
1249 | }
1250 | else if (command == InputCommand::Pattern5) {
1251 | moveTo(4);
1252 | break;
1253 | }
1254 | else if (command == InputCommand::Pattern6) {
1255 | moveTo(5);
1256 | break;
1257 | }
1258 | else if (command == InputCommand::Pattern7) {
1259 | moveTo(6);
1260 | break;
1261 | }
1262 | else if (command == InputCommand::Pattern8) {
1263 | moveTo(7);
1264 | break;
1265 | }
1266 | else if (command == InputCommand::Pattern9) {
1267 | moveTo(8);
1268 | break;
1269 | }
1270 | else if (command == InputCommand::Pattern10) {
1271 | moveTo(9);
1272 | break;
1273 | }
1274 | else if (command == InputCommand::Pattern11) {
1275 | moveTo(10);
1276 | break;
1277 | }
1278 | else if (command == InputCommand::Pattern12) {
1279 | moveTo(11);
1280 | break;
1281 | }
1282 |
1283 | // custom color adjustment buttons
1284 |
1285 | else if (command == InputCommand::RedUp) {
1286 | solidColor.red += 1;
1287 | setSolidColor(solidColor);
1288 | break;
1289 | }
1290 | else if (command == InputCommand::RedDown) {
1291 | solidColor.red -= 1;
1292 | setSolidColor(solidColor);
1293 | break;
1294 | }
1295 | else if (command == InputCommand::GreenUp) {
1296 | solidColor.green += 1;
1297 | setSolidColor(solidColor);
1298 |
1299 | break;
1300 | }
1301 | else if (command == InputCommand::GreenDown) {
1302 | solidColor.green -= 1;
1303 | setSolidColor(solidColor);
1304 | break;
1305 | }
1306 | else if (command == InputCommand::BlueUp) {
1307 | solidColor.blue += 1;
1308 | setSolidColor(solidColor);
1309 | break;
1310 | }
1311 | else if (command == InputCommand::BlueDown) {
1312 | solidColor.blue -= 1;
1313 | setSolidColor(solidColor);
1314 | break;
1315 | }
1316 |
1317 | // color buttons
1318 |
1319 | else if (command == InputCommand::Red) {
1320 | setSolidColor(CRGB::Red);
1321 | break;
1322 | }
1323 | else if (command == InputCommand::RedOrange) {
1324 | setSolidColor(CRGB::OrangeRed);
1325 | break;
1326 | }
1327 | else if (command == InputCommand::Orange) {
1328 | setSolidColor(CRGB::Orange);
1329 | break;
1330 | }
1331 | else if (command == InputCommand::YellowOrange) {
1332 | setSolidColor(CRGB::Goldenrod);
1333 | break;
1334 | }
1335 | else if (command == InputCommand::Yellow) {
1336 | setSolidColor(CRGB::Yellow);
1337 | break;
1338 | }
1339 |
1340 | else if (command == InputCommand::Green) { // Red, Green, and Blue buttons can be used by ColorInvaders game, which is the next to last pattern
1341 | setSolidColor(CRGB::Green);
1342 | break;
1343 | }
1344 | else if (command == InputCommand::Lime) {
1345 | setSolidColor(CRGB::Lime);
1346 | break;
1347 | }
1348 | else if (command == InputCommand::Aqua) {
1349 | setSolidColor(CRGB::Aqua);
1350 | break;
1351 | }
1352 | else if (command == InputCommand::Teal) {
1353 | setSolidColor(CRGB::Teal);
1354 | break;
1355 | }
1356 | else if (command == InputCommand::Navy) {
1357 | setSolidColor(CRGB::Navy);
1358 | break;
1359 | }
1360 |
1361 | else if (command == InputCommand::Blue) { // Red, Green, and Blue buttons can be used by ColorInvaders game, which is the next to last pattern
1362 | setSolidColor(CRGB::Blue);
1363 | break;
1364 | }
1365 | else if (command == InputCommand::RoyalBlue) {
1366 | setSolidColor(CRGB::RoyalBlue);
1367 | break;
1368 | }
1369 | else if (command == InputCommand::Purple) {
1370 | setSolidColor(CRGB::Purple);
1371 | break;
1372 | }
1373 | else if (command == InputCommand::Indigo) {
1374 | setSolidColor(CRGB::Indigo);
1375 | break;
1376 | }
1377 | else if (command == InputCommand::Magenta) {
1378 | setSolidColor(CRGB::Magenta);
1379 | break;
1380 | }
1381 |
1382 | else if (command == InputCommand::White) {
1383 | setSolidColor(CRGB::White);
1384 | break;
1385 | }
1386 | else if (command == InputCommand::Pink) {
1387 | setSolidColor(CRGB::Pink);
1388 | break;
1389 | }
1390 | else if (command == InputCommand::LightPink) {
1391 | setSolidColor(CRGB::LightPink);
1392 | break;
1393 | }
1394 | else if (command == InputCommand::BabyBlue) {
1395 | setSolidColor(CRGB::CornflowerBlue);
1396 | break;
1397 | }
1398 | else if (command == InputCommand::LightBlue) {
1399 | setSolidColor(CRGB::LightBlue);
1400 | break;
1401 | }
1402 |
1403 | if (millis() >= requestedDelayTimeout)
1404 | break;
1405 | }
1406 | }
1407 |
1408 | void setup()
1409 | {
1410 | FastLED.addLeds(leds, NUM_LEDS);
1411 | FastLED.setCorrection(Typical8mmPixel);
1412 | FastLED.setBrightness(brightness);
1413 | FastLED.setDither(false);
1414 | fill_solid(leds, NUM_LEDS, solidColor);
1415 | FastLED.show();
1416 |
1417 | // Serial.begin(9600);
1418 |
1419 | // Initialize the IR receiver
1420 | irReceiver.enableIRIn();
1421 | irReceiver.blink13(true);
1422 |
1423 | loadSettings();
1424 |
1425 | FastLED.setBrightness(brightness);
1426 | FastLED.setDither(brightness < 255);
1427 |
1428 | noisex = random16();
1429 | noisey = random16();
1430 | noisez = random16();
1431 | }
1432 |
1433 | void loop()
1434 | {
1435 | // Add entropy to random number generator; we use a lot of it.
1436 | random16_add_entropy(random());
1437 |
1438 | uint8_t requestedDelay = patterns[patternIndex]();
1439 |
1440 | // send the 'leds' array out to the actual LED strip
1441 | FastLED.show();
1442 |
1443 | handleInput(requestedDelay);
1444 |
1445 | if (autoplayEnabled && millis() > autoPlayTimout) {
1446 | move(1);
1447 | autoPlayTimout = millis() + (autoPlayDurationSeconds * 1000);
1448 | }
1449 |
1450 | // blend the current palette to the next
1451 | EVERY_N_MILLISECONDS(40) {
1452 | nblendPaletteTowardPalette(currentPalette, targetPalette, 16);
1453 | }
1454 |
1455 | EVERY_N_MILLISECONDS( 40 ) {
1456 | gHue++; // slowly cycle the "base color" through the rainbow
1457 | }
1458 |
1459 | // slowly change to a new palette
1460 | EVERY_N_SECONDS(SECONDS_PER_PALETTE) {
1461 | paletteIndex++;
1462 | if (paletteIndex >= paletteCount) paletteIndex = 0;
1463 | targetPalette = palettes[paletteIndex];
1464 | };
1465 |
1466 | // slowly change to a new cpt-city gradient palette
1467 | EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {
1468 | gCurrentPaletteNumber = addmod8( gCurrentPaletteNumber, 1, gGradientPaletteCount);
1469 | gTargetPalette = gGradientPalettes[ gCurrentPaletteNumber ];
1470 | }
1471 |
1472 | // blend the current cpt-city gradient palette to the next
1473 | EVERY_N_MILLISECONDS(40) {
1474 | nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 16);
1475 | }
1476 | }
1477 |
1478 |
--------------------------------------------------------------------------------