diff --git a/platformio.ini b/platformio.ini index 7dbb2b8f..9389cbd9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,7 +26,7 @@ lib_deps_external = #Blynk@0.5.4(changed) #E131@1.0.0(changed) FastLED@3.2.6 - NeoPixelBus@2.3.5 + NeoPixelBus@2.4.3 ESPAsyncTCP@1.2.0 AsyncTCP@1.0.3 EspAsyncWebServer@1.2.0 diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index db9e13c0..4476377e 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -14,11 +14,11 @@ #else //esp8266 //autoselect the right method depending on strip pin #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 #define PIXELMETHOD NeoEsp8266Dma800KbpsMethod #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." #endif #endif diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp index 534506bc..f3ea3e46 100644 --- a/wled00/WS2812FX.cpp +++ b/wled00/WS2812FX.cpp @@ -35,7 +35,7 @@ */ uint16_t WS2812FX::mode_static(void) { 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; 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)); } } else { @@ -108,7 +108,7 @@ uint16_t WS2812FX::color_wipe(uint32_t color1, uint32_t color2, bool rev, bool d } else { uint32_t led_offset = SEGMENT_RUNTIME.counter_mode_step - SEGMENT_LENGTH; if(rev) { - setPixelColor(SEGMENT.stop - led_offset, color2); + setPixelColor(SEGMENT.stop -1 - led_offset, color2); } else { 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 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); } 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) { 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())); } } @@ -214,12 +214,12 @@ uint16_t WS2812FX::mode_breath(void) { uint8_t r = ((color >> 16 & 0xFF) * lum) >> 8; uint8_t g = ((color >> 8 & 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); } } 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)); } } @@ -237,7 +237,7 @@ uint16_t WS2812FX::mode_fade(void) { int lum = SEGMENT_RUNTIME.counter_mode_step; 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)); } @@ -474,7 +474,7 @@ uint16_t WS2812FX::mode_dissolve_random(void) { * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ 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)); } 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) { 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)); } } @@ -511,7 +511,7 @@ uint16_t WS2812FX::mode_flash_sparkle(void) { * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ 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)); } @@ -529,7 +529,7 @@ uint16_t WS2812FX::mode_hyper_sparkle(void) { * Strobe effect with different strobe count and pause, controlled by speed. */ 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)); } @@ -537,7 +537,7 @@ uint16_t WS2812FX::mode_multi_strobe(void) { uint16_t count = 2 * ((SEGMENT.speed / 10) + 1); if(SEGMENT_RUNTIME.counter_mode_step < count) { 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]); } delay = 20; @@ -559,7 +559,7 @@ uint16_t WS2812FX::mode_android(void) { 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)); } @@ -583,19 +583,19 @@ uint16_t WS2812FX::mode_android(void) { 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++) { setPixelColor(i, SEGMENT.colors[0]); } } else { - for(int i = a; i <= SEGMENT.stop; i++) { + for(int i = a; i < SEGMENT.stop; i++) { 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]); } } @@ -671,7 +671,7 @@ uint16_t WS2812FX::mode_colorful(void) { for (uint8_t i = 4; i < 7; i++) cols[i] = cols[i-4]; } 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+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]); } i+=4; - if(i <= SEGMENT.stop) + if(i < SEGMENT.stop) { 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]); - if(i+2 <= SEGMENT.stop) + if(i+2 < SEGMENT.stop) { setPixelColor(i+2, cols[SEGMENT_RUNTIME.counter_mode_step+2]); } @@ -704,10 +704,10 @@ uint16_t WS2812FX::mode_colorful(void) { * Emulates a traffic light. */ 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)); 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) { @@ -743,7 +743,7 @@ uint16_t WS2812FX::mode_chase_flash(void) { const static uint8_t flash_count = 4; 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)); } @@ -808,13 +808,13 @@ uint16_t WS2812FX::running(uint32_t color1, uint32_t color2) { if((i + SEGMENT_RUNTIME.counter_mode_step) % 4 < 2) { 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 { - setPixelColor(SEGMENT.stop - i, color1); + setPixelColor(SEGMENT.stop -i -1, color1); } } 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_param2 = UINT16_MAX; } - 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 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); uint32_t sv1 = 0, sv2 = 0; if (valid1) sv1 = getPixelColor(SEGMENT_RUNTIME.aux_param); 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) { SEGMENT_RUNTIME.counter_mode_step = 0; //shift all leds right - uint32_t ctemp = getPixelColor(SEGMENT.stop); - for(uint16_t i=SEGMENT.stop; i>SEGMENT.start; i--) { + uint32_t ctemp = getPixelColor(SEGMENT.stop -1); + for(uint16_t i=SEGMENT.stop -1; i>SEGMENT.start; i--) { setPixelColor(i, getPixelColor(i-1)); } setPixelColor(SEGMENT.start, ctemp); @@ -955,8 +955,8 @@ uint16_t WS2812FX::mode_rain() SEGMENT_RUNTIME.aux_param2++; 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_param == SEGMENT.stop +1) SEGMENT_RUNTIME.aux_param = SEGMENT.start; - if (SEGMENT_RUNTIME.aux_param2 == SEGMENT.stop +1) SEGMENT_RUNTIME.aux_param2 = SEGMENT.start; + if (SEGMENT_RUNTIME.aux_param == SEGMENT.stop) SEGMENT_RUNTIME.aux_param = SEGMENT.start; + if (SEGMENT_RUNTIME.aux_param2 == SEGMENT.stop) SEGMENT_RUNTIME.aux_param2 = SEGMENT.start; } return mode_fireworks(); } @@ -972,7 +972,7 @@ uint16_t WS2812FX::mode_fire_flicker(void) { byte b = (SEGMENT.colors[0] & 0xFF); byte lum = (SEGMENT.palette == 0) ? max(w, max(r, max(g, b))) : 255; 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); if (SEGMENT.palette == 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 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) { @@ -1011,7 +1011,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { } 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); 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); else if(index > 1) color = color2; - setPixelColor(SEGMENT.stop - i, color); + setPixelColor(SEGMENT.stop - i -1, color); } SEGMENT_RUNTIME.counter_mode_step++; @@ -1335,7 +1335,7 @@ uint16_t WS2812FX::mode_tricolor_fade(void) byte stp = SEGMENT_RUNTIME.counter_mode_step % 256; 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) { color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); } 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; 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) { 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)); } - 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; return SPEED_FORMULA_L; @@ -1423,10 +1423,11 @@ uint16_t WS2812FX::mode_dual_larson_scanner(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)); } - 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 g = random8(6) != 0 ? (color >> 8 & 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 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 ledstart = SEGMENT.start + random8(SEGMENT_LENGTH); // Determine starting location of flash + 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); if (SEGMENT_RUNTIME.counter_mode_step == 0) @@ -1540,7 +1541,7 @@ uint16_t WS2812FX::mode_pride_2015(void) uint16_t brightnesstheta16 = sPseudotime; 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; uint8_t hue8 = hue16 >> 8; @@ -1582,9 +1583,9 @@ uint16_t WS2812FX::mode_juggle(void){ uint16_t WS2812FX::mode_palette(void) { 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" @@ -1633,23 +1634,23 @@ uint16_t WS2812FX::mode_palette(void) uint16_t WS2812FX::mode_fire_2012(void) { // 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)); } // 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; } // Step 3. Randomly ignite new 'sparks' of heat near the bottom if( random8() <= SEGMENT.intensity ) { 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 - 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); setPixelColor(j, color.red, color.green, color.blue); } @@ -1678,7 +1679,7 @@ uint16_t WS2812FX::mode_colorwaves(void) uint16_t brightnesstheta16 = sPseudotime; 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; uint8_t hue8 = hue16 >> 8; uint16_t h16_128 = hue16 >> 7; @@ -1712,7 +1713,7 @@ uint16_t WS2812FX::mode_bpm(void) { CRGB fastled_col; 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)); 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); 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; fastled_col = ColorFromPalette(currentPalette, index, 255, LINEARBLEND); 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; 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_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; 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_y = SEGMENT_RUNTIME.counter_mode_step/42; @@ -1795,7 +1796,7 @@ uint16_t WS2812FX::mode_noise16_3(void) CRGB fastled_col; 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_y = 1234; @@ -1821,7 +1822,7 @@ uint16_t WS2812FX::mode_noise16_4(void) { CRGB fastled_col; 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); fastled_col = ColorFromPalette(currentPalette, index); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -1835,7 +1836,7 @@ uint16_t WS2812FX::mode_colortwinkle() { CRGB fastled_col, prev; 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)); prev = fastled_col; if(_locked[i]) { @@ -1886,7 +1887,7 @@ uint16_t WS2812FX::mode_lake() { uint8_t wave3 = beatsin8(sp +2, 0,80); 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; 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; // 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) { byte meteorTrailDecay = 128 + random8(127); @@ -1917,8 +1918,8 @@ uint16_t WS2812FX::mode_meteor() { // draw meteor for(int j = 0; j < meteorSize; j++) { uint16_t index = in + j; - if(in + j > SEGMENT.stop) { - index = SEGMENT.start + (in + j - SEGMENT.stop) -1; + if(in + j >= SEGMENT.stop) { + index = SEGMENT.start + (in + j - SEGMENT.stop) -2; } _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 uint16_t WS2812FX::mode_meteor_smooth() { 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 - 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) { int change = 3 - random8(12); //change each time between -8 and +3 @@ -1952,8 +1953,8 @@ uint16_t WS2812FX::mode_meteor_smooth() { // draw meteor for(int j = 0; j < meteorSize; j++) { uint16_t index = in + j; - if(in + j > SEGMENT.stop) { - index = SEGMENT.start + (in + j - SEGMENT.stop) -1; + if(in + j >= SEGMENT.stop) { + index = SEGMENT.start + (in + j - SEGMENT.stop) -2; } setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48)); _locked[index] = 240; @@ -1982,10 +1983,10 @@ uint16_t WS2812FX::mode_railway() if (p0 < 255) pos = p0; } 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)); - if (i != SEGMENT.stop) + if (i < SEGMENT.stop -1) { 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)); } 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)); } diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h index ad530217..a7e5bcf0 100644 --- a/wled00/WS2812FX.h +++ b/wled00/WS2812FX.h @@ -35,18 +35,18 @@ #define DEFAULT_BRIGHTNESS (uint8_t)127 #define DEFAULT_MODE (uint8_t)0 #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 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 */ #define MAX_NUM_SEGMENTS 10 #define NUM_COLORS 3 /* number of colors per segment */ #define SEGMENT _segments[_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 RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes)) @@ -65,13 +65,17 @@ #define ULTRAWHITE (uint32_t)0xFFFFFFFF // options -// bit 8: reverse animation -// bits 5-7: fade rate (0-7) -// bit 4: gamma correction -// bits 1-3: TBD +// bit 7: segment is in transition mode +// bits 2-6: TBD +// bit 1: reverse segment +// bit 0: segment is selected #define NO_OPTIONS (uint8_t)0x00 -#define REVERSE (uint8_t)0x80 -#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE) +#define TRANSITIONAL (uint8_t)0x80 +#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 @@ -165,26 +169,22 @@ class WS2812FX { public: typedef struct Segment { // 21 bytes uint16_t start; - uint16_t stop; + uint16_t stop; //segment invalid if stop == 0 uint8_t speed; uint8_t intensity; uint8_t palette; uint8_t mode; - uint8_t options; - //uint8_t clone; - //bool reverse; - //uint8_t grouping; + uint8_t options; //bit pattern: msb first: cloning3 cloning2 cloning1 cloning0 tbd tbd reverse selected uint32_t colors[NUM_COLORS]; } segment; // segment runtime parameters - typedef struct Segment_runtime { // 17 bytes + typedef struct Segment_runtime { // 16 bytes unsigned long next_time; uint32_t counter_mode_step; uint32_t counter_mode_call; uint16_t aux_param; uint16_t aux_param2; - uint8_t trans_act; } segment_runtime; WS2812FX() { @@ -488,6 +488,7 @@ class WS2812FX { uint32_t _lastPaletteChange = 0; + uint32_t _lastShow = 0; uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; @@ -496,7 +497,7 @@ class WS2812FX { // start, stop, speed, intensity, palette, mode, options, 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 }; diff --git a/wled00/WS2812FX_fcn.cpp b/wled00/WS2812FX_fcn.cpp index 2148660d..bb6b8835 100644 --- a/wled00/WS2812FX_fcn.cpp +++ b/wled00/WS2812FX_fcn.cpp @@ -27,7 +27,8 @@ #include "WS2812FX.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) { @@ -47,7 +48,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) _locked = new byte[_length]; _segments[0].start = 0; - _segments[0].stop = _length -1; + _segments[0].stop = _length; unlockAll(); setBrightness(_brightness); @@ -55,6 +56,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) void WS2812FX::service() { unsigned long now = millis(); // Be aware, millis() rolls over every 49 days + if (now - _lastShow < MIN_SHOW_DELAY) return; bool doShow = false; for(uint8_t i=0; i < _num_segments; i++) { @@ -64,12 +66,14 @@ void WS2812FX::service() { doShow = true; handle_palette(); 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++; } } if(doShow) { + yield(); show(); + _lastShow = millis(); } _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) { if (_locked[i] && !_modeUsesLock) return; - if (_reverseMode) i = _length - 1 -i; - if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment + if (_reverseMode) i = _length -1 -i; + if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment byte tmpg = g; switch (colorOrder) //0 = Grb, default { @@ -157,7 +161,7 @@ void WS2812FX::setReverseMode(bool b) void WS2812FX::driverModeCronixie(bool b) { _cronixieMode = b; - _segments[0].stop = (b) ? 5 : _length-1; + _segments[0].stop = (b) ? 6 : _length; } void WS2812FX::setCronixieBacklight(bool b) @@ -240,6 +244,7 @@ void WS2812FX::show(void) { currentMilliamps += _length; //add standby power back to estimate } else { currentMilliamps = 0; + bus->SetBrightness(_brightness); } bus->Show(); @@ -375,7 +380,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) } WS2812FX::Segment WS2812FX::getSegment(void) { - return SEGMENT; + return _segments[0]; } WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) { @@ -478,8 +483,13 @@ void WS2812FX::unlockAll() void WS2812FX::setTransitionMode(bool t) { - SEGMENT_RUNTIME.trans_act = (t) ? 1:2; - if (!t) return; + if (t) { + SEGMENT.options |= 0x01 << 7; + } else + { + SEGMENT.options &= ~(0x01 << 7); + return; + } 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; } @@ -513,7 +523,7 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) * Fills segment with color */ 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); } } @@ -531,7 +541,7 @@ void WS2812FX::fade_out(uint8_t rate) { int g2 = (color >> 8) & 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); int w1 = (color >> 24) & 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 seep = blur_amount >> 1; 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 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 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" CRGB fastled_col; fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND); diff --git a/wled00/wled00.ino b/wled00/wled00.ino index abfc3929..5ce1c380 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -89,7 +89,7 @@ //version code in format yymmddb (b = daily build) -#define VERSION 1903032 +#define VERSION 1903051 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, 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 void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 82323041..0801cab5 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -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) { //to save complexity this function is not comprehensive diff --git a/wled00/wled15_hue.ino b/wled00/wled15_hue.ino index e8f0bb46..a67f38b0 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/wled15_hue.ino @@ -115,9 +115,9 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len) if (hueAuthRequired) { 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; hueNewKey = true; } diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino index 5a911513..2c60773c 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled18_server.ino @@ -64,6 +64,10 @@ void initServer() doReboot = true; }); + server.on("/json/state", HTTP_GET, [](AsyncWebServerRequest *request){ + serveJsonState(request); + }); + server.on("/json/effects", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "application/json", JSON_mode_names); }); @@ -172,13 +176,13 @@ void initServer() } else { 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){ - 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){ - 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; 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); //error message is not gzipped @@ -321,7 +325,7 @@ void serveSettings(AsyncWebServerRequest* request) 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 diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino new file mode 100644 index 00000000..c77278df --- /dev/null +++ b/wled00/wled19_json.ino @@ -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); +}