├── Clock.h
├── Commands.h
├── FSBrowser.h
├── Field.h
├── Fields.h
├── GradientPalettes.h
├── LICENSE
├── Pacifica.h
├── Ping.h
├── README.md
├── TwinkleFOX.h
├── Twinkles.h
├── build.sh
├── data
├── css
│ ├── bootstrap.min.css
│ ├── jquery.minicolors.min.css
│ ├── simple.css
│ └── styles.css
├── edit.htm
├── favicon.ico
├── fonts
│ ├── glyphicons.eot
│ ├── glyphicons.svg
│ ├── glyphicons.ttf
│ ├── glyphicons.woff
│ └── glyphicons.woff2
├── images
│ └── atom196.png
├── index.htm
├── js
│ ├── app.js
│ ├── bootstrap.min.js
│ ├── jquery-3.1.1.min.js
│ ├── jquery.minicolors.min.js
│ ├── r-websocket.min.js
│ └── simple.js
└── simple.htm
├── deployapp.sh
├── deployfirmware.sh
├── eclipse-v2.ino
├── power.sh
└── uploadfile.sh
/Clock.h:
--------------------------------------------------------------------------------
1 | uint8_t flipClock = 0;
2 | int timeZone = -6;
3 |
4 | unsigned long lastTimeSync = millis();
5 |
6 | int oldSecTime = 0;
7 | int oldSec = 0;
8 |
9 | IPAddress timeServerIP; // time.nist.gov NTP server address
10 | const char* ntpServerName = "time.nist.gov";
11 |
12 | const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
13 |
14 | byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
15 |
16 | // send an NTP request to the time server at the given address
17 | void sendNTPpacket()
18 | {
19 | //get a random server from the pool
20 | WiFi.hostByName(ntpServerName, timeServerIP);
21 |
22 | // set all bytes in the buffer to 0
23 | memset(packetBuffer, 0, NTP_PACKET_SIZE);
24 | // Initialize values needed to form NTP request
25 | // (see URL above for details on the packets)
26 | packetBuffer[0] = 0b11100011; // LI, Version, Mode
27 | packetBuffer[1] = 0; // Stratum, or type of clock
28 | packetBuffer[2] = 6; // Polling Interval
29 | packetBuffer[3] = 0xEC; // Peer Clock Precision
30 | // 8 bytes of zero for Root Delay & Root Dispersion
31 | packetBuffer[12] = 49;
32 | packetBuffer[13] = 0x4E;
33 | packetBuffer[14] = 49;
34 | packetBuffer[15] = 52;
35 | // all NTP fields have been given values, now
36 | // you can send a packet requesting a timestamp:
37 | udp.beginPacket(timeServerIP, 123); //NTP requests are to port 123
38 | udp.write(packetBuffer, NTP_PACKET_SIZE);
39 | udp.endPacket();
40 | }
41 |
42 | time_t getNtpTime()
43 | {
44 | while (udp.parsePacket() > 0) ; // discard any previously received packets
45 | Serial.println("Transmit NTP Request");
46 | sendNTPpacket();
47 | uint32_t beginWait = millis();
48 | while (millis() - beginWait < 1500) {
49 | int size = udp.parsePacket();
50 | if (size >= NTP_PACKET_SIZE) {
51 | Serial.println("Receive NTP Response");
52 | udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
53 | unsigned long secsSince1900;
54 | // convert four bytes starting at location 40 to a long integer
55 | secsSince1900 = (unsigned long)packetBuffer[40] << 24;
56 | secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
57 | secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
58 | secsSince1900 |= (unsigned long)packetBuffer[43];
59 | return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
60 | }
61 | }
62 | Serial.println("No NTP Response :-(");
63 | return 0; // return 0 if unable to get the time
64 | }
65 |
66 | void drawAnalogClock(byte seconds, byte minutes, byte hours, boolean drawMillis, boolean drawSecond)
67 | {
68 | if (timeStatus() == timeSet) {
69 | setSyncInterval(300);
70 | }
71 | else {
72 | setSyncInterval(30);
73 | }
74 |
75 | if (second() != oldSec) {
76 | oldSecTime = millis();
77 | oldSec = second();
78 | }
79 |
80 | if (hours > 12) hours -= 12;
81 |
82 | int millisecond = millis() - oldSecTime;
83 |
84 | int secondIndex = map(seconds, 0, 59, 0, NUM_LEDS);
85 | int minuteIndex = map(minutes, 0, 59, 0, NUM_LEDS);
86 | int hourIndex = map(hours * 5, 5, 60, 0, NUM_LEDS);
87 | int millisecondIndex = map(secondIndex + millisecond * .06, 0, 60, 0, NUM_LEDS);
88 |
89 | if (millisecondIndex >= NUM_LEDS)
90 | millisecondIndex -= NUM_LEDS;
91 |
92 | hourIndex += minuteIndex / 12;
93 |
94 | if (hourIndex >= NUM_LEDS)
95 | hourIndex -= NUM_LEDS;
96 |
97 | // see if we need to reverse the order of the LEDS
98 | if (flipClock == 1) {
99 | int max = NUM_LEDS - 1;
100 | secondIndex = max - secondIndex;
101 | minuteIndex = max - minuteIndex;
102 | hourIndex = max - hourIndex;
103 | millisecondIndex = max - millisecondIndex;
104 | }
105 |
106 | if (secondIndex >= NUM_LEDS)
107 | secondIndex = NUM_LEDS - 1;
108 | else if (secondIndex < 0)
109 | secondIndex = 0;
110 |
111 | if (minuteIndex >= NUM_LEDS)
112 | minuteIndex = NUM_LEDS - 1;
113 | else if (minuteIndex < 0)
114 | minuteIndex = 0;
115 |
116 | if (hourIndex >= NUM_LEDS)
117 | hourIndex = NUM_LEDS - 1;
118 | else if (hourIndex < 0)
119 | hourIndex = 0;
120 |
121 | if (millisecondIndex >= NUM_LEDS)
122 | millisecondIndex = NUM_LEDS - 1;
123 | else if (millisecondIndex < 0)
124 | millisecondIndex = 0;
125 |
126 | if (drawMillis)
127 | leds[millisecondIndex] += CRGB(0, 0, 127); // Blue
128 |
129 | if (drawSecond)
130 | leds[secondIndex] += CRGB(0, 0, 127); // Blue
131 |
132 | leds[minuteIndex] += CRGB::Green;
133 | leds[hourIndex] += CRGB::Red;
134 | }
135 |
136 | void analogClock() {
137 | dimAll(220);
138 |
139 | drawAnalogClock(second(), minute(), hour(), false, true);
140 | }
141 |
142 | void analogClockWithMillis() {
143 | dimAll(220);
144 |
145 | drawAnalogClock(second(), minute(), hour(), true, true);
146 | }
147 |
148 |
--------------------------------------------------------------------------------
/Commands.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ESP8266 + FastLED + IR Remote + MSGEQ7: https://github.com/jasoncoon/esp8266-fastled-webserver
3 | * Copyright (C) 2015 Jason Coon
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 | enum class InputCommand {
20 | None,
21 | Up,
22 | Down,
23 | Left,
24 | Right,
25 | Select,
26 | Brightness,
27 | PlayMode,
28 | Palette,
29 | Power,
30 | BrightnessUp,
31 | BrightnessDown,
32 |
33 | Pattern1,
34 | Pattern2,
35 | Pattern3,
36 | Pattern4,
37 | Pattern5,
38 | Pattern6,
39 | Pattern7,
40 | Pattern8,
41 | Pattern9,
42 | Pattern10,
43 | Pattern11,
44 | Pattern12,
45 |
46 | RedUp,
47 | RedDown,
48 | GreenUp,
49 | GreenDown,
50 | BlueUp,
51 | BlueDown,
52 |
53 | Red,
54 | RedOrange,
55 | Orange,
56 | YellowOrange,
57 | Yellow,
58 |
59 | Green,
60 | Lime,
61 | Aqua,
62 | Teal,
63 | Navy,
64 |
65 | Blue,
66 | RoyalBlue,
67 | Purple,
68 | Indigo,
69 | Magenta,
70 |
71 | White,
72 | Pink,
73 | LightPink,
74 | BabyBlue,
75 | LightBlue,
76 | };
77 |
78 | // IR Raw Key Codes for SparkFun remote
79 | #define IRCODE_SPARKFUN_POWER 0x10EFD827 // 284153895
80 | #define IRCODE_SPARKFUN_A 0x10EFF807 //
81 | #define IRCODE_SPARKFUN_B 0x10EF7887
82 | #define IRCODE_SPARKFUN_C 0x10EF58A7
83 | #define IRCODE_SPARKFUN_UP 0x10EFA05F // 284139615
84 | #define IRCODE_SPARKFUN_LEFT 0x10EF10EF
85 | #define IRCODE_SPARKFUN_SELECT 0x10EF20DF
86 | #define IRCODE_SPARKFUN_RIGHT 0x10EF807F
87 | #define IRCODE_SPARKFUN_DOWN 0x10EF00FF
88 | #define IRCODE_SPARKFUN_HELD 0xFFFFFFFF
89 |
90 | // IR Raw Key Codes for Adafruit remote
91 | #define IRCODE_ADAFRUIT_HELD 0x7FFFFFFF // 4294967295
92 | #define IRCODE_ADAFRUIT_VOLUME_UP 0x00FD40BF // 16597183
93 | #define IRCODE_ADAFRUIT_PLAY_PAUSE 0x00FD807F // 16613503
94 | #define IRCODE_ADAFRUIT_VOLUME_DOWN 0x00FD00FF // 16580863
95 | #define IRCODE_ADAFRUIT_SETUP 0x00FD20DF // 16589023
96 | #define IRCODE_ADAFRUIT_UP 0x00FDA05F // 16621663
97 | #define IRCODE_ADAFRUIT_STOP_MODE 0x00FD609F // 16605343
98 | #define IRCODE_ADAFRUIT_LEFT 0x00FD10EF // 16584943
99 | #define IRCODE_ADAFRUIT_ENTER_SAVE 0x00FD906F // 16617583
100 | #define IRCODE_ADAFRUIT_RIGHT 0x00FD50AF // 16601263
101 | #define IRCODE_ADAFRUIT_0_10_PLUS 0x00FD30CF // 16593103
102 | #define IRCODE_ADAFRUIT_DOWN 0x00FDB04F // 16625743
103 | #define IRCODE_ADAFRUIT_BACK 0x00FD708F // 16609423
104 | #define IRCODE_ADAFRUIT_1 0x00FD08F7 // 16582903
105 | #define IRCODE_ADAFRUIT_2 0x00FD8877 // 16615543
106 | #define IRCODE_ADAFRUIT_3 0x00FD48B7 // 16599223
107 | #define IRCODE_ADAFRUIT_4 0x00FD28D7 // 16591063
108 | #define IRCODE_ADAFRUIT_5 0x00FDA857 // 16623703
109 | #define IRCODE_ADAFRUIT_6 0x00FD6897 // 16607383
110 | #define IRCODE_ADAFRUIT_7 0x00FD18E7 // 16586983
111 | #define IRCODE_ADAFRUIT_8 0x00FD9867 // 16619623
112 | #define IRCODE_ADAFRUIT_9 0x00FD58A7 // 16603303
113 |
114 | // IR Raw Key Codes for eTopxizu 44Key IR Remote Controller for 5050 3528 RGB LED Light Strip
115 | #define IRCODE_ETOPXIZU_HELD 0x7FFFFFFF // 4294967295
116 | #define IRCODE_ETOPXIZU_POWER 16712445
117 | #define IRCODE_ETOPXIZU_PLAY_PAUSE 16745085
118 | #define IRCODE_ETOPXIZU_BRIGHTNESS_UP 16726725
119 | #define IRCODE_ETOPXIZU_BRIGHTNESS_DOWN 16759365
120 |
121 | #define IRCODE_ETOPXIZU_DIY1 16724175
122 | #define IRCODE_ETOPXIZU_DIY2 16756815
123 | #define IRCODE_ETOPXIZU_DIY3 16740495
124 | #define IRCODE_ETOPXIZU_DIY4 16716015
125 | #define IRCODE_ETOPXIZU_DIY5 16748655
126 | #define IRCODE_ETOPXIZU_DIY6 16732335
127 |
128 | #define IRCODE_ETOPXIZU_JUMP3 16720095
129 | #define IRCODE_ETOPXIZU_JUMP7 16752735
130 | #define IRCODE_ETOPXIZU_FADE3 16736415
131 | #define IRCODE_ETOPXIZU_FADE7 16769055
132 | #define IRCODE_ETOPXIZU_FLASH 16764975
133 | #define IRCODE_ETOPXIZU_AUTO 16773135
134 |
135 | #define IRCODE_ETOPXIZU_QUICK 16771095
136 | #define IRCODE_ETOPXIZU_SLOW 16762935
137 |
138 | #define IRCODE_ETOPXIZU_RED_UP 16722135
139 | #define IRCODE_ETOPXIZU_RED_DOWN 16713975
140 |
141 | #define IRCODE_ETOPXIZU_GREEN_UP 16754775
142 | #define IRCODE_ETOPXIZU_GREEN_DOWN 16746615
143 |
144 | #define IRCODE_ETOPXIZU_BLUE_UP 16738455
145 | #define IRCODE_ETOPXIZU_BLUE_DOWN 16730295
146 |
147 | #define IRCODE_ETOPXIZU_RED 16718565
148 | #define IRCODE_ETOPXIZU_RED_ORANGE 16722645
149 | #define IRCODE_ETOPXIZU_ORANGE 16714485
150 | #define IRCODE_ETOPXIZU_YELLOW_ORANGE 16726215
151 | #define IRCODE_ETOPXIZU_YELLOW 16718055
152 |
153 | #define IRCODE_ETOPXIZU_GREEN 16751205
154 | #define IRCODE_ETOPXIZU_LIME 16755285
155 | #define IRCODE_ETOPXIZU_AQUA 16747125
156 | #define IRCODE_ETOPXIZU_TEAL 16758855
157 | #define IRCODE_ETOPXIZU_NAVY 16750695
158 |
159 | #define IRCODE_ETOPXIZU_BLUE 16753245
160 | #define IRCODE_ETOPXIZU_ROYAL_BLUE 16749165
161 | #define IRCODE_ETOPXIZU_PURPLE 16757325
162 | #define IRCODE_ETOPXIZU_INDIGO 16742535
163 | #define IRCODE_ETOPXIZU_MAGENTA 16734375
164 |
165 | #define IRCODE_ETOPXIZU_WHITE 16720605
166 | #define IRCODE_ETOPXIZU_PINK 16716525
167 | #define IRCODE_ETOPXIZU_LIGHT_PINK 16724685
168 | #define IRCODE_ETOPXIZU_BABY_BLUE 16775175
169 | #define IRCODE_ETOPXIZU_LIGHT_BLUE 16767015
170 |
171 | bool sparkfunRemoteEnabled = true;
172 | bool adafruitRemoteEnabled = true;
173 | bool etopxizuRemoteEnabled = true;
174 |
175 | // Low level IR code reading function
176 | // Function will return 0 if no IR code available
177 | unsigned long decodeIRCode() {
178 |
179 | decode_results results;
180 |
181 | results.value = 0;
182 |
183 | // Attempt to read an IR code ?
184 | if (irReceiver.decode(&results)) {
185 | delay(20);
186 |
187 | if (results.value != 0)
188 | Serial.println(results.value);
189 |
190 | // Prepare to receive the next IR code
191 | irReceiver.resume();
192 | }
193 |
194 | return results.value;
195 | }
196 |
197 | // Read an IR code
198 | // Function will return 0 if no IR code available
199 | unsigned long readIRCode() {
200 |
201 | // Is there an IR code to read ?
202 | unsigned long code = decodeIRCode();
203 | if (code == 0) {
204 | // No code so return 0
205 | return 0;
206 | }
207 |
208 | // Keep reading until code changes
209 | while (decodeIRCode() == code) {
210 | ;
211 | }
212 | // Serial.println(code);
213 | return code;
214 | }
215 |
216 | unsigned long lastIrCode = 0;
217 |
218 | unsigned int holdStartTime = 0;
219 | unsigned int defaultHoldDelay = 500;
220 | bool isHolding = false;
221 |
222 | unsigned int zeroStartTime = 0;
223 | unsigned int zeroDelay = 120;
224 |
225 | unsigned long readIRCode(unsigned int holdDelay) {
226 | // read the raw code from the sensor
227 | unsigned long irCode = readIRCode();
228 |
229 | //Serial.print(millis());
230 | //Serial.print("\t");
231 | //Serial.println(irCode);
232 |
233 | // don't return a short click until we know it's not a long hold
234 | // we'll have to wait for holdDelay ms to pass before returning a non-zero IR code
235 | // then, after that delay, as long as the button is held, we can keep returning the code
236 | // every time until it's released
237 |
238 | // the ir remote only sends codes every 107 ms or so (avg 106.875, max 111, min 102),
239 | // so the ir sensor will return 0 even if a button is held
240 | // so we have to wait longer than that before returning a non-zero code
241 | // in order to detect that a button has been released and is no longer held
242 |
243 | // only reset after we've gotten 0 back for more than the ir remote send interval
244 | unsigned int zeroTime = 0;
245 |
246 | if (irCode == 0) {
247 | zeroTime = millis() - zeroStartTime;
248 | if (zeroTime >= zeroDelay && lastIrCode != 0) {
249 | //Serial.println(F("zero delay has elapsed, returning last ir code"));
250 | // the button has been released for longer than the zero delay
251 | // start over delays over and return the last code
252 | irCode = lastIrCode;
253 | lastIrCode = 0;
254 | return irCode;
255 | }
256 |
257 | return 0;
258 | }
259 |
260 | // reset the zero timer every time a non-zero code is read
261 | zeroStartTime = millis();
262 |
263 | unsigned int heldTime = 0;
264 |
265 | if (irCode == IRCODE_SPARKFUN_HELD || irCode == IRCODE_ADAFRUIT_HELD) {
266 | // has the hold delay passed?
267 | heldTime = millis() - holdStartTime;
268 | if (heldTime >= holdDelay) {
269 | isHolding = true;
270 | //Serial.println(F("hold delay has elapsed, returning last ir code"));
271 | return lastIrCode;
272 | }
273 | else if (holdStartTime == 0) {
274 | isHolding = false;
275 | holdStartTime = millis();
276 | }
277 | }
278 | else {
279 | // not zero, not IRCODE_SPARKFUN_HELD
280 | // store it for use later, until the hold and zero delays have elapsed
281 | holdStartTime = millis();
282 | isHolding = false;
283 | lastIrCode = irCode;
284 | return 0;
285 | }
286 |
287 | return 0;
288 | }
289 |
290 | void heldButtonHasBeenHandled() {
291 | lastIrCode = 0;
292 | isHolding = false;
293 | holdStartTime = 0;
294 | }
295 |
296 | unsigned long waitForIRCode() {
297 |
298 | unsigned long irCode = readIRCode();
299 | while ((irCode == 0) || (irCode == 0xFFFFFFFF)) {
300 | delay(200);
301 | irCode = readIRCode();
302 | }
303 | return irCode;
304 | }
305 |
306 | InputCommand getCommand(unsigned long input) {
307 | if (adafruitRemoteEnabled) {
308 | switch (input) {
309 | case IRCODE_ADAFRUIT_UP:
310 | return InputCommand::Up;
311 |
312 | case IRCODE_ADAFRUIT_DOWN:
313 | return InputCommand::Down;
314 |
315 | case IRCODE_ADAFRUIT_LEFT:
316 | return InputCommand::Left;
317 |
318 | case IRCODE_ADAFRUIT_RIGHT:
319 | return InputCommand::Right;
320 |
321 | case IRCODE_ADAFRUIT_ENTER_SAVE:
322 | return InputCommand::Select;
323 |
324 | case IRCODE_ADAFRUIT_STOP_MODE:
325 | case IRCODE_ADAFRUIT_1:
326 | return InputCommand::PlayMode;
327 |
328 | case IRCODE_ADAFRUIT_2:
329 | return InputCommand::Palette;
330 |
331 | case IRCODE_ADAFRUIT_PLAY_PAUSE:
332 | return InputCommand::Power;
333 |
334 | case IRCODE_ADAFRUIT_VOLUME_UP:
335 | return InputCommand::BrightnessUp;
336 |
337 | case IRCODE_ADAFRUIT_VOLUME_DOWN:
338 | return InputCommand::BrightnessDown;
339 | }
340 | }
341 |
342 | if (sparkfunRemoteEnabled) {
343 | switch (input) {
344 | case IRCODE_SPARKFUN_UP:
345 | return InputCommand::Up;
346 |
347 | case IRCODE_SPARKFUN_DOWN:
348 | return InputCommand::Down;
349 |
350 | case IRCODE_SPARKFUN_LEFT:
351 | return InputCommand::Left;
352 |
353 | case IRCODE_SPARKFUN_RIGHT:
354 | return InputCommand::Right;
355 |
356 | case IRCODE_SPARKFUN_SELECT:
357 | return InputCommand::Select;
358 |
359 | case IRCODE_SPARKFUN_POWER:
360 | return InputCommand::Brightness;
361 |
362 | case IRCODE_SPARKFUN_A:
363 | return InputCommand::PlayMode;
364 |
365 | case IRCODE_SPARKFUN_B:
366 | return InputCommand::Palette;
367 | }
368 | }
369 |
370 | if (etopxizuRemoteEnabled) {
371 | switch (input) {
372 | case IRCODE_ETOPXIZU_QUICK:
373 | return InputCommand::Up;
374 |
375 | case IRCODE_ETOPXIZU_SLOW:
376 | return InputCommand::Down;
377 |
378 | case IRCODE_ETOPXIZU_PLAY_PAUSE:
379 | return InputCommand::PlayMode;
380 |
381 | case IRCODE_ETOPXIZU_POWER:
382 | return InputCommand::Power;
383 |
384 | case IRCODE_ETOPXIZU_BRIGHTNESS_UP:
385 | return InputCommand::BrightnessUp;
386 | case IRCODE_ETOPXIZU_BRIGHTNESS_DOWN:
387 | return InputCommand::BrightnessDown;
388 |
389 | case IRCODE_ETOPXIZU_DIY1:
390 | return InputCommand::Pattern1;
391 | case IRCODE_ETOPXIZU_DIY2:
392 | return InputCommand::Pattern2;
393 | case IRCODE_ETOPXIZU_DIY3:
394 | return InputCommand::Pattern3;
395 | case IRCODE_ETOPXIZU_DIY4:
396 | return InputCommand::Pattern4;
397 | case IRCODE_ETOPXIZU_DIY5:
398 | return InputCommand::Pattern5;
399 | case IRCODE_ETOPXIZU_DIY6:
400 | return InputCommand::Pattern6;
401 | case IRCODE_ETOPXIZU_JUMP3:
402 | return InputCommand::Pattern7;
403 | case IRCODE_ETOPXIZU_JUMP7:
404 | return InputCommand::Pattern8;
405 | case IRCODE_ETOPXIZU_FADE3:
406 | return InputCommand::Pattern9;
407 | case IRCODE_ETOPXIZU_FADE7:
408 | return InputCommand::Pattern10;
409 | case IRCODE_ETOPXIZU_FLASH:
410 | return InputCommand::Pattern11;
411 | case IRCODE_ETOPXIZU_AUTO:
412 | return InputCommand::Pattern12;
413 |
414 | case IRCODE_ETOPXIZU_RED_UP:
415 | return InputCommand::RedUp;
416 | case IRCODE_ETOPXIZU_RED_DOWN:
417 | return InputCommand::RedDown;
418 |
419 | case IRCODE_ETOPXIZU_GREEN_UP:
420 | return InputCommand::GreenUp;
421 | case IRCODE_ETOPXIZU_GREEN_DOWN:
422 | return InputCommand::GreenDown;
423 |
424 | case IRCODE_ETOPXIZU_BLUE_UP:
425 | return InputCommand::BlueUp;
426 | case IRCODE_ETOPXIZU_BLUE_DOWN:
427 | return InputCommand::BlueDown;
428 |
429 | case IRCODE_ETOPXIZU_RED:
430 | return InputCommand::Red;
431 | case IRCODE_ETOPXIZU_RED_ORANGE:
432 | return InputCommand::RedOrange;
433 | case IRCODE_ETOPXIZU_ORANGE:
434 | return InputCommand::Orange;
435 | case IRCODE_ETOPXIZU_YELLOW_ORANGE:
436 | return InputCommand::YellowOrange;
437 | case IRCODE_ETOPXIZU_YELLOW:
438 | return InputCommand::Yellow;
439 |
440 | case IRCODE_ETOPXIZU_GREEN:
441 | return InputCommand::Green;
442 | case IRCODE_ETOPXIZU_LIME:
443 | return InputCommand::Lime;
444 | case IRCODE_ETOPXIZU_AQUA:
445 | return InputCommand::Aqua;
446 | case IRCODE_ETOPXIZU_TEAL:
447 | return InputCommand::Teal;
448 | case IRCODE_ETOPXIZU_NAVY:
449 | return InputCommand::Navy;
450 |
451 | case IRCODE_ETOPXIZU_BLUE:
452 | return InputCommand::Blue;
453 | case IRCODE_ETOPXIZU_ROYAL_BLUE:
454 | return InputCommand::RoyalBlue;
455 | case IRCODE_ETOPXIZU_PURPLE:
456 | return InputCommand::Purple;
457 | case IRCODE_ETOPXIZU_INDIGO:
458 | return InputCommand::Indigo;
459 | case IRCODE_ETOPXIZU_MAGENTA:
460 | return InputCommand::Magenta;
461 |
462 | case IRCODE_ETOPXIZU_WHITE:
463 | return InputCommand::White;
464 | case IRCODE_ETOPXIZU_PINK:
465 | return InputCommand::Pink;
466 | case IRCODE_ETOPXIZU_LIGHT_PINK:
467 | return InputCommand::LightPink;
468 | case IRCODE_ETOPXIZU_BABY_BLUE:
469 | return InputCommand::BabyBlue;
470 | case IRCODE_ETOPXIZU_LIGHT_BLUE:
471 | return InputCommand::LightBlue;
472 | }
473 | }
474 |
475 | return InputCommand::None;
476 | }
477 |
478 | InputCommand readCommand() {
479 | return getCommand(readIRCode());
480 | }
481 |
482 | InputCommand readCommand(unsigned int holdDelay) {
483 | return getCommand(readIRCode(holdDelay));
484 | }
485 |
--------------------------------------------------------------------------------
/FSBrowser.h:
--------------------------------------------------------------------------------
1 | //holds the current upload
2 | File fsUploadFile;
3 |
4 | //format bytes
5 | String formatBytes(size_t bytes){
6 | if (bytes < 1024){
7 | return String(bytes)+"B";
8 | } else if(bytes < (1024 * 1024)){
9 | return String(bytes/1024.0)+"KB";
10 | } else if(bytes < (1024 * 1024 * 1024)){
11 | return String(bytes/1024.0/1024.0)+"MB";
12 | } else {
13 | return String(bytes/1024.0/1024.0/1024.0)+"GB";
14 | }
15 | }
16 |
17 | String getContentType(String filename){
18 | if(webServer.hasArg("download")) return "application/octet-stream";
19 | else if(filename.endsWith(".htm")) return "text/html";
20 | else if(filename.endsWith(".html")) return "text/html";
21 | else if(filename.endsWith(".css")) return "text/css";
22 | else if(filename.endsWith(".js")) return "application/javascript";
23 | else if(filename.endsWith(".png")) return "image/png";
24 | else if(filename.endsWith(".gif")) return "image/gif";
25 | else if(filename.endsWith(".jpg")) return "image/jpeg";
26 | else if(filename.endsWith(".ico")) return "image/x-icon";
27 | else if(filename.endsWith(".xml")) return "text/xml";
28 | else if(filename.endsWith(".pdf")) return "application/x-pdf";
29 | else if(filename.endsWith(".zip")) return "application/x-zip";
30 | else if(filename.endsWith(".gz")) return "application/x-gzip";
31 | return "text/plain";
32 | }
33 |
34 | bool handleFileRead(String path){
35 | Serial.println("handleFileRead: " + path);
36 | if(path.endsWith("/")) path += "index.htm";
37 | String contentType = getContentType(path);
38 | String pathWithGz = path + ".gz";
39 | if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
40 | if(SPIFFS.exists(pathWithGz))
41 | path += ".gz";
42 | File file = SPIFFS.open(path, "r");
43 | size_t sent = webServer.streamFile(file, contentType);
44 | file.close();
45 | return true;
46 | }
47 | return false;
48 | }
49 |
50 | void handleFileUpload(){
51 | if(webServer.uri() != "/edit") return;
52 | HTTPUpload& upload = webServer.upload();
53 | if(upload.status == UPLOAD_FILE_START){
54 | String filename = upload.filename;
55 | if(!filename.startsWith("/")) filename = "/"+filename;
56 | Serial.print("handleFileUpload Name: "); Serial.println(filename);
57 | fsUploadFile = SPIFFS.open(filename, "w");
58 | filename = String();
59 | } else if(upload.status == UPLOAD_FILE_WRITE){
60 | //Serial.print("handleFileUpload Data: "); Serial.println(upload.currentSize);
61 | if(fsUploadFile)
62 | fsUploadFile.write(upload.buf, upload.currentSize);
63 | } else if(upload.status == UPLOAD_FILE_END){
64 | if(fsUploadFile)
65 | fsUploadFile.close();
66 | Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize);
67 | }
68 | }
69 |
70 | void handleFileDelete(){
71 | if(webServer.args() == 0) return webServer.send(500, "text/plain", "BAD ARGS");
72 | String path = webServer.arg(0);
73 | Serial.println("handleFileDelete: " + path);
74 | if(path == "/")
75 | return webServer.send(500, "text/plain", "BAD PATH");
76 | if(!SPIFFS.exists(path))
77 | return webServer.send(404, "text/plain", "FileNotFound");
78 | SPIFFS.remove(path);
79 | webServer.send(200, "text/plain", "");
80 | path = String();
81 | }
82 |
83 | void handleFileCreate(){
84 | if(webServer.args() == 0)
85 | return webServer.send(500, "text/plain", "BAD ARGS");
86 | String path = webServer.arg(0);
87 | Serial.println("handleFileCreate: " + path);
88 | if(path == "/")
89 | return webServer.send(500, "text/plain", "BAD PATH");
90 | if(SPIFFS.exists(path))
91 | return webServer.send(500, "text/plain", "FILE EXISTS");
92 | File file = SPIFFS.open(path, "w");
93 | if(file)
94 | file.close();
95 | else
96 | return webServer.send(500, "text/plain", "CREATE FAILED");
97 | webServer.send(200, "text/plain", "");
98 | path = String();
99 | }
100 |
101 | void handleFileList() {
102 | if(!webServer.hasArg("dir")) {webServer.send(500, "text/plain", "BAD ARGS"); return;}
103 |
104 | String path = webServer.arg("dir");
105 | Serial.println("handleFileList: " + path);
106 | Dir dir = SPIFFS.openDir(path);
107 | path = String();
108 |
109 | String output = "[";
110 | while(dir.next()){
111 | File entry = dir.openFile("r");
112 | if (output != "[") output += ',';
113 | bool isDir = false;
114 | output += "{\"type\":\"";
115 | output += (isDir)?"dir":"file";
116 | output += "\",\"name\":\"";
117 | output += String(entry.name()).substring(1);
118 | output += "\"}";
119 | entry.close();
120 | }
121 |
122 | output += "]";
123 | webServer.send(200, "text/json", output);
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/Field.h:
--------------------------------------------------------------------------------
1 | /*
2 | ESP8266 + FastLED + IR Remote: https://github.com/jasoncoon/esp8266-fastled-webserver
3 | Copyright (C) 2016 Jason Coon
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 | typedef String (*FieldSetter)(String);
20 | typedef String (*FieldGetter)();
21 |
22 | const String NumberFieldType = "Number";
23 | const String BooleanFieldType = "Boolean";
24 | const String SelectFieldType = "Select";
25 | const String ColorFieldType = "Color";
26 | const String SectionFieldType = "Section";
27 | const String LabelFieldType = "Label";
28 |
29 | typedef struct Field {
30 | String name;
31 | String label;
32 | String type;
33 | uint8_t min;
34 | uint8_t max;
35 | FieldGetter getValue;
36 | FieldGetter getOptions;
37 | FieldSetter setValue;
38 | };
39 |
40 | typedef Field FieldList[];
41 |
42 | Field getField(String name, FieldList fields, uint8_t count) {
43 | for (uint8_t i = 0; i < count; i++) {
44 | Field field = fields[i];
45 | if (field.name == name) {
46 | return field;
47 | }
48 | }
49 | return Field();
50 | }
51 |
52 | String getFieldValue(String name, FieldList fields, uint8_t count) {
53 | Field field = getField(name, fields, count);
54 | if (field.getValue) {
55 | return field.getValue();
56 | }
57 | return String();
58 | }
59 |
60 | String setFieldValue(String name, String value, FieldList fields, uint8_t count) {
61 | Field field = getField(name, fields, count);
62 | if (field.setValue) {
63 | return field.setValue(value);
64 | }
65 | return String();
66 | }
67 |
68 | String getFieldsJson(FieldList fields, uint8_t count) {
69 | String json = "[";
70 |
71 | for (uint8_t i = 0; i < count; i++) {
72 | Field field = fields[i];
73 |
74 | json += "{\"name\":\"" + field.name + "\",\"label\":\"" + field.label + "\",\"type\":\"" + field.type + "\"";
75 |
76 | if(field.getValue) {
77 | if (field.type == ColorFieldType || field.type == "String" || field.type == "Label") {
78 | json += ",\"value\":\"" + field.getValue() + "\"";
79 | }
80 | else {
81 | json += ",\"value\":" + field.getValue();
82 | }
83 | }
84 |
85 | if (field.type == NumberFieldType) {
86 | json += ",\"min\":" + String(field.min);
87 | json += ",\"max\":" + String(field.max);
88 | }
89 |
90 | if (field.getOptions) {
91 | json += ",\"options\":[";
92 | json += field.getOptions();
93 | json += "]";
94 | }
95 |
96 | json += "}";
97 |
98 | if (i < count - 1)
99 | json += ",";
100 | }
101 |
102 | json += "]";
103 |
104 | return json;
105 | }
106 |
107 | /*
108 | String json = "[";
109 |
110 | json += "{\"name\":\"power\",\"label\":\"Power\",\"type\":\"Boolean\",\"value\":" + String(power) + "},";
111 | json += "{\"name\":\"brightness\",\"label\":\"Brightness\",\"type\":\"Number\",\"value\":" + String(brightness) + "},";
112 |
113 | json += "{\"name\":\"pattern\",\"label\":\"Pattern\",\"type\":\"Select\",\"value\":" + String(currentPatternIndex) + ",\"options\":[";
114 | for (uint8_t i = 0; i < patternCount; i++)
115 | {
116 | json += "\"" + patterns[i].name + "\"";
117 | if (i < patternCount - 1)
118 | json += ",";
119 | }
120 | json += "]},";
121 |
122 | json += "{\"name\":\"autoplay\",\"label\":\"Autoplay\",\"type\":\"Boolean\",\"value\":" + String(autoplay) + "},";
123 | json += "{\"name\":\"autoplayDuration\",\"label\":\"Autoplay Duration\",\"type\":\"Number\",\"value\":" + String(autoplayDuration) + "},";
124 |
125 | json += "{\"name\":\"solidColor\",\"label\":\"Color\",\"type\":\"Color\",\"value\":\"" + String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b) +"\"},";
126 |
127 | json += "{\"name\":\"cooling\",\"label\":\"Cooling\",\"type\":\"Number\",\"value\":" + String(cooling) + "},";
128 | json += "{\"name\":\"sparking\",\"label\":\"Sparking\",\"type\":\"Number\",\"value\":" + String(sparking) + "}";
129 |
130 | json += "]";
131 | */
132 |
--------------------------------------------------------------------------------
/Fields.h:
--------------------------------------------------------------------------------
1 | /*
2 | ESP8266 + FastLED + IR Remote: https://github.com/jasoncoon/esp8266-fastled-webserver
3 | Copyright (C) 2016 Jason Coon
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 | uint8_t power = 1;
20 | uint8_t brightness = brightnessMap[brightnessIndex];
21 |
22 | //String setPower(String value) {
23 | // power = value.toInt();
24 | // if(power < 0) power = 0;
25 | // else if (power > 1) power = 1;
26 | // return String(power);
27 | //}
28 |
29 | String getPower() {
30 | return String(power);
31 | }
32 |
33 | //String setBrightness(String value) {
34 | // brightness = value.toInt();
35 | // if(brightness < 0) brightness = 0;
36 | // else if (brightness > 255) brightness = 255;
37 | // return String(brightness);
38 | //}
39 |
40 | String getBrightness() {
41 | return String(brightness);
42 | }
43 |
44 | String getPattern() {
45 | return String(currentPatternIndex);
46 | }
47 |
48 | String getPatterns() {
49 | String json = "";
50 |
51 | for (uint8_t i = 0; i < patternCount; i++) {
52 | json += "\"" + patterns[i].name + "\"";
53 | if (i < patternCount - 1)
54 | json += ",";
55 | }
56 |
57 | return json;
58 | }
59 |
60 | String getAutoplay() {
61 | return String(autoplay);
62 | }
63 |
64 | String getAutoplayDuration() {
65 | return String(autoplayDuration);
66 | }
67 |
68 | String getSolidColor() {
69 | return String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b);
70 | }
71 |
72 | String getCooling() {
73 | return String(cooling);
74 | }
75 |
76 | String getSparking() {
77 | return String(sparking);
78 | }
79 |
80 | String getSpeed() {
81 | return String(speed);
82 | }
83 |
84 | String getTwinkleSpeed() {
85 | return String(twinkleSpeed);
86 | }
87 |
88 | String getTwinkleDensity() {
89 | return String(twinkleDensity);
90 | }
91 |
92 | String getName() {
93 | return nameString;
94 | }
95 |
96 | FieldList fields = {
97 | { "name", "Name", LabelFieldType, 0, 0, getName },
98 | { "power", "Power", BooleanFieldType, 0, 1, getPower },
99 | { "brightness", "Brightness", NumberFieldType, 1, 255, getBrightness },
100 | { "pattern", "Pattern", SelectFieldType, 0, patternCount, getPattern, getPatterns },
101 | { "speed", "Speed", NumberFieldType, 1, 255, getSpeed },
102 | { "autoplay", "Autoplay", SectionFieldType },
103 | { "autoplay", "Autoplay", BooleanFieldType, 0, 1, getAutoplay },
104 | { "autoplayDuration", "Autoplay Duration", NumberFieldType, 0, 255, getAutoplayDuration },
105 | { "solidColor", "Solid Color", SectionFieldType },
106 | { "solidColor", "Color", ColorFieldType, 0, 255, getSolidColor },
107 | { "fire", "Fire & Water", SectionFieldType },
108 | { "cooling", "Cooling", NumberFieldType, 0, 255, getCooling },
109 | { "sparking", "Sparking", NumberFieldType, 0, 255, getSparking },
110 | { "twinkles", "Twinkles", SectionFieldType },
111 | { "twinkleSpeed", "Twinkle Speed", NumberFieldType, 0, 8, getTwinkleSpeed },
112 | { "twinkleDensity", "Twinkle Density", NumberFieldType, 0, 8, getTwinkleDensity },
113 | };
114 |
115 | uint8_t fieldCount = ARRAY_SIZE(fields);
116 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Pacifica.h:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////
2 | //
3 | // The code for this animation is more complicated than other examples, and
4 | // while it is "ready to run", and documented in general, it is probably not
5 | // the best starting point for learning. Nevertheless, it does illustrate some
6 | // useful techniques.
7 | //
8 | //////////////////////////////////////////////////////////////////////////
9 | //
10 | // In this animation, there are four "layers" of waves of light.
11 | //
12 | // Each layer moves independently, and each is scaled separately.
13 | //
14 | // All four wave layers are added together on top of each other, and then
15 | // another filter is applied that adds "whitecaps" of brightness where the
16 | // waves line up with each other more. Finally, another pass is taken
17 | // over the led array to 'deepen' (dim) the blues and greens.
18 | //
19 | // The speed and scale and motion each layer varies slowly within independent
20 | // hand-chosen ranges, which is why the code has a lot of low-speed 'beatsin8' functions
21 | // with a lot of oddly specific numeric ranges.
22 | //
23 | // These three custom blue-green color palettes were inspired by the colors found in
24 | // the waters off the southern coast of California, https://goo.gl/maps/QQgd97jjHesHZVxQ7
25 | //
26 | CRGBPalette16 pacifica_palette_1 =
27 | { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
28 | 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
29 | CRGBPalette16 pacifica_palette_2 =
30 | { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
31 | 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
32 | CRGBPalette16 pacifica_palette_3 =
33 | { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33,
34 | 0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };
35 |
36 | // Add one layer of waves into the led array
37 | void pacifica_one_layer( CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff)
38 | {
39 | uint16_t ci = cistart;
40 | uint16_t waveangle = ioff;
41 | uint16_t wavescale_half = (wavescale / 2) + 20;
42 | for( uint16_t i = 0; i < NUM_LEDS; i++) {
43 | waveangle += 250;
44 | uint16_t s16 = sin16( waveangle ) + 32768;
45 | uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half;
46 | ci += cs;
47 | uint16_t sindex16 = sin16( ci) + 32768;
48 | uint8_t sindex8 = scale16( sindex16, 240);
49 | CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND);
50 | leds[i] += c;
51 | }
52 | }
53 |
54 | // Add extra 'white' to areas where the four layers of light have lined up brightly
55 | void pacifica_add_whitecaps()
56 | {
57 | uint8_t basethreshold = beatsin8( 9, 55, 65);
58 | uint8_t wave = beat8( 7 );
59 |
60 | for( uint16_t i = 0; i < NUM_LEDS; i++) {
61 | uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
62 | wave += 7;
63 | uint8_t l = leds[i].getAverageLight();
64 | if( l > threshold) {
65 | uint8_t overage = l - threshold;
66 | uint8_t overage2 = qadd8( overage, overage);
67 | leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2));
68 | }
69 | }
70 | }
71 |
72 | // Deepen the blues and greens
73 | void pacifica_deepen_colors()
74 | {
75 | for( uint16_t i = 0; i < NUM_LEDS; i++) {
76 | leds[i].blue = scale8( leds[i].blue, 145);
77 | leds[i].green= scale8( leds[i].green, 200);
78 | leds[i] |= CRGB( 2, 5, 7);
79 | }
80 | }
81 |
82 | void pacifica()
83 | {
84 | // Increment the four "color index start" counters, one for each wave layer.
85 | // Each is incremented at a different speed, and the speeds vary over time.
86 | static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
87 | static uint32_t sLastms = 0;
88 | uint32_t ms = GET_MILLIS();
89 | uint32_t deltams = ms - sLastms;
90 | sLastms = ms;
91 | uint16_t speedfactor1 = beatsin16(3, 179, 269);
92 | uint16_t speedfactor2 = beatsin16(4, 179, 269);
93 | uint32_t deltams1 = (deltams * speedfactor1) / 256;
94 | uint32_t deltams2 = (deltams * speedfactor2) / 256;
95 | uint32_t deltams21 = (deltams1 + deltams2) / 2;
96 | sCIStart1 += (deltams1 * beatsin88(1011,10,13));
97 | sCIStart2 -= (deltams21 * beatsin88(777,8,11));
98 | sCIStart3 -= (deltams1 * beatsin88(501,5,7));
99 | sCIStart4 -= (deltams2 * beatsin88(257,4,6));
100 |
101 | // Clear out the LED array to a dim background blue-green
102 | fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10));
103 |
104 | // Render each of four layers, with different scales and speeds, that vary over time
105 | pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0-beat16( 301) );
106 | pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4, 6 * 256, 9 * 256), beatsin8( 17, 40, 80), beat16( 401) );
107 | pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10,38), 0-beat16(503));
108 | pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10,28), beat16(601));
109 |
110 | // Add brighter 'whitecaps' where the waves lines up more
111 | pacifica_add_whitecaps();
112 |
113 | // Deepen the blues and greens a bit
114 | pacifica_deepen_colors();
115 | }
116 |
--------------------------------------------------------------------------------
/Ping.h:
--------------------------------------------------------------------------------
1 | /*
2 | ESP8266 + FastLED: https://github.com/jasoncoon/esp8266-fastled-webserver
3 | Copyright (C) 2015-2020 Jason Coon
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 | // Discovery enables you to find your internet-connected ESP8266 devices on your network.
20 | // When enabled, the ESP8266 will "ping" a server every 10 minutes, by default.
21 | // Then, you can go to https://discover.evilgeniuslabs.org to view all of the
22 | // ESP8266 devices at your current location.
23 |
24 | // Data submitted to the server: device name, local IP address, MAC address, and current millis (uptime).
25 | // The server logs this, along with the public request IP address.
26 | // When you visit https://discover.evilgeniuslabs.org, the server returns a list of devices
27 | // with the same public request IP address.
28 |
29 | // Discovery is "opt-in". It is disabled by default. Enable it if you want, if you find it useful.
30 | // Evil Genius Labs, despite the name, is not actually evil, and will never sell or share
31 | // this data to any 3rd parties, ever.
32 |
33 | // This was a feature I needed for my own devices, of which there are dozens. :)
34 |
35 | const bool discovery = true;
36 | const String serverName = "https://ping.evilgeniuslabs.org"; // address of server to ping
37 | const String fingerPrint = "AD 1F CB D9 A0 BC 17 D5 5B F2 E1 BF 98 D1 06 CD AC 3F B8 33"; // server SSL cert fingerprint
38 |
39 | void checkPingTimer()
40 | {
41 | if (!discovery)
42 | return;
43 |
44 | const unsigned long pingDelay = 600000; /// 60 * 10 * 1000; // 10 minutes
45 | static unsigned long lastPingTime = pingDelay;
46 |
47 | if ((millis() - lastPingTime) > pingDelay)
48 | {
49 | // Serial.println("Time to ping");
50 |
51 | // Check WiFi connection status
52 | if (WiFi.status() == WL_CONNECTED)
53 | {
54 | Serial.println("Connected, ready to ping");
55 | HTTPClient http;
56 |
57 | http.begin(serverName, fingerPrint);
58 | http.addHeader("Content-Type", "application/json");
59 | String deviceName = "\"deviceName\":\"" + nameString;
60 | String localIp = WiFi.localIP().toString();
61 | String macAddress = WiFi.macAddress();
62 | String body = "{" +
63 | deviceName +
64 | "\",\"localIp\":\"" + localIp +
65 | "\",\"macAddress\":\"" + macAddress +
66 | "\",\"millis\":" + String(millis()) +
67 | "}";
68 | Serial.print("Pinging ");
69 | Serial.print(serverName);
70 | Serial.print(" with: ");
71 | Serial.println(body);
72 | Serial.print("Millis: ");
73 | Serial.println(millis());
74 | int httpResponseCode = http.POST(body);
75 | Serial.print("Millis: ");
76 | Serial.println(millis());
77 | Serial.print("Ping response code: ");
78 | Serial.println(httpResponseCode);
79 | lastPingTime = millis();
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Eclipse v2
2 | =========
3 |
4 | [Demo Videos](https://youtu.be/OM4Ad-Sr1Ro?list=PLUYGVM-2vDxLnqGd-mG_AMGEECwHlfd5e):
5 |
6 | [](https://youtu.be/OM4Ad-Sr1Ro?list=PLUYGVM-2vDxLnqGd-mG_AMGEECwHlfd5e)
7 |
8 | Small (5.25" / 133.35mm) clock and art display built with 60 RGB LEDs, controlled with an ESP8266 using the FastLED library.
9 |
10 | Fully open-source, and programmable over Wi-Fi or micro USB cable.
11 |
12 | Controlled via a web app over Wi-Fi, and/or a wireless infrared remote control.
13 |
14 | Parts list:
15 |
16 | * 4 [3D printed quarters](https://www.thingiverse.com/thing:2873557) (10mm or 12mm to match your LED strip)
17 | * [ESP8266 Level Shifter Shield](https://www.tindie.com/products/jasoncoon/wemos-d1-mini-esp8266-led-and-level-shifter-shield/)
18 | * [Wood Circle](http://www.michaels.com/circle-shape-by-artminds/10298974.html) or [Round Mirror](http://www.michaels.com/round-mirror-by-artminds/M10025203.html)
19 | * [1m, 144 RGB LED Strip](https://www.adafruit.com/product/1507)
20 | * [ESP8266](https://www.aliexpress.com/item/WEMOS-D1-mini-Pro-16M-bytes-external-antenna-connector-ESP8266-WIFI-Internet-of-Things-development-board/32724692514.html)
21 | * [SN74HCT245N Level Shifter](http://www.digikey.com/product-detail/en/texas-instruments/SN74HCT245N/296-1612-5-ND/277258)
22 | * [1000µF Capacitor](http://www.digikey.com/product-detail/en/panasonic-electronic-components/ECA-1EM102/P5156-ND/245015)
23 | * [0.10µF Capacitor](https://www.digikey.com/product-detail/en/kemet/C320C104M5R5TA/399-9776-ND/3726028)
24 | * [470 ohm resistors](https://www.digikey.com/product-detail/en/stackpole-electronics-inc/CF14JT470R/CF14JT470RCT-ND/1830342)
25 |
26 | Controller assembly instructions: https://www.evilgeniuslabs.org/wifi-led-controller
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/TwinkleFOX.h:
--------------------------------------------------------------------------------
1 | // TwinkleFOX by Mark Kriegsman: https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
2 | //
3 | // TwinkleFOX: Twinkling 'holiday' lights that fade in and out.
4 | // Colors are chosen from a palette; a few palettes are provided.
5 | //
6 | // This December 2015 implementation improves on the December 2014 version
7 | // in several ways:
8 | // - smoother fading, compatible with any colors and any palettes
9 | // - easier control of twinkle speed and twinkle density
10 | // - supports an optional 'background color'
11 | // - takes even less RAM: zero RAM overhead per pixel
12 | // - illustrates a couple of interesting techniques (uh oh...)
13 | //
14 | // The idea behind this (new) implementation is that there's one
15 | // basic, repeating pattern that each pixel follows like a waveform:
16 | // The brightness rises from 0..255 and then falls back down to 0.
17 | // The brightness at any given point in time can be determined as
18 | // as a function of time, for example:
19 | // brightness = sine( time ); // a sine wave of brightness over time
20 | //
21 | // So the way this implementation works is that every pixel follows
22 | // the exact same wave function over time. In this particular case,
23 | // I chose a sawtooth triangle wave (triwave8) rather than a sine wave,
24 | // but the idea is the same: brightness = triwave8( time ).
25 | //
26 | // Of course, if all the pixels used the exact same wave form, and
27 | // if they all used the exact same 'clock' for their 'time base', all
28 | // the pixels would brighten and dim at once -- which does not look
29 | // like twinkling at all.
30 | //
31 | // So to achieve random-looking twinkling, each pixel is given a
32 | // slightly different 'clock' signal. Some of the clocks run faster,
33 | // some run slower, and each 'clock' also has a random offset from zero.
34 | // The net result is that the 'clocks' for all the pixels are always out
35 | // of sync from each other, producing a nice random distribution
36 | // of twinkles.
37 | //
38 | // The 'clock speed adjustment' and 'time offset' for each pixel
39 | // are generated randomly. One (normal) approach to implementing that
40 | // would be to randomly generate the clock parameters for each pixel
41 | // at startup, and store them in some arrays. However, that consumes
42 | // a great deal of precious RAM, and it turns out to be totally
43 | // unnessary! If the random number generate is 'seeded' with the
44 | // same starting value every time, it will generate the same sequence
45 | // of values every time. So the clock adjustment parameters for each
46 | // pixel are 'stored' in a pseudo-random number generator! The PRNG
47 | // is reset, and then the first numbers out of it are the clock
48 | // adjustment parameters for the first pixel, the second numbers out
49 | // of it are the parameters for the second pixel, and so on.
50 | // In this way, we can 'store' a stable sequence of thousands of
51 | // random clock adjustment parameters in literally two bytes of RAM.
52 | //
53 | // There's a little bit of fixed-point math involved in applying the
54 | // clock speed adjustments, which are expressed in eighths. Each pixel's
55 | // clock speed ranges from 8/8ths of the system clock (i.e. 1x) to
56 | // 23/8ths of the system clock (i.e. nearly 3x).
57 | //
58 | // On a basic Arduino Uno or Leonardo, this code can twinkle 300+ pixels
59 | // smoothly at over 50 updates per seond.
60 | //
61 | // -Mark Kriegsman, December 2015
62 |
63 | // Overall twinkle speed.
64 | // 0 (VERY slow) to 8 (VERY fast).
65 | // 4, 5, and 6 are recommended, default is 4.
66 | uint8_t twinkleSpeed = 4;
67 |
68 | // Overall twinkle density.
69 | // 0 (NONE lit) to 8 (ALL lit at once).
70 | // Default is 5.
71 | uint8_t twinkleDensity = 5;
72 |
73 | // Background color for 'unlit' pixels
74 | // Can be set to CRGB::Black if desired.
75 | CRGB gBackgroundColor = CRGB::Black;
76 | // Example of dim incandescent fairy light background color
77 | // CRGB gBackgroundColor = CRGB(CRGB::FairyLight).nscale8_video(16);
78 |
79 | // If AUTO_SELECT_BACKGROUND_COLOR is set to 1,
80 | // then for any palette where the first two entries
81 | // are the same, a dimmed version of that color will
82 | // automatically be used as the background color.
83 | #define AUTO_SELECT_BACKGROUND_COLOR 0
84 |
85 | // If COOL_LIKE_INCANDESCENT is set to 1, colors will
86 | // fade out slighted 'reddened', similar to how
87 | // incandescent bulbs change color as they get dim down.
88 | #define COOL_LIKE_INCANDESCENT 1
89 |
90 | CRGBPalette16 twinkleFoxPalette;
91 |
92 | // This function is like 'triwave8', which produces a
93 | // symmetrical up-and-down triangle sawtooth waveform, except that this
94 | // function produces a triangle wave with a faster attack and a slower decay:
95 | //
96 | // / \
97 | // / \
98 | // / \
99 | // / \
100 | //
101 |
102 | uint8_t attackDecayWave8( uint8_t i)
103 | {
104 | if( i < 86) {
105 | return i * 3;
106 | } else {
107 | i -= 86;
108 | return 255 - (i + (i/2));
109 | }
110 | }
111 |
112 | // This function takes a pixel, and if its in the 'fading down'
113 | // part of the cycle, it adjusts the color a little bit like the
114 | // way that incandescent bulbs fade toward 'red' as they dim.
115 | void coolLikeIncandescent( CRGB& c, uint8_t phase)
116 | {
117 | if( phase < 128) return;
118 |
119 | uint8_t cooling = (phase - 128) >> 4;
120 | c.g = qsub8( c.g, cooling);
121 | c.b = qsub8( c.b, cooling * 2);
122 | }
123 |
124 | // This function takes a time in pseudo-milliseconds,
125 | // figures out brightness = f( time ), and also hue = f( time )
126 | // The 'low digits' of the millisecond time are used as
127 | // input to the brightness wave function.
128 | // The 'high digits' are used to select a color, so that the color
129 | // does not change over the course of the fade-in, fade-out
130 | // of one cycle of the brightness wave function.
131 | // The 'high digits' are also used to determine whether this pixel
132 | // should light at all during this cycle, based on the twinkleDensity.
133 | CRGB computeOneTwinkle( uint32_t ms, uint8_t salt)
134 | {
135 | uint16_t ticks = ms >> (8-twinkleSpeed);
136 | uint8_t fastcycle8 = ticks;
137 | uint16_t slowcycle16 = (ticks >> 8) + salt;
138 | slowcycle16 += sin8( slowcycle16);
139 | slowcycle16 = (slowcycle16 * 2053) + 1384;
140 | uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
141 |
142 | uint8_t bright = 0;
143 | if( ((slowcycle8 & 0x0E)/2) < twinkleDensity) {
144 | bright = attackDecayWave8( fastcycle8);
145 | }
146 |
147 | uint8_t hue = slowcycle8 - salt;
148 | CRGB c;
149 | if( bright > 0) {
150 | c = ColorFromPalette( twinkleFoxPalette, hue, bright, NOBLEND);
151 | if( COOL_LIKE_INCANDESCENT == 1 ) {
152 | coolLikeIncandescent( c, fastcycle8);
153 | }
154 | } else {
155 | c = CRGB::Black;
156 | }
157 | return c;
158 | }
159 |
160 | // This function loops over each pixel, calculates the
161 | // adjusted 'clock' that this pixel should use, and calls
162 | // "CalculateOneTwinkle" on each pixel. It then displays
163 | // either the twinkle color of the background color,
164 | // whichever is brighter.
165 | void drawTwinkles()
166 | {
167 | // "PRNG16" is the pseudorandom number generator
168 | // It MUST be reset to the same starting value each time
169 | // this function is called, so that the sequence of 'random'
170 | // numbers that it generates is (paradoxically) stable.
171 | uint16_t PRNG16 = 11337;
172 |
173 | uint32_t clock32 = millis();
174 |
175 | // Set up the background color, "bg".
176 | // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of
177 | // the current palette are identical, then a deeply faded version of
178 | // that color is used for the background color
179 | CRGB bg;
180 | if( (AUTO_SELECT_BACKGROUND_COLOR == 1) &&
181 | (twinkleFoxPalette[0] == twinkleFoxPalette[1] )) {
182 | bg = twinkleFoxPalette[0];
183 | uint8_t bglight = bg.getAverageLight();
184 | if( bglight > 64) {
185 | bg.nscale8_video( 16); // very bright, so scale to 1/16th
186 | } else if( bglight > 16) {
187 | bg.nscale8_video( 64); // not that bright, so scale to 1/4th
188 | } else {
189 | bg.nscale8_video( 86); // dim, scale to 1/3rd.
190 | }
191 | } else {
192 | bg = gBackgroundColor; // just use the explicitly defined background color
193 | }
194 |
195 | uint8_t backgroundBrightness = bg.getAverageLight();
196 |
197 | for(uint8_t i = 0; i < NUM_LEDS; i++) {
198 | CRGB& pixel = leds[i];
199 |
200 | PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
201 | uint16_t myclockoffset16= PRNG16; // use that number as clock offset
202 | PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
203 | // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
204 | uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
205 | uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
206 | uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
207 |
208 | // We now have the adjusted 'clock' for this pixel, now we call
209 | // the function that computes what color the pixel should be based
210 | // on the "brightness = f( time )" idea.
211 | CRGB c = computeOneTwinkle( myclock30, myunique8);
212 |
213 | uint8_t cbright = c.getAverageLight();
214 | int16_t deltabright = cbright - backgroundBrightness;
215 | if( deltabright >= 32 || (!bg)) {
216 | // If the new pixel is significantly brighter than the background color,
217 | // use the new color.
218 | pixel = c;
219 | } else if( deltabright > 0 ) {
220 | // If the new pixel is just slightly brighter than the background color,
221 | // mix a blend of the new color and the background color
222 | pixel = blend( bg, c, deltabright * 8);
223 | } else {
224 | // if the new pixel is not at all brighter than the background color,
225 | // just use the background color.
226 | pixel = bg;
227 | }
228 | }
229 | }
230 |
231 | // A mostly red palette with green accents and white trim.
232 | // "CRGB::Gray" is used as white to keep the brightness more uniform.
233 | const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM =
234 | { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
235 | CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
236 | CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
237 | CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green };
238 |
239 | // A mostly (dark) green palette with red berries.
240 | #define Holly_Green 0x00580c
241 | #define Holly_Red 0xB00402
242 | const TProgmemRGBPalette16 Holly_p FL_PROGMEM =
243 | { Holly_Green, Holly_Green, Holly_Green, Holly_Green,
244 | Holly_Green, Holly_Green, Holly_Green, Holly_Green,
245 | Holly_Green, Holly_Green, Holly_Green, Holly_Green,
246 | Holly_Green, Holly_Green, Holly_Green, Holly_Red
247 | };
248 |
249 | // A red and white striped palette
250 | // "CRGB::Gray" is used as white to keep the brightness more uniform.
251 | const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM =
252 | { CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
253 | CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
254 | CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
255 | CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray };
256 |
257 | // A mostly blue palette with white accents.
258 | // "CRGB::Gray" is used as white to keep the brightness more uniform.
259 | const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM =
260 | { CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
261 | CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
262 | CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
263 | CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray };
264 |
265 | // A pure "fairy light" palette with some brightness variations
266 | #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2)
267 | #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4)
268 | const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM =
269 | { CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight,
270 | HALFFAIRY, HALFFAIRY, CRGB::FairyLight, CRGB::FairyLight,
271 | QUARTERFAIRY, QUARTERFAIRY, CRGB::FairyLight, CRGB::FairyLight,
272 | CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight };
273 |
274 | // A palette of soft snowflakes with the occasional bright one
275 | const TProgmemRGBPalette16 Snow_p FL_PROGMEM =
276 | { 0x304048, 0x304048, 0x304048, 0x304048,
277 | 0x304048, 0x304048, 0x304048, 0x304048,
278 | 0x304048, 0x304048, 0x304048, 0x304048,
279 | 0x304048, 0x304048, 0x304048, 0xE0F0FF };
280 |
281 | // A palette reminiscent of large 'old-school' C9-size tree lights
282 | // in the five classic colors: red, orange, green, blue, and white.
283 | #define C9_Red 0xB80400
284 | #define C9_Orange 0x902C02
285 | #define C9_Green 0x046002
286 | #define C9_Blue 0x070758
287 | #define C9_White 0x606820
288 | const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM =
289 | { C9_Red, C9_Orange, C9_Red, C9_Orange,
290 | C9_Orange, C9_Red, C9_Orange, C9_Red,
291 | C9_Green, C9_Green, C9_Green, C9_Green,
292 | C9_Blue, C9_Blue, C9_Blue,
293 | C9_White
294 | };
295 |
296 | // A cold, icy pale blue palette
297 | #define Ice_Blue1 0x0C1040
298 | #define Ice_Blue2 0x182080
299 | #define Ice_Blue3 0x5080C0
300 | const TProgmemRGBPalette16 Ice_p FL_PROGMEM =
301 | {
302 | Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
303 | Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
304 | Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
305 | Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3
306 | };
307 |
308 | void redGreenWhiteTwinkles()
309 | {
310 | twinkleFoxPalette = RedGreenWhite_p;
311 | drawTwinkles();
312 | }
313 |
314 | void hollyTwinkles()
315 | {
316 | twinkleFoxPalette = Holly_p;
317 | drawTwinkles();
318 | }
319 |
320 | void redWhiteTwinkles()
321 | {
322 | twinkleFoxPalette = RedWhite_p;
323 | drawTwinkles();
324 | }
325 |
326 | void blueWhiteTwinkles()
327 | {
328 | twinkleFoxPalette = BlueWhite_p;
329 | drawTwinkles();
330 | }
331 |
332 | void fairyLightTwinkles()
333 | {
334 | twinkleFoxPalette = FairyLight_p;
335 | drawTwinkles();
336 | }
337 |
338 | void snow2Twinkles()
339 | {
340 | twinkleFoxPalette = Snow_p;
341 | drawTwinkles();
342 | }
343 |
344 | void iceTwinkles()
345 | {
346 | twinkleFoxPalette = Ice_p;
347 | drawTwinkles();
348 | }
349 |
350 | void retroC9Twinkles()
351 | {
352 | twinkleFoxPalette = RetroC9_p;
353 | drawTwinkles();
354 | }
355 |
356 | void partyTwinkles()
357 | {
358 | twinkleFoxPalette = PartyColors_p;
359 | drawTwinkles();
360 | }
361 |
362 | void forestTwinkles()
363 | {
364 | twinkleFoxPalette = ForestColors_p;
365 | drawTwinkles();
366 | }
367 |
368 | void lavaTwinkles()
369 | {
370 | twinkleFoxPalette = LavaColors_p;
371 | drawTwinkles();
372 | }
373 |
374 | void fireTwinkles()
375 | {
376 | twinkleFoxPalette = HeatColors_p;
377 | drawTwinkles();
378 | }
379 |
380 | void cloud2Twinkles()
381 | {
382 | twinkleFoxPalette = CloudColors_p;
383 | drawTwinkles();
384 | }
385 |
386 | void oceanTwinkles()
387 | {
388 | twinkleFoxPalette = OceanColors_p;
389 | drawTwinkles();
390 | }
391 |
--------------------------------------------------------------------------------
/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 | EVERY_N_MILLIS(30)
75 | {
76 | // Make each pixel brighter or darker, depending on
77 | // its 'direction' flag.
78 | brightenOrDarkenEachPixel( FADE_IN_SPEED, FADE_OUT_SPEED);
79 |
80 | // Now consider adding a new random twinkle
81 | if ( random8() < DENSITY ) {
82 | int pos = random16(NUM_LEDS);
83 | if ( !leds[pos]) {
84 | leds[pos] = ColorFromPalette( gCurrentPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
85 | setPixelDirection(pos, GETTING_BRIGHTER);
86 | }
87 | }
88 | }
89 | }
90 |
91 | void cloudTwinkles()
92 | {
93 | gCurrentPalette = CloudColors_p; // Blues and whites!
94 | colortwinkles();
95 | }
96 |
97 | void rainbowTwinkles()
98 | {
99 | gCurrentPalette = RainbowColors_p;
100 | colortwinkles();
101 | }
102 |
103 | void snowTwinkles()
104 | {
105 | CRGB w(85, 85, 85), W(CRGB::White);
106 |
107 | gCurrentPalette = CRGBPalette16( W, W, W, W, w, w, w, w, w, w, w, w, w, w, w, w );
108 | colortwinkles();
109 | }
110 |
111 | void 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 | }
118 |
119 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | outputDir=build
2 | arduinoDir=C:/Users/Jason/dev/arduino-1.6.12
3 | arduinoDataDir=C:/Users/Jason/AppData/Local/Arduino15
4 | arduinoSketchBookDir=C:/Users/Jason/Documents/Arduino
5 |
6 | mkdir -p $outputDir/
7 |
8 | $arduinoDir/arduino-builder -compile -logger=machine -hardware $arduinoDir/hardware -hardware $arduinoDataDir/packages -hardware $arduinoSketchBookDir/hardware -tools $arduinoDir/tools-builder -tools $arduinoDir/hardware/tools/avr -tools $arduinoDataDir/packages -built-in-libraries $arduinoDir/libraries -libraries $arduinoSketchBookDir/libraries -fqbn=esp8266:esp8266:d1_mini:CpuFrequency=160,UploadSpeed=921600,FlashSize=4M3M -ide-version=10612 -build-path $outputDir/ -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.esptool.path=$arduinoDataDir/packages/esp8266/tools/esptool/0.4.9 -prefs=runtime.tools.xtensa-lx106-elf-gcc.path=$arduinoDataDir/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2 -prefs=runtime.tools.mkspiffs.path=$arduinoDataDir/packages/esp8266/tools/mkspiffs/0.1.2 -verbose tree-v2.ino
9 |
--------------------------------------------------------------------------------
/data/css/simple.css:
--------------------------------------------------------------------------------
1 | /*body {
2 | padding-bottom: 70px;
3 | }*/
4 |
5 | .grid-item-color {
6 | width: 4%;
7 | height: 32px;
8 | cursor: pointer;
9 | }
10 |
11 | .grid-item-pattern {
12 | width: 100px;
13 | height: 100px;
14 | margin: 5px;
15 | padding: 6px;
16 | white-space: normal;
17 | cursor: pointer;
18 | }
19 |
--------------------------------------------------------------------------------
/data/css/styles.css:
--------------------------------------------------------------------------------
1 | body { padding-bottom: 70px; }
2 |
--------------------------------------------------------------------------------
/data/edit.htm:
--------------------------------------------------------------------------------
1 | ESP Editor
4 |
--------------------------------------------------------------------------------
/data/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evilgeniuslabs/eclipse-v2/dbeb696b232de5c152bb03bfafe816a5ed9fe7f4/data/favicon.ico
--------------------------------------------------------------------------------
/data/fonts/glyphicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evilgeniuslabs/eclipse-v2/dbeb696b232de5c152bb03bfafe816a5ed9fe7f4/data/fonts/glyphicons.eot
--------------------------------------------------------------------------------
/data/fonts/glyphicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evilgeniuslabs/eclipse-v2/dbeb696b232de5c152bb03bfafe816a5ed9fe7f4/data/fonts/glyphicons.ttf
--------------------------------------------------------------------------------
/data/fonts/glyphicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evilgeniuslabs/eclipse-v2/dbeb696b232de5c152bb03bfafe816a5ed9fe7f4/data/fonts/glyphicons.woff
--------------------------------------------------------------------------------
/data/fonts/glyphicons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evilgeniuslabs/eclipse-v2/dbeb696b232de5c152bb03bfafe816a5ed9fe7f4/data/fonts/glyphicons.woff2
--------------------------------------------------------------------------------
/data/images/atom196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evilgeniuslabs/eclipse-v2/dbeb696b232de5c152bb03bfafe816a5ed9fe7f4/data/images/atom196.png
--------------------------------------------------------------------------------
/data/index.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Eclipse v2 by Evil Genius Labs
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
54 |
55 |