From 6122a8371a4e24267c4dd55d1ec93048c76937f1 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 6 Dec 2019 01:44:45 +0100 Subject: [PATCH] Added Glitter and Candle effects --- wled00/FX.cpp | 89 ++++++++++++++++++++++++++++++++++++------ wled00/FX.h | 15 +++++-- wled00/FX_fcn.cpp | 7 +++- wled00/data/index.htm | 6 +-- wled00/wled00.ino | 2 +- wled00/wled05_init.ino | 18 ++++++++- 6 files changed, 111 insertions(+), 26 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2bdb75ba9..c862a0854 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -533,11 +533,18 @@ uint16_t WS2812FX::mode_dissolve_random(void) { */ uint16_t WS2812FX::mode_sparkle(void) { 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)); } - SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index + uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2; + uint32_t it = now / cycleTime; + if (it != SEGENV.step) + { + SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index + SEGENV.step = it; + } + setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(0)); - return 10 + (uint16_t)(255 - SEGMENT.speed); + return FRAMETIME; } @@ -546,15 +553,10 @@ uint16_t WS2812FX::mode_sparkle(void) { * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ uint16_t WS2812FX::mode_flash_sparkle(void) { - if(SEGENV.call == 0) { - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - } + for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } - uint16_t i = SEGMENT.start + SEGENV.aux0; - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - if(random8(5) == 0) { SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(1)); @@ -613,7 +615,6 @@ uint16_t WS2812FX::mode_multi_strobe(void) { uint16_t WS2812FX::mode_android(void) { if (SEGENV.call == 0) { - SEGENV.aux0 = 0; SEGENV.step = SEGMENT.start; } @@ -1530,13 +1531,13 @@ uint16_t WS2812FX::mode_palette() } bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0)); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) + for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t colorIndex = (i * 255 / SEGLEN) - counter; if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end" - setPixelColor(i, color_from_palette(colorIndex, false, true, 255)); + setPixelColor(SEGMENT.start + i, color_from_palette(colorIndex, false, true, 255)); } return FRAMETIME; } @@ -2285,3 +2286,65 @@ uint16_t WS2812FX::mode_spots_fade() uint16_t tr = (t >> 1) + (t >> 2); return spots_base(tr); } + + +//Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6 +uint16_t WS2812FX::mode_glitter() +{ + mode_palette(); + + if (SEGMENT.intensity > random8()) + { + setPixelColor(SEGMENT.start + random16(SEGLEN), ULTRAWHITE); + } + + return FRAMETIME; +} + + +uint16_t WS2812FX::mode_candle() +{ + if (SEGENV.call == 0) { + SEGENV.aux0 = 128; SEGENV.aux1 = 132; SEGENV.step = 1; + } + bool newTarget = false; + + uint8_t s = SEGENV.aux0, target = SEGENV.aux1, fadeStep = SEGENV.step; + + if (target > s) { //fade up + s = qadd8(s, fadeStep); + if (s >= target) newTarget = true; + } else { + s = qsub8(s, fadeStep); + if (s <= target) newTarget = true; + } + SEGENV.aux0 = s; + + for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); + } + + if (newTarget) + { + uint8_t valrange = SEGMENT.intensity; + uint8_t rndval = valrange >> 1; + target = random8(rndval) + random8(rndval); + if (target < (rndval >> 1)) target += random8(rndval >> 1); + uint8_t offset = (255 - valrange) >> 1; + target += offset; + + uint8_t dif = (target > s) ? target - s : s - target; + uint16_t fadeSpeed = 50 + ((255-SEGMENT.speed) >> 1); + + //how much to move closer to target per frame + fadeStep = dif; + uint8_t frames = 1; + if (fadeSpeed > FRAMETIME) fadeStep = dif / (fadeSpeed / FRAMETIME); + if (fadeStep == 0) fadeStep = 1; + + SEGENV.step = fadeStep; + SEGENV.aux1 = target; + } + + return FRAMETIME; +} diff --git a/wled00/FX.h b/wled00/FX.h index 5a3865ae0..9ba70357d 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -42,7 +42,7 @@ /* Not used in all effects yet */ #define WLED_FPS 42 -#define FRAMETIME 1000/WLED_FPS +#define FRAMETIME (1000/WLED_FPS) /* each segment uses 37 bytes of SRAM memory, so if you're application fails because of insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ @@ -84,7 +84,7 @@ #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED ) -#define MODE_COUNT 87 +#define MODE_COUNT 89 #define FX_MODE_STATIC 0 #define FX_MODE_BLINK 1 @@ -173,6 +173,8 @@ #define FX_MODE_TRI_STATIC_PATTERN 84 #define FX_MODE_SPOTS 85 #define FX_MODE_SPOTS_FADE 86 +#define FX_MODE_GLITTER 87 +#define FX_MODE_CANDLE 88 class WS2812FX { @@ -317,6 +319,8 @@ class WS2812FX { _mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern; _mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots; _mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade; + _mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter; + _mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -497,7 +501,10 @@ class WS2812FX { mode_static_pattern(void), mode_tri_static_pattern(void), mode_spots(void), - mode_spots_fade(void); + mode_spots_fade(void), + mode_glitter(void), + mode_candle(void); + private: NeoPixelWrapper *bus; @@ -570,7 +577,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([ "Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet", "Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise", "Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple", -"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade" +"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle" ])====="; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index b887332f4..ab204d69a 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -711,7 +711,8 @@ void WS2812FX::handle_palette(void) _segment_index_palette_last = _segment_index; byte paletteIndex = SEGMENT.palette; - if ((SEGMENT.mode >= FX_MODE_METEOR) && SEGMENT.palette == 0) paletteIndex = 4; + if (SEGMENT.mode == FX_MODE_GLITTER && paletteIndex == 0) paletteIndex = 11; + if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4; switch (paletteIndex) { @@ -725,6 +726,7 @@ void WS2812FX::handle_palette(void) case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33 + //case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break; default: targetPalette = PartyColors_p; break;//palette, bpm } @@ -763,7 +765,8 @@ void WS2812FX::handle_palette(void) case 5: {//based on primary + secondary CRGB prim = col_to_crgb(SEGCOLOR(0)); CRGB sec = col_to_crgb(SEGCOLOR(1)); - targetPalette = CRGBPalette16(sec,prim,CRGB::White); break;} + CRGB ter = col_to_crgb(SEGCOLOR(2)); + targetPalette = CRGBPalette16(ter,sec,prim); break;} case 6: //Party colors targetPalette = PartyColors_p; break; case 7: //Cloud colors diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 439081b44..460bcadfd 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -941,8 +941,8 @@ function requestJson(command, verbose = true) { e1 = d.getElementById('fxlist'); e2 = d.getElementById('selectPalette'); - //url = command ? 'http://10.10.1.26/json/state':'http://10.10.1.26/json'; url = command ? '/json/state':'/json'; + url = command ? 'http://10.10.1.26/json/state':'http://10.10.1.26/json'; type = command ? 'post':'get'; if (command) { @@ -1096,7 +1096,7 @@ function makeSeg() {
Start LED:
Stop LED: - (${ledCount} LEDs)
+ (${ledCount - ns} LEDs)
`; @@ -1137,8 +1137,6 @@ function setRev(s){ } function setX(ind) { - selectedFx = ind; - var obj = {"seg": {"fx": parseInt(ind)}}; requestJson(obj); } diff --git a/wled00/wled00.ino b/wled00/wled00.ino index f3ce48332..7c621a0bb 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -97,7 +97,7 @@ //version code in format yymmddb (b = daily build) -#define VERSION 1912051 +#define VERSION 1912061 char versionString[] = "0.9.0-dev"; diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index a07ef3d7b..1c5a233ec 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -231,7 +231,7 @@ void initInterfaces() { if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort); initBlynk(blynkApiKey); - Serial.println(e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT)); + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT); reconnectHue(); initMqtt(); interfacesInited = true; @@ -239,11 +239,25 @@ void initInterfaces() { } byte stacO = 0; +uint32_t lastHeap; +unsigned long heapTime = 0; void handleConnection() { - //TODO: reconnect if heap <8000 if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return; if (lastReconnectAttempt == 0) initConnection(); + + //reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 5000) + { + uint32_t heap = ESP.getFreeHeap(); + if (heap < 9000 && lastHeap < 9000) { + DEBUG_PRINT("Heap too low! "); + DEBUG_PRINTLN(heap); + forceReconnect = true; + } + lastHeap = heap; + heapTime = millis(); + } byte stac = 0; if (apActive) {