Added /json/state

This commit is contained in:
cschwinne 2019-03-05 10:59:15 +01:00
parent 0377958d8f
commit 3f9b37aa7f
10 changed files with 258 additions and 184 deletions

View File

@ -26,7 +26,7 @@ lib_deps_external =
#Blynk@0.5.4(changed) #Blynk@0.5.4(changed)
#E131@1.0.0(changed) #E131@1.0.0(changed)
FastLED@3.2.6 FastLED@3.2.6
NeoPixelBus@2.3.5 NeoPixelBus@2.4.3
ESPAsyncTCP@1.2.0 ESPAsyncTCP@1.2.0
AsyncTCP@1.0.3 AsyncTCP@1.0.3
EspAsyncWebServer@1.2.0 EspAsyncWebServer@1.2.0

View File

@ -14,11 +14,11 @@
#else //esp8266 #else //esp8266
//autoselect the right method depending on strip pin //autoselect the right method depending on strip pin
#if LEDPIN == 2 #if LEDPIN == 2
#define PIXELMETHOD NeoEsp8266UartWs2813Method //if you get an error here, try to change to NeoEsp8266Uart1Ws2813Method or use Neopixelbus v2.3.5 #define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus
#elif LEDPIN == 3 #elif LEDPIN == 3
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod #define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
#else #else
#define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod #define PIXELMETHOD NeoEsp8266BitBangWs2813Method
#pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results." #pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results."
#endif #endif
#endif #endif

View File

@ -35,7 +35,7 @@
*/ */
uint16_t WS2812FX::mode_static(void) { uint16_t WS2812FX::mode_static(void) {
fill(SEGMENT.colors[0]); fill(SEGMENT.colors[0]);
return (SEGMENT_RUNTIME.trans_act == 1) ? 20 : 500; return ((SEGMENT.options >> 7) & 0x01) ? 20 : 500; //update faster if in transition
} }
@ -48,7 +48,7 @@ uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_
uint32_t color = ((SEGMENT_RUNTIME.counter_mode_call & 1) == 0) ? color1 : color2; uint32_t color = ((SEGMENT_RUNTIME.counter_mode_call & 1) == 0) ? color1 : color2;
if (color == color1 && do_palette) if (color == color1 && do_palette)
{ {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
} }
} else { } else {
@ -108,7 +108,7 @@ uint16_t WS2812FX::color_wipe(uint32_t color1, uint32_t color2, bool rev, bool d
} else { } else {
uint32_t led_offset = SEGMENT_RUNTIME.counter_mode_step - SEGMENT_LENGTH; uint32_t led_offset = SEGMENT_RUNTIME.counter_mode_step - SEGMENT_LENGTH;
if(rev) { if(rev) {
setPixelColor(SEGMENT.stop - led_offset, color2); setPixelColor(SEGMENT.stop -1 - led_offset, color2);
} else { } else {
setPixelColor(SEGMENT.start + led_offset, color2); setPixelColor(SEGMENT.start + led_offset, color2);
} }
@ -167,7 +167,7 @@ uint16_t WS2812FX::mode_random_color(void) {
SEGMENT_RUNTIME.aux_param = get_random_wheel_index(SEGMENT_RUNTIME.aux_param); // aux_param will store our random color wheel index SEGMENT_RUNTIME.aux_param = get_random_wheel_index(SEGMENT_RUNTIME.aux_param); // aux_param will store our random color wheel index
uint32_t color = color_wheel(SEGMENT_RUNTIME.aux_param); uint32_t color = color_wheel(SEGMENT_RUNTIME.aux_param);
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color); setPixelColor(i, color);
} }
return 50 + (20 * (uint32_t)(255 - SEGMENT.speed)); return 50 + (20 * (uint32_t)(255 - SEGMENT.speed));
@ -180,7 +180,7 @@ uint16_t WS2812FX::mode_random_color(void) {
*/ */
uint16_t WS2812FX::mode_dynamic(void) { uint16_t WS2812FX::mode_dynamic(void) {
if(SEGMENT.intensity > 127 || SEGMENT_RUNTIME.counter_mode_call == 0) { if(SEGMENT.intensity > 127 || SEGMENT_RUNTIME.counter_mode_call == 0) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_wheel(random8())); setPixelColor(i, color_wheel(random8()));
} }
} }
@ -214,12 +214,12 @@ uint16_t WS2812FX::mode_breath(void) {
uint8_t r = ((color >> 16 & 0xFF) * lum) >> 8; uint8_t r = ((color >> 16 & 0xFF) * lum) >> 8;
uint8_t g = ((color >> 8 & 0xFF) * lum) >> 8; uint8_t g = ((color >> 8 & 0xFF) * lum) >> 8;
uint8_t b = ((color & 0xFF) * lum) >> 8; uint8_t b = ((color & 0xFF) * lum) >> 8;
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, r, g, b, w); setPixelColor(i, r, g, b, w);
} }
} else } else
{ {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, lum)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, lum));
} }
} }
@ -237,7 +237,7 @@ uint16_t WS2812FX::mode_fade(void) {
int lum = SEGMENT_RUNTIME.counter_mode_step; int lum = SEGMENT_RUNTIME.counter_mode_step;
if(lum > 255) lum = 511 - lum; // lum = 0 -> 255 -> 0 if(lum > 255) lum = 511 - lum; // lum = 0 -> 255 -> 0
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGMENT.colors[1], lum)); setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGMENT.colors[1], lum));
} }
@ -474,7 +474,7 @@ uint16_t WS2812FX::mode_dissolve_random(void) {
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t WS2812FX::mode_sparkle(void) { uint16_t WS2812FX::mode_sparkle(void) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
} }
SEGMENT_RUNTIME.aux_param = random16(SEGMENT_LENGTH); // aux_param stores the random led index SEGMENT_RUNTIME.aux_param = random16(SEGMENT_LENGTH); // aux_param stores the random led index
@ -489,7 +489,7 @@ uint16_t WS2812FX::mode_sparkle(void) {
*/ */
uint16_t WS2812FX::mode_flash_sparkle(void) { uint16_t WS2812FX::mode_flash_sparkle(void) {
if(SEGMENT_RUNTIME.counter_mode_call == 0) { if(SEGMENT_RUNTIME.counter_mode_call == 0) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
} }
} }
@ -511,7 +511,7 @@ uint16_t WS2812FX::mode_flash_sparkle(void) {
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t WS2812FX::mode_hyper_sparkle(void) { uint16_t WS2812FX::mode_hyper_sparkle(void) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
} }
@ -529,7 +529,7 @@ uint16_t WS2812FX::mode_hyper_sparkle(void) {
* Strobe effect with different strobe count and pause, controlled by speed. * Strobe effect with different strobe count and pause, controlled by speed.
*/ */
uint16_t WS2812FX::mode_multi_strobe(void) { uint16_t WS2812FX::mode_multi_strobe(void) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
} }
@ -537,7 +537,7 @@ uint16_t WS2812FX::mode_multi_strobe(void) {
uint16_t count = 2 * ((SEGMENT.speed / 10) + 1); uint16_t count = 2 * ((SEGMENT.speed / 10) + 1);
if(SEGMENT_RUNTIME.counter_mode_step < count) { if(SEGMENT_RUNTIME.counter_mode_step < count) {
if((SEGMENT_RUNTIME.counter_mode_step & 1) == 0) { if((SEGMENT_RUNTIME.counter_mode_step & 1) == 0) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, SEGMENT.colors[0]); setPixelColor(i, SEGMENT.colors[0]);
} }
delay = 20; delay = 20;
@ -559,7 +559,7 @@ uint16_t WS2812FX::mode_android(void) {
SEGMENT_RUNTIME.counter_mode_step = SEGMENT.start; SEGMENT_RUNTIME.counter_mode_step = SEGMENT.start;
} }
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
} }
@ -583,19 +583,19 @@ uint16_t WS2812FX::mode_android(void) {
if (SEGMENT_RUNTIME.counter_mode_call %3 != 1) SEGMENT_RUNTIME.aux_param2--; if (SEGMENT_RUNTIME.counter_mode_call %3 != 1) SEGMENT_RUNTIME.aux_param2--;
} }
if (a > SEGMENT.stop) a = SEGMENT.start; if (a >= SEGMENT.stop) a = SEGMENT.start;
if (a + SEGMENT_RUNTIME.aux_param2 <= SEGMENT.stop) if (a + SEGMENT_RUNTIME.aux_param2 < SEGMENT.stop)
{ {
for(int i = a; i < a+SEGMENT_RUNTIME.aux_param2; i++) { for(int i = a; i < a+SEGMENT_RUNTIME.aux_param2; i++) {
setPixelColor(i, SEGMENT.colors[0]); setPixelColor(i, SEGMENT.colors[0]);
} }
} else } else
{ {
for(int i = a; i <= SEGMENT.stop; i++) { for(int i = a; i < SEGMENT.stop; i++) {
setPixelColor(i, SEGMENT.colors[0]); setPixelColor(i, SEGMENT.colors[0]);
} }
for(int i = SEGMENT.start; i < SEGMENT_RUNTIME.aux_param2 - (SEGMENT.stop +1 -a); i++) { for(int i = SEGMENT.start; i < SEGMENT_RUNTIME.aux_param2 - (SEGMENT.stop -a); i++) {
setPixelColor(i, SEGMENT.colors[0]); setPixelColor(i, SEGMENT.colors[0]);
} }
} }
@ -671,7 +671,7 @@ uint16_t WS2812FX::mode_colorful(void) {
for (uint8_t i = 4; i < 7; i++) cols[i] = cols[i-4]; for (uint8_t i = 4; i < 7; i++) cols[i] = cols[i-4];
} }
int i = SEGMENT.start; int i = SEGMENT.start;
for (i; i <= SEGMENT.stop ; i+=4) for (i; i < SEGMENT.stop ; i+=4)
{ {
setPixelColor(i, cols[SEGMENT_RUNTIME.counter_mode_step]); setPixelColor(i, cols[SEGMENT_RUNTIME.counter_mode_step]);
setPixelColor(i+1, cols[SEGMENT_RUNTIME.counter_mode_step+1]); setPixelColor(i+1, cols[SEGMENT_RUNTIME.counter_mode_step+1]);
@ -679,15 +679,15 @@ uint16_t WS2812FX::mode_colorful(void) {
setPixelColor(i+3, cols[SEGMENT_RUNTIME.counter_mode_step+3]); setPixelColor(i+3, cols[SEGMENT_RUNTIME.counter_mode_step+3]);
} }
i+=4; i+=4;
if(i <= SEGMENT.stop) if(i < SEGMENT.stop)
{ {
setPixelColor(i, cols[SEGMENT_RUNTIME.counter_mode_step]); setPixelColor(i, cols[SEGMENT_RUNTIME.counter_mode_step]);
if(i+1 <= SEGMENT.stop) if(i+1 < SEGMENT.stop)
{ {
setPixelColor(i+1, cols[SEGMENT_RUNTIME.counter_mode_step+1]); setPixelColor(i+1, cols[SEGMENT_RUNTIME.counter_mode_step+1]);
if(i+2 <= SEGMENT.stop) if(i+2 < SEGMENT.stop)
{ {
setPixelColor(i+2, cols[SEGMENT_RUNTIME.counter_mode_step+2]); setPixelColor(i+2, cols[SEGMENT_RUNTIME.counter_mode_step+2]);
} }
@ -704,10 +704,10 @@ uint16_t WS2812FX::mode_colorful(void) {
* Emulates a traffic light. * Emulates a traffic light.
*/ */
uint16_t WS2812FX::mode_traffic_light(void) { uint16_t WS2812FX::mode_traffic_light(void) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++)
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
uint32_t mdelay = 500; uint32_t mdelay = 500;
for (int i = SEGMENT.start; i < SEGMENT.stop-1 ; i+=3) for (int i = SEGMENT.start; i < SEGMENT.stop-2 ; i+=3)
{ {
switch (SEGMENT_RUNTIME.counter_mode_step) switch (SEGMENT_RUNTIME.counter_mode_step)
{ {
@ -743,7 +743,7 @@ uint16_t WS2812FX::mode_chase_flash(void) {
const static uint8_t flash_count = 4; const static uint8_t flash_count = 4;
uint8_t flash_step = SEGMENT_RUNTIME.counter_mode_call % ((flash_count * 2) + 1); uint8_t flash_step = SEGMENT_RUNTIME.counter_mode_call % ((flash_count * 2) + 1);
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
} }
@ -808,13 +808,13 @@ uint16_t WS2812FX::running(uint32_t color1, uint32_t color2) {
if((i + SEGMENT_RUNTIME.counter_mode_step) % 4 < 2) { if((i + SEGMENT_RUNTIME.counter_mode_step) % 4 < 2) {
if (color1 == SEGMENT.colors[0]) if (color1 == SEGMENT.colors[0])
{ {
setPixelColor(SEGMENT.stop - i, color_from_palette(SEGMENT.stop - i, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(SEGMENT.stop -i, color_from_palette(SEGMENT.stop -i -1, true, PALETTE_SOLID_WRAP, 0));
} else } else
{ {
setPixelColor(SEGMENT.stop - i, color1); setPixelColor(SEGMENT.stop -i -1, color1);
} }
} else { } else {
setPixelColor(SEGMENT.stop - i, color2); setPixelColor(SEGMENT.stop -i -1, color2);
} }
} }
@ -918,8 +918,8 @@ uint16_t WS2812FX::mode_fireworks() {
SEGMENT_RUNTIME.aux_param = UINT16_MAX; SEGMENT_RUNTIME.aux_param = UINT16_MAX;
SEGMENT_RUNTIME.aux_param2 = UINT16_MAX; SEGMENT_RUNTIME.aux_param2 = UINT16_MAX;
} }
bool valid1 = (SEGMENT_RUNTIME.aux_param <= SEGMENT.stop && SEGMENT_RUNTIME.aux_param >= SEGMENT.start); bool valid1 = (SEGMENT_RUNTIME.aux_param < SEGMENT.stop && SEGMENT_RUNTIME.aux_param >= SEGMENT.start);
bool valid2 = (SEGMENT_RUNTIME.aux_param2 <= SEGMENT.stop && SEGMENT_RUNTIME.aux_param2 >= SEGMENT.start); bool valid2 = (SEGMENT_RUNTIME.aux_param2 < SEGMENT.stop && SEGMENT_RUNTIME.aux_param2 >= SEGMENT.start);
uint32_t sv1 = 0, sv2 = 0; uint32_t sv1 = 0, sv2 = 0;
if (valid1) sv1 = getPixelColor(SEGMENT_RUNTIME.aux_param); if (valid1) sv1 = getPixelColor(SEGMENT_RUNTIME.aux_param);
if (valid2) sv2 = getPixelColor(SEGMENT_RUNTIME.aux_param2); if (valid2) sv2 = getPixelColor(SEGMENT_RUNTIME.aux_param2);
@ -946,8 +946,8 @@ uint16_t WS2812FX::mode_rain()
if (SEGMENT_RUNTIME.counter_mode_step > SPEED_FORMULA_L) { if (SEGMENT_RUNTIME.counter_mode_step > SPEED_FORMULA_L) {
SEGMENT_RUNTIME.counter_mode_step = 0; SEGMENT_RUNTIME.counter_mode_step = 0;
//shift all leds right //shift all leds right
uint32_t ctemp = getPixelColor(SEGMENT.stop); uint32_t ctemp = getPixelColor(SEGMENT.stop -1);
for(uint16_t i=SEGMENT.stop; i>SEGMENT.start; i--) { for(uint16_t i=SEGMENT.stop -1; i>SEGMENT.start; i--) {
setPixelColor(i, getPixelColor(i-1)); setPixelColor(i, getPixelColor(i-1));
} }
setPixelColor(SEGMENT.start, ctemp); setPixelColor(SEGMENT.start, ctemp);
@ -955,8 +955,8 @@ uint16_t WS2812FX::mode_rain()
SEGMENT_RUNTIME.aux_param2++; SEGMENT_RUNTIME.aux_param2++;
if (SEGMENT_RUNTIME.aux_param == 0) SEGMENT_RUNTIME.aux_param = UINT16_MAX; if (SEGMENT_RUNTIME.aux_param == 0) SEGMENT_RUNTIME.aux_param = UINT16_MAX;
if (SEGMENT_RUNTIME.aux_param2 == 0) SEGMENT_RUNTIME.aux_param = UINT16_MAX; if (SEGMENT_RUNTIME.aux_param2 == 0) SEGMENT_RUNTIME.aux_param = UINT16_MAX;
if (SEGMENT_RUNTIME.aux_param == SEGMENT.stop +1) SEGMENT_RUNTIME.aux_param = SEGMENT.start; if (SEGMENT_RUNTIME.aux_param == SEGMENT.stop) SEGMENT_RUNTIME.aux_param = SEGMENT.start;
if (SEGMENT_RUNTIME.aux_param2 == SEGMENT.stop +1) SEGMENT_RUNTIME.aux_param2 = SEGMENT.start; if (SEGMENT_RUNTIME.aux_param2 == SEGMENT.stop) SEGMENT_RUNTIME.aux_param2 = SEGMENT.start;
} }
return mode_fireworks(); return mode_fireworks();
} }
@ -972,7 +972,7 @@ uint16_t WS2812FX::mode_fire_flicker(void) {
byte b = (SEGMENT.colors[0] & 0xFF); byte b = (SEGMENT.colors[0] & 0xFF);
byte lum = (SEGMENT.palette == 0) ? max(w, max(r, max(g, b))) : 255; byte lum = (SEGMENT.palette == 0) ? max(w, max(r, max(g, b))) : 255;
lum /= (((256-SEGMENT.intensity)/16)+1); lum /= (((256-SEGMENT.intensity)/16)+1);
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
byte flicker = random8(lum); byte flicker = random8(lum);
if (SEGMENT.palette == 0) { if (SEGMENT.palette == 0) {
setPixelColor(i, max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0)); setPixelColor(i, max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0));
@ -997,7 +997,7 @@ uint16_t WS2812FX::gradient_base(bool loading) {
int p1 = pp-SEGMENT_LENGTH; int p1 = pp-SEGMENT_LENGTH;
int p2 = pp+SEGMENT_LENGTH; int p2 = pp+SEGMENT_LENGTH;
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++)
{ {
if (loading) if (loading)
{ {
@ -1011,7 +1011,7 @@ uint16_t WS2812FX::gradient_base(bool loading) {
} }
SEGMENT_RUNTIME.counter_mode_step++; SEGMENT_RUNTIME.counter_mode_step++;
if (SEGMENT_RUNTIME.counter_mode_step > SEGMENT.stop) SEGMENT_RUNTIME.counter_mode_step = SEGMENT.start; if (SEGMENT_RUNTIME.counter_mode_step >= SEGMENT.stop) SEGMENT_RUNTIME.counter_mode_step = SEGMENT.start;
if (SEGMENT.speed == 0) SEGMENT_RUNTIME.counter_mode_step = SEGMENT.start + (SEGMENT_LENGTH >> 1); if (SEGMENT.speed == 0) SEGMENT_RUNTIME.counter_mode_step = SEGMENT.start + (SEGMENT_LENGTH >> 1);
return SPEED_FORMULA_L; return SPEED_FORMULA_L;
} }
@ -1224,7 +1224,7 @@ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) {
if(index > 3) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); if(index > 3) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1);
else if(index > 1) color = color2; else if(index > 1) color = color2;
setPixelColor(SEGMENT.stop - i, color); setPixelColor(SEGMENT.stop - i -1, color);
} }
SEGMENT_RUNTIME.counter_mode_step++; SEGMENT_RUNTIME.counter_mode_step++;
@ -1335,7 +1335,7 @@ uint16_t WS2812FX::mode_tricolor_fade(void)
byte stp = SEGMENT_RUNTIME.counter_mode_step % 256; byte stp = SEGMENT_RUNTIME.counter_mode_step % 256;
uint32_t color = 0; uint32_t color = 0;
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
if (stage == 2) { if (stage == 2) {
color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp);
} else if (stage == 1) { } else if (stage == 1) {
@ -1401,7 +1401,7 @@ uint16_t WS2812FX::mode_dual_larson_scanner(void){
uint16_t index = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step; uint16_t index = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step;
setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0));
index = SEGMENT.stop - SEGMENT_RUNTIME.counter_mode_step; index = SEGMENT.stop - SEGMENT_RUNTIME.counter_mode_step -1;
if (SEGMENT.colors[2] != 0) if (SEGMENT.colors[2] != 0)
{ {
setPixelColor(index, SEGMENT.colors[2]); setPixelColor(index, SEGMENT.colors[2]);
@ -1410,7 +1410,7 @@ uint16_t WS2812FX::mode_dual_larson_scanner(void){
setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0));
} }
if(SEGMENT_RUNTIME.counter_mode_step >= (SEGMENT.stop - SEGMENT.start) || SEGMENT_RUNTIME.counter_mode_step <= 0) if(SEGMENT_RUNTIME.counter_mode_step >= SEGMENT_LENGTH -1 || SEGMENT_RUNTIME.counter_mode_step <= 0)
SEGMENT_RUNTIME.aux_param = !SEGMENT_RUNTIME.aux_param; SEGMENT_RUNTIME.aux_param = !SEGMENT_RUNTIME.aux_param;
return SPEED_FORMULA_L; return SPEED_FORMULA_L;
@ -1423,10 +1423,11 @@ uint16_t WS2812FX::mode_dual_larson_scanner(void){
*/ */
uint16_t WS2812FX::mode_random_chase(void) uint16_t WS2812FX::mode_random_chase(void)
{ {
for(uint16_t i=SEGMENT.stop; i>SEGMENT.start; i--) { for(uint16_t i=SEGMENT.stop -1; i>SEGMENT.start; i--) {
setPixelColor(i, getPixelColor(i-1)); setPixelColor(i, getPixelColor(i-1));
} }
uint32_t color = getPixelColor(SEGMENT.start + 1); uint32_t color = getPixelColor(SEGMENT.start);
if (SEGMENT_LENGTH > 1) color = getPixelColor(SEGMENT.start + 1);
uint8_t r = random8(6) != 0 ? (color >> 16 & 0xFF) : random8(); uint8_t r = random8(6) != 0 ? (color >> 16 & 0xFF) : random8();
uint8_t g = random8(6) != 0 ? (color >> 8 & 0xFF) : random8(); uint8_t g = random8(6) != 0 ? (color >> 8 & 0xFF) : random8();
uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8(); uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8();
@ -1480,8 +1481,8 @@ uint16_t WS2812FX::mode_oscillate(void)
uint16_t WS2812FX::mode_lightning(void) uint16_t WS2812FX::mode_lightning(void)
{ {
uint16_t ledstart = SEGMENT.start + random8(SEGMENT_LENGTH); // Determine starting location of flash uint16_t ledstart = SEGMENT.start + random8(SEGMENT_LENGTH); // Determine starting location of flash
uint16_t ledlen = random8(SEGMENT.stop - ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint16_t ledlen = random8(SEGMENT.stop -1 -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1)
uint8_t bri = 255/random8(1, 3); uint8_t bri = 255/random8(1, 3);
if (SEGMENT_RUNTIME.counter_mode_step == 0) if (SEGMENT_RUNTIME.counter_mode_step == 0)
@ -1540,7 +1541,7 @@ uint16_t WS2812FX::mode_pride_2015(void)
uint16_t brightnesstheta16 = sPseudotime; uint16_t brightnesstheta16 = sPseudotime;
CRGB fastled_col; CRGB fastled_col;
for( uint16_t i = SEGMENT.start ; i <= SEGMENT.stop; i++) { for( uint16_t i = SEGMENT.start ; i < SEGMENT.stop; i++) {
hue16 += hueinc16; hue16 += hueinc16;
uint8_t hue8 = hue16 >> 8; uint8_t hue8 = hue16 >> 8;
@ -1582,9 +1583,9 @@ uint16_t WS2812FX::mode_juggle(void){
uint16_t WS2812FX::mode_palette(void) uint16_t WS2812FX::mode_palette(void)
{ {
bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0)); bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0));
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
{ {
uint8_t colorIndex = map(i,SEGMENT.start,SEGMENT.stop,0,255) - (SEGMENT_RUNTIME.counter_mode_step >> 6 & 0xFF); uint8_t colorIndex = map(i,SEGMENT.start,SEGMENT.stop -1,0,255) - (SEGMENT_RUNTIME.counter_mode_step >> 6 & 0xFF);
if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end" if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end"
@ -1633,23 +1634,23 @@ uint16_t WS2812FX::mode_palette(void)
uint16_t WS2812FX::mode_fire_2012(void) uint16_t WS2812FX::mode_fire_2012(void)
{ {
// Step 1. Cool down every cell a little // Step 1. Cool down every cell a little
for( int i = SEGMENT.start; i <= SEGMENT.stop; i++) { for( int i = SEGMENT.start; i < SEGMENT.stop; i++) {
_locked[i] = qsub8(_locked[i], random8(0, ((COOLING * 10) / SEGMENT_LENGTH) + 2)); _locked[i] = qsub8(_locked[i], random8(0, ((COOLING * 10) / SEGMENT_LENGTH) + 2));
} }
// Step 2. Heat from each cell drifts 'up' and diffuses a little // Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= SEGMENT.stop; k >= SEGMENT.start + 2; k--) { for( int k= SEGMENT.stop -1; k >= SEGMENT.start + 2; k--) {
_locked[k] = (_locked[k - 1] + _locked[k - 2] + _locked[k - 2] ) / 3; _locked[k] = (_locked[k - 1] + _locked[k - 2] + _locked[k - 2] ) / 3;
} }
// Step 3. Randomly ignite new 'sparks' of heat near the bottom // Step 3. Randomly ignite new 'sparks' of heat near the bottom
if( random8() <= SEGMENT.intensity ) { if( random8() <= SEGMENT.intensity ) {
int y = SEGMENT.start + random8(7); int y = SEGMENT.start + random8(7);
if (y <= SEGMENT.stop) _locked[y] = qadd8(_locked[y], random8(160,255) ); if (y < SEGMENT.stop) _locked[y] = qadd8(_locked[y], random8(160,255) );
} }
// Step 4. Map from heat cells to LED colors // Step 4. Map from heat cells to LED colors
for( int j = SEGMENT.start; j <= SEGMENT.stop; j++) { for( int j = SEGMENT.start; j < SEGMENT.stop; j++) {
CRGB color = ColorFromPalette( currentPalette, min(_locked[j],240), 255, LINEARBLEND); CRGB color = ColorFromPalette( currentPalette, min(_locked[j],240), 255, LINEARBLEND);
setPixelColor(j, color.red, color.green, color.blue); setPixelColor(j, color.red, color.green, color.blue);
} }
@ -1678,7 +1679,7 @@ uint16_t WS2812FX::mode_colorwaves(void)
uint16_t brightnesstheta16 = sPseudotime; uint16_t brightnesstheta16 = sPseudotime;
CRGB fastled_col; CRGB fastled_col;
for ( uint16_t i = SEGMENT.start ; i <= SEGMENT.stop; i++) { for ( uint16_t i = SEGMENT.start ; i < SEGMENT.stop; i++) {
hue16 += hueinc16; hue16 += hueinc16;
uint8_t hue8 = hue16 >> 8; uint8_t hue8 = hue16 >> 8;
uint16_t h16_128 = hue16 >> 7; uint16_t h16_128 = hue16 >> 7;
@ -1712,7 +1713,7 @@ uint16_t WS2812FX::mode_bpm(void)
{ {
CRGB fastled_col; CRGB fastled_col;
uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); uint8_t beat = beatsin8(SEGMENT.speed, 64, 255);
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
fastled_col = ColorFromPalette(currentPalette, SEGMENT_RUNTIME.counter_mode_step + (i * 2), beat - SEGMENT_RUNTIME.counter_mode_step + (i * 10)); fastled_col = ColorFromPalette(currentPalette, SEGMENT_RUNTIME.counter_mode_step + (i * 2), beat - SEGMENT_RUNTIME.counter_mode_step + (i * 10));
setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
} }
@ -1726,7 +1727,7 @@ uint16_t WS2812FX::mode_fillnoise8(void)
{ {
if (SEGMENT_RUNTIME.counter_mode_call == 0) SEGMENT_RUNTIME.counter_mode_step = random16(12345); if (SEGMENT_RUNTIME.counter_mode_call == 0) SEGMENT_RUNTIME.counter_mode_step = random16(12345);
CRGB fastled_col; CRGB fastled_col;
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
uint8_t index = inoise8(i * SEGMENT_LENGTH, SEGMENT_RUNTIME.counter_mode_step + i * SEGMENT_LENGTH) % 255; uint8_t index = inoise8(i * SEGMENT_LENGTH, SEGMENT_RUNTIME.counter_mode_step + i * SEGMENT_LENGTH) % 255;
fastled_col = ColorFromPalette(currentPalette, index, 255, LINEARBLEND); fastled_col = ColorFromPalette(currentPalette, index, 255, LINEARBLEND);
setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@ -1742,7 +1743,7 @@ uint16_t WS2812FX::mode_noise16_1(void)
CRGB fastled_col; CRGB fastled_col;
SEGMENT_RUNTIME.counter_mode_step += (1 + SEGMENT.speed/16); SEGMENT_RUNTIME.counter_mode_step += (1 + SEGMENT.speed/16);
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
uint16_t shift_x = beatsin8(11); // the x position of the noise field swings @ 17 bpm uint16_t shift_x = beatsin8(11); // the x position of the noise field swings @ 17 bpm
uint16_t shift_y = SEGMENT_RUNTIME.counter_mode_step/42; // the y position becomes slowly incremented uint16_t shift_y = SEGMENT_RUNTIME.counter_mode_step/42; // the y position becomes slowly incremented
@ -1770,7 +1771,7 @@ uint16_t WS2812FX::mode_noise16_2(void)
CRGB fastled_col; CRGB fastled_col;
SEGMENT_RUNTIME.counter_mode_step += (1 + SEGMENT.speed); SEGMENT_RUNTIME.counter_mode_step += (1 + SEGMENT.speed);
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
uint16_t shift_x = SEGMENT_RUNTIME.counter_mode_step >> 6; // x as a function of time uint16_t shift_x = SEGMENT_RUNTIME.counter_mode_step >> 6; // x as a function of time
uint16_t shift_y = SEGMENT_RUNTIME.counter_mode_step/42; uint16_t shift_y = SEGMENT_RUNTIME.counter_mode_step/42;
@ -1795,7 +1796,7 @@ uint16_t WS2812FX::mode_noise16_3(void)
CRGB fastled_col; CRGB fastled_col;
SEGMENT_RUNTIME.counter_mode_step += (1 + SEGMENT.speed); SEGMENT_RUNTIME.counter_mode_step += (1 + SEGMENT.speed);
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
uint16_t shift_x = 4223; // no movement along x and y uint16_t shift_x = 4223; // no movement along x and y
uint16_t shift_y = 1234; uint16_t shift_y = 1234;
@ -1821,7 +1822,7 @@ uint16_t WS2812FX::mode_noise16_4(void)
{ {
CRGB fastled_col; CRGB fastled_col;
SEGMENT_RUNTIME.counter_mode_step += SEGMENT.speed; SEGMENT_RUNTIME.counter_mode_step += SEGMENT.speed;
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
int16_t index = inoise16(uint32_t(i - SEGMENT.start) << 12, SEGMENT_RUNTIME.counter_mode_step/8); int16_t index = inoise16(uint32_t(i - SEGMENT.start) << 12, SEGMENT_RUNTIME.counter_mode_step/8);
fastled_col = ColorFromPalette(currentPalette, index); fastled_col = ColorFromPalette(currentPalette, index);
setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@ -1835,7 +1836,7 @@ uint16_t WS2812FX::mode_colortwinkle()
{ {
CRGB fastled_col, prev; CRGB fastled_col, prev;
fract8 fadeUpAmount = 8 + (SEGMENT.speed/4), fadeDownAmount = 5 + (SEGMENT.speed/7); fract8 fadeUpAmount = 8 + (SEGMENT.speed/4), fadeDownAmount = 5 + (SEGMENT.speed/7);
for( uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for( uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
fastled_col = fastled_from_col(getPixelColor(i)); fastled_col = fastled_from_col(getPixelColor(i));
prev = fastled_col; prev = fastled_col;
if(_locked[i]) { if(_locked[i]) {
@ -1886,7 +1887,7 @@ uint16_t WS2812FX::mode_lake() {
uint8_t wave3 = beatsin8(sp +2, 0,80); uint8_t wave3 = beatsin8(sp +2, 0,80);
CRGB fastled_col; CRGB fastled_col;
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
{ {
int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2;
uint8_t lum = (index > wave3) ? index - wave3 : 0; uint8_t lum = (index > wave3) ? index - wave3 : 0;
@ -1905,7 +1906,7 @@ uint16_t WS2812FX::mode_meteor() {
uint16_t in = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step; uint16_t in = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step;
// fade all leds to colors[1] in LEDs one step // fade all leds to colors[1] in LEDs one step
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
if (random8() <= 255 - SEGMENT.intensity) if (random8() <= 255 - SEGMENT.intensity)
{ {
byte meteorTrailDecay = 128 + random8(127); byte meteorTrailDecay = 128 + random8(127);
@ -1917,8 +1918,8 @@ uint16_t WS2812FX::mode_meteor() {
// draw meteor // draw meteor
for(int j = 0; j < meteorSize; j++) { for(int j = 0; j < meteorSize; j++) {
uint16_t index = in + j; uint16_t index = in + j;
if(in + j > SEGMENT.stop) { if(in + j >= SEGMENT.stop) {
index = SEGMENT.start + (in + j - SEGMENT.stop) -1; index = SEGMENT.start + (in + j - SEGMENT.stop) -2;
} }
_locked[index] = 240; _locked[index] = 240;
@ -1935,10 +1936,10 @@ uint16_t WS2812FX::mode_meteor() {
// adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain
uint16_t WS2812FX::mode_meteor_smooth() { uint16_t WS2812FX::mode_meteor_smooth() {
byte meteorSize= 1+ SEGMENT_LENGTH / 10; byte meteorSize= 1+ SEGMENT_LENGTH / 10;
uint16_t in = map((SEGMENT_RUNTIME.counter_mode_step >> 6 & 0xFF), 0, 255, SEGMENT.start, SEGMENT.stop); uint16_t in = map((SEGMENT_RUNTIME.counter_mode_step >> 6 & 0xFF), 0, 255, SEGMENT.start, SEGMENT.stop -1);
// fade all leds to colors[1] in LEDs one step // fade all leds to colors[1] in LEDs one step
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) { for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
if (_locked[i] != 0 && random8() <= 255 - SEGMENT.intensity) if (_locked[i] != 0 && random8() <= 255 - SEGMENT.intensity)
{ {
int change = 3 - random8(12); //change each time between -8 and +3 int change = 3 - random8(12); //change each time between -8 and +3
@ -1952,8 +1953,8 @@ uint16_t WS2812FX::mode_meteor_smooth() {
// draw meteor // draw meteor
for(int j = 0; j < meteorSize; j++) { for(int j = 0; j < meteorSize; j++) {
uint16_t index = in + j; uint16_t index = in + j;
if(in + j > SEGMENT.stop) { if(in + j >= SEGMENT.stop) {
index = SEGMENT.start + (in + j - SEGMENT.stop) -1; index = SEGMENT.start + (in + j - SEGMENT.stop) -2;
} }
setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48)); setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48));
_locked[index] = 240; _locked[index] = 240;
@ -1982,10 +1983,10 @@ uint16_t WS2812FX::mode_railway()
if (p0 < 255) pos = p0; if (p0 < 255) pos = p0;
} }
if (SEGMENT_RUNTIME.aux_param) pos = 255 - pos; if (SEGMENT_RUNTIME.aux_param) pos = 255 - pos;
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i += 2) for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i += 2)
{ {
setPixelColor(i, color_from_palette(255 - pos, false, false, 255)); setPixelColor(i, color_from_palette(255 - pos, false, false, 255));
if (i != SEGMENT.stop) if (i < SEGMENT.stop -1)
{ {
setPixelColor(i + 1, color_from_palette(pos, false, false, 255)); setPixelColor(i + 1, color_from_palette(pos, false, false, 255));
} }
@ -2029,7 +2030,7 @@ uint16_t WS2812FX::mode_ripple()
setPixelColor(v, color_blend(getPixelColor(v), col, mag)); setPixelColor(v, color_blend(getPixelColor(v), col, mag));
} }
int16_t w = left + propI*2 + 3 -(v-left); int16_t w = left + propI*2 + 3 -(v-left);
if (w <= SEGMENT.stop && w >= SEGMENT.start) if (w < SEGMENT.stop && w >= SEGMENT.start)
{ {
setPixelColor(w, color_blend(getPixelColor(w), col, mag)); setPixelColor(w, color_blend(getPixelColor(w), col, mag));
} }

View File

@ -35,18 +35,18 @@
#define DEFAULT_BRIGHTNESS (uint8_t)127 #define DEFAULT_BRIGHTNESS (uint8_t)127
#define DEFAULT_MODE (uint8_t)0 #define DEFAULT_MODE (uint8_t)0
#define DEFAULT_SPEED (uint8_t)128 #define DEFAULT_SPEED (uint8_t)128
#define DEFAULT_COLOR (uint32_t)0xFF0000 #define DEFAULT_COLOR (uint32_t)0xFFAA00
#define min(a,b) ((a)<(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b))
/* each segment uses 38 bytes of SRAM memory, so if you're application fails because of /* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#define MAX_NUM_SEGMENTS 10 #define MAX_NUM_SEGMENTS 10
#define NUM_COLORS 3 /* number of colors per segment */ #define NUM_COLORS 3 /* number of colors per segment */
#define SEGMENT _segments[_segment_index] #define SEGMENT _segments[_segment_index]
#define SEGMENT_RUNTIME _segment_runtimes[_segment_index] #define SEGMENT_RUNTIME _segment_runtimes[_segment_index]
#define SEGMENT_LENGTH (SEGMENT.stop - SEGMENT.start + 1) #define SEGMENT_LENGTH (SEGMENT.stop - SEGMENT.start)
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGMENT_LENGTH #define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGMENT_LENGTH
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes)) #define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
@ -65,13 +65,17 @@
#define ULTRAWHITE (uint32_t)0xFFFFFFFF #define ULTRAWHITE (uint32_t)0xFFFFFFFF
// options // options
// bit 8: reverse animation // bit 7: segment is in transition mode
// bits 5-7: fade rate (0-7) // bits 2-6: TBD
// bit 4: gamma correction // bit 1: reverse segment
// bits 1-3: TBD // bit 0: segment is selected
#define NO_OPTIONS (uint8_t)0x00 #define NO_OPTIONS (uint8_t)0x00
#define REVERSE (uint8_t)0x80 #define TRANSITIONAL (uint8_t)0x80
#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE) #define REVERSE (uint8_t)0x02
#define SELECTED (uint8_t)0x01
#define IS_TRANSITIONAL ((SEGMENT.options & TRANSITIONAL) == TRANSITIONAL)
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
#define MODE_COUNT 80 #define MODE_COUNT 80
@ -165,26 +169,22 @@ class WS2812FX {
public: public:
typedef struct Segment { // 21 bytes typedef struct Segment { // 21 bytes
uint16_t start; uint16_t start;
uint16_t stop; uint16_t stop; //segment invalid if stop == 0
uint8_t speed; uint8_t speed;
uint8_t intensity; uint8_t intensity;
uint8_t palette; uint8_t palette;
uint8_t mode; uint8_t mode;
uint8_t options; uint8_t options; //bit pattern: msb first: cloning3 cloning2 cloning1 cloning0 tbd tbd reverse selected
//uint8_t clone;
//bool reverse;
//uint8_t grouping;
uint32_t colors[NUM_COLORS]; uint32_t colors[NUM_COLORS];
} segment; } segment;
// segment runtime parameters // segment runtime parameters
typedef struct Segment_runtime { // 17 bytes typedef struct Segment_runtime { // 16 bytes
unsigned long next_time; unsigned long next_time;
uint32_t counter_mode_step; uint32_t counter_mode_step;
uint32_t counter_mode_call; uint32_t counter_mode_call;
uint16_t aux_param; uint16_t aux_param;
uint16_t aux_param2; uint16_t aux_param2;
uint8_t trans_act;
} segment_runtime; } segment_runtime;
WS2812FX() { WS2812FX() {
@ -488,6 +488,7 @@ class WS2812FX {
uint32_t _lastPaletteChange = 0; uint32_t _lastPaletteChange = 0;
uint32_t _lastShow = 0;
uint8_t _segment_index = 0; uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99; uint8_t _segment_index_palette_last = 99;
@ -496,7 +497,7 @@ class WS2812FX {
// start, stop, speed, intensity, palette, mode, options, color[] // start, stop, speed, intensity, palette, mode, options, color[]
{ 0, 7, DEFAULT_SPEED, 128, 0, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}} { 0, 7, DEFAULT_SPEED, 128, 0, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
}; };
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 17 bytes per element segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
}; };

View File

@ -27,7 +27,8 @@
#include "WS2812FX.h" #include "WS2812FX.h"
#include "palettes.h" #include "palettes.h"
#define LED_SKIP_AMOUNT 1 #define LED_SKIP_AMOUNT 1
#define MIN_SHOW_DELAY 15
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
{ {
@ -47,7 +48,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
_locked = new byte[_length]; _locked = new byte[_length];
_segments[0].start = 0; _segments[0].start = 0;
_segments[0].stop = _length -1; _segments[0].stop = _length;
unlockAll(); unlockAll();
setBrightness(_brightness); setBrightness(_brightness);
@ -55,6 +56,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
void WS2812FX::service() { void WS2812FX::service() {
unsigned long now = millis(); // Be aware, millis() rolls over every 49 days unsigned long now = millis(); // Be aware, millis() rolls over every 49 days
if (now - _lastShow < MIN_SHOW_DELAY) return;
bool doShow = false; bool doShow = false;
for(uint8_t i=0; i < _num_segments; i++) for(uint8_t i=0; i < _num_segments; i++)
{ {
@ -64,12 +66,14 @@ void WS2812FX::service() {
doShow = true; doShow = true;
handle_palette(); handle_palette();
uint16_t delay = (this->*_mode[SEGMENT.mode])(); uint16_t delay = (this->*_mode[SEGMENT.mode])();
SEGMENT_RUNTIME.next_time = now + max(delay, 5); SEGMENT_RUNTIME.next_time = now + max(delay, MIN_SHOW_DELAY);
SEGMENT_RUNTIME.counter_mode_call++; SEGMENT_RUNTIME.counter_mode_call++;
} }
} }
if(doShow) { if(doShow) {
yield();
show(); show();
_lastShow = millis();
} }
_triggered = false; _triggered = false;
} }
@ -93,8 +97,8 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
{ {
if (_locked[i] && !_modeUsesLock) return; if (_locked[i] && !_modeUsesLock) return;
if (_reverseMode) i = _length - 1 -i; if (_reverseMode) i = _length -1 -i;
if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment
byte tmpg = g; byte tmpg = g;
switch (colorOrder) //0 = Grb, default switch (colorOrder) //0 = Grb, default
{ {
@ -157,7 +161,7 @@ void WS2812FX::setReverseMode(bool b)
void WS2812FX::driverModeCronixie(bool b) void WS2812FX::driverModeCronixie(bool b)
{ {
_cronixieMode = b; _cronixieMode = b;
_segments[0].stop = (b) ? 5 : _length-1; _segments[0].stop = (b) ? 6 : _length;
} }
void WS2812FX::setCronixieBacklight(bool b) void WS2812FX::setCronixieBacklight(bool b)
@ -240,6 +244,7 @@ void WS2812FX::show(void) {
currentMilliamps += _length; //add standby power back to estimate currentMilliamps += _length; //add standby power back to estimate
} else { } else {
currentMilliamps = 0; currentMilliamps = 0;
bus->SetBrightness(_brightness);
} }
bus->Show(); bus->Show();
@ -375,7 +380,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
} }
WS2812FX::Segment WS2812FX::getSegment(void) { WS2812FX::Segment WS2812FX::getSegment(void) {
return SEGMENT; return _segments[0];
} }
WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) { WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) {
@ -478,8 +483,13 @@ void WS2812FX::unlockAll()
void WS2812FX::setTransitionMode(bool t) void WS2812FX::setTransitionMode(bool t)
{ {
SEGMENT_RUNTIME.trans_act = (t) ? 1:2; if (t) {
if (!t) return; SEGMENT.options |= 0x01 << 7;
} else
{
SEGMENT.options &= ~(0x01 << 7);
return;
}
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
if (SEGMENT.mode == FX_MODE_STATIC && SEGMENT_RUNTIME.next_time > waitMax) SEGMENT_RUNTIME.next_time = waitMax; if (SEGMENT.mode == FX_MODE_STATIC && SEGMENT_RUNTIME.next_time > waitMax) SEGMENT_RUNTIME.next_time = waitMax;
} }
@ -513,7 +523,7 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend)
* Fills segment with color * Fills segment with color
*/ */
void WS2812FX::fill(uint32_t c) { void WS2812FX::fill(uint32_t c) {
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, c); setPixelColor(i, c);
} }
} }
@ -531,7 +541,7 @@ void WS2812FX::fade_out(uint8_t rate) {
int g2 = (color >> 8) & 0xff; int g2 = (color >> 8) & 0xff;
int b2 = color & 0xff; int b2 = color & 0xff;
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
color = getPixelColor(i); color = getPixelColor(i);
int w1 = (color >> 24) & 0xff; int w1 = (color >> 24) & 0xff;
int r1 = (color >> 16) & 0xff; int r1 = (color >> 16) & 0xff;
@ -561,7 +571,7 @@ void WS2812FX::blur(uint8_t blur_amount)
uint8_t keep = 255 - blur_amount; uint8_t keep = 255 - blur_amount;
uint8_t seep = blur_amount >> 1; uint8_t seep = blur_amount >> 1;
CRGB carryover = CRGB::Black; CRGB carryover = CRGB::Black;
for(uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) for(uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
{ {
CRGB cur = fastled_from_col(getPixelColor(i)); CRGB cur = fastled_from_col(getPixelColor(i));
CRGB part = cur; CRGB part = cur;
@ -718,7 +728,7 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8
{ {
if (SEGMENT.palette == 0 && mcol < 3) return SEGMENT.colors[mcol]; //WS2812FX default if (SEGMENT.palette == 0 && mcol < 3) return SEGMENT.colors[mcol]; //WS2812FX default
uint8_t paletteIndex = i; uint8_t paletteIndex = i;
if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop,0,255); if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop-1,0,255);
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGB fastled_col; CRGB fastled_col;
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND); fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);

View File

@ -89,7 +89,7 @@
//version code in format yymmddb (b = daily build) //version code in format yymmddb (b = daily build)
#define VERSION 1903032 #define VERSION 1903051
char versionString[] = "0.8.4-dev"; char versionString[] = "0.8.4-dev";
@ -464,8 +464,6 @@ const byte gamma8[] = {
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 }; 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
String txd = "Please disable OTA Lock in security settings!";
//function prototypes //function prototypes
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte); void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);

View File

@ -215,76 +215,6 @@ void initCon()
} }
//fill string buffer with build info
void serveJsonInfo(AsyncWebServerRequest* request)
{
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject& doc = response->getRoot();
doc["ver"] = versionString;
doc["vid"] = VERSION;
JsonObject& leds = doc.createNestedObject("leds");
leds["count"] = ledCount;
leds["rgbw"] = useRGBW;
JsonArray& leds_pin = leds.createNestedArray("pin");
leds_pin.add(LEDPIN);
leds["pwr"] = strip.currentMilliamps;
leds["maxpwr"] = strip.ablMilliampsMax;
leds["maxseg"] = 1;
doc["name"] = serverDescription;
doc["udpport"] = udpPort;
doc["modecount"] = strip.getModeCount();
doc["palettecount"] = strip.getPaletteCount();
#ifdef ARDUINO_ARCH_ESP32
doc["arch"] = "esp32";
doc["core"] = ESP.getSdkVersion();
doc["maxalloc"] = ESP.getMaxAllocHeap();
#else
doc["arch"] = "esp8266";
doc["core"] = ESP.getCoreVersion();
doc["maxalloc"] = ESP.getMaxFreeBlockSize();
#endif
doc["freeheap"] = ESP.getFreeHeap();
doc["uptime"] = millis()/1000;
JsonArray& opt = doc.createNestedArray("opt");
#ifndef WLED_DISABLE_ALEXA
opt.add("alexa");
#endif
#ifndef WLED_DISABLE_BLYNK
opt.add("blynk");
#endif
#ifndef WLED_DISABLE_CRONIXIE
opt.add("cronixie");
#endif
#ifdef WLED_DEBUG
opt.add("debug");
#endif
#ifdef USEFS
opt.add("fs");
#endif
#ifndef WLED_DISABLE_HUESYNC
opt.add("huesync");
#endif
#ifndef WLED_DISABLE_MOBILE_UI
opt.add("mobile-ui");
#endif
#ifndef WLED_DISABLE_OTA
opt.add("ota");
#endif
doc["brand"] = "wled";
doc["product"] = "DIY light";
doc["btype"] = "dev";
doc["mac"] = escapedMac;
response->setLength();
request->send(response);
}
bool checkClientIsMobile(String useragent) bool checkClientIsMobile(String useragent)
{ {
//to save complexity this function is not comprehensive //to save complexity this function is not comprehensive

View File

@ -115,9 +115,9 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len)
if (hueAuthRequired) if (hueAuthRequired)
{ {
const char* apikey = root[0]["success"]["username"]; const char* apikey = root[0]["success"]["username"];
if (apikey != nullptr) if (apikey != nullptr && strlen(apikey) < sizeof(hueApiKey))
{ {
strlcpy(hueApiKey, apikey, sizeof(hueApiKey)); strcpy(hueApiKey, apikey);
hueAuthRequired = false; hueAuthRequired = false;
hueNewKey = true; hueNewKey = true;
} }

View File

@ -64,6 +64,10 @@ void initServer()
doReboot = true; doReboot = true;
}); });
server.on("/json/state", HTTP_GET, [](AsyncWebServerRequest *request){
serveJsonState(request);
});
server.on("/json/effects", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/json/effects", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "application/json", JSON_mode_names); request->send_P(200, "application/json", JSON_mode_names);
}); });
@ -172,13 +176,13 @@ void initServer()
} else } else
{ {
server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 500, "Access Denied", txd, 254); serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254);
}); });
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 500, "Access Denied", txd, 254); serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254);
}); });
server.on("/list", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/list", HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 500, "Access Denied", txd, 254); serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254);
}); });
} }
@ -239,7 +243,7 @@ void serveIndex(AsyncWebServerRequest* request)
else if (uiConfiguration == 2) serveMobile = true; else if (uiConfiguration == 2) serveMobile = true;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html",
(serveMobile) ? PAGE_indexM : PAGE_index, (serveMobile) ? (uint8_t*)PAGE_indexM : PAGE_index,
(serveMobile) ? PAGE_indexM_L : PAGE_index_L); (serveMobile) ? PAGE_indexM_L : PAGE_index_L);
//error message is not gzipped //error message is not gzipped
@ -321,7 +325,7 @@ void serveSettings(AsyncWebServerRequest* request)
if (subPage == 1 && wifiLock && otaLock) if (subPage == 1 && wifiLock && otaLock)
{ {
serveMessage(request, 500, "Access Denied", txd, 254); return; serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254); return;
} }
#ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage #ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage

130
wled00/wled19_json.ino Normal file
View File

@ -0,0 +1,130 @@
/*
* JSON API (De)serialization
*/
void serveJsonState(AsyncWebServerRequest* request)
{
AsyncJsonResponse * response = new AsyncJsonResponse();
JsonObject& doc = response->getRoot();
doc["on"] = (bri > 0);
doc["bri"] = briLast;
doc["transition"] = transitionDelay/100; //in 100ms
JsonObject& nl = doc.createNestedObject("nl");
nl["on"] = nightlightActive;
nl["dur"] = nightlightDelayMins;
nl["fade"] = nightlightFade;
nl["tbri"] = nightlightTargetBri;
JsonObject& udpn = doc.createNestedObject("udpn");
udpn["send"] = notifyDirect;
udpn["recv"] = receiveNotifications;
JsonArray& seg = doc.createNestedArray("seg");
JsonObject& seg0 = seg.createNestedObject();
serializeSegment(seg0);
response->setLength();
request->send(response);
}
JsonObject& serializeSegment(JsonObject& root)
{
WS2812FX::Segment seg = strip.getSegment();
//root["i"] = i;
root["start"] = seg.start;
root["stop"] = seg.stop;
root["len"] = seg.stop - seg.start;
JsonArray& colarr = root.createNestedArray("col");
for (uint8_t i = 0; i < 3; i++)
{
JsonArray& colX = colarr.createNestedArray();
colX.add((seg.colors[i] >> 16) & 0xFF);
colX.add((seg.colors[i] >> 8) & 0xFF);
colX.add((seg.colors[i] ) & 0xFF);
if (useRGBW)
colX.add((seg.colors[i] >> 24) & 0xFF);
}
root["fx"] = seg.mode;
root["sx"] = seg.speed;
root["ix"] = seg.intensity;
root["pal"] = seg.palette;
root["sel"] = ((seg.options & 0x01) == 0x01);
root["rev"] = ((seg.options & 0x02) == 0x02);
root["cln"] = -1;
}
//fill string buffer with build info
void serveJsonInfo(AsyncWebServerRequest* request)
{
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject& doc = response->getRoot();
doc["ver"] = versionString;
doc["vid"] = VERSION;
JsonObject& leds = doc.createNestedObject("leds");
leds["count"] = ledCount;
leds["rgbw"] = useRGBW;
JsonArray& leds_pin = leds.createNestedArray("pin");
leds_pin.add(LEDPIN);
leds["pwr"] = strip.currentMilliamps;
leds["maxpwr"] = strip.ablMilliampsMax;
leds["maxseg"] = 1;
doc["name"] = serverDescription;
doc["udpport"] = udpPort;
doc["live"] = realtimeActive;
doc["fxcount"] = strip.getModeCount();
doc["palcount"] = strip.getPaletteCount();
#ifdef ARDUINO_ARCH_ESP32
doc["arch"] = "esp32";
doc["core"] = ESP.getSdkVersion();
//doc["maxalloc"] = ESP.getMaxAllocHeap();
#else
doc["arch"] = "esp8266";
doc["core"] = ESP.getCoreVersion();
//doc["maxalloc"] = ESP.getMaxFreeBlockSize();
#endif
doc["freeheap"] = ESP.getFreeHeap();
doc["uptime"] = millis()/1000;
JsonArray& opt = doc.createNestedArray("opt");
#ifndef WLED_DISABLE_ALEXA
opt.add("alexa");
#endif
#ifndef WLED_DISABLE_BLYNK
opt.add("blynk");
#endif
#ifndef WLED_DISABLE_CRONIXIE
opt.add("cronixie");
#endif
#ifdef WLED_DEBUG
opt.add("debug");
#endif
#ifdef USEFS
opt.add("fs");
#endif
#ifndef WLED_DISABLE_HUESYNC
opt.add("huesync");
#endif
#ifndef WLED_DISABLE_MOBILE_UI
opt.add("mobile-ui");
#endif
#ifndef WLED_DISABLE_OTA
opt.add("ota");
#endif
doc["brand"] = "wled";
doc["product"] = "DIY light";
doc["btype"] = "dev";
doc["mac"] = escapedMac;
response->setLength();
request->send(response);
}