From 2c3cad6e6171902f7fc73e20c54a14541cebc0ba Mon Sep 17 00:00:00 2001 From: Warren Spits Date: Wed, 27 Nov 2019 08:41:17 +1100 Subject: [PATCH 1/7] Pixel grouping support, configurable through JSON API. It probably breaks cronixie. --- wled00/FX.h | 8 ++-- wled00/FX_fcn.cpp | 101 +++++++++++++++++++++-------------------- wled00/wled03_set.ino | 4 +- wled00/wled05_init.ino | 2 +- wled00/wled19_json.ino | 3 +- 5 files changed, 63 insertions(+), 55 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index 5a3865ae0..6eb7fdebe 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -187,6 +187,7 @@ class WS2812FX { uint8_t intensity; uint8_t palette; uint8_t mode; + uint8_t grouping; uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected uint8_t group, spacing; uint8_t opacity; @@ -331,7 +332,7 @@ class WS2812FX { } void - init(bool supportWhite, uint16_t countPixels, bool skipFirs, uint8_t disableNLeds), + init(bool supportWhite, uint16_t countPixels, uint8_t grouping, uint8_t disableNLeds, bool skipFirst), service(void), blur(uint8_t), fade_out(uint8_t r), @@ -351,7 +352,7 @@ class WS2812FX { unlockAll(void), setTransitionMode(bool t), trigger(void), - setSegment(uint8_t n, uint16_t start, uint16_t stop), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping), resetSegments(), setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), @@ -372,6 +373,7 @@ class WS2812FX { colorOrder = 0, milliampsPerLed = 55, _disableNLeds = 0, + _grouping = 1, getBrightness(void), getMode(void), getSpeed(void), @@ -508,7 +510,7 @@ class WS2812FX { CRGBPalette16 targetPalette; uint32_t now; - uint16_t _length, _lengthRaw, _usableCount; + uint16_t _length, _lengthRaw; uint16_t _rand16seed; uint8_t _brightness; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index b887332f4..02cc7bd8d 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -30,24 +30,14 @@ #define LED_SKIP_AMOUNT 1 #define MIN_SHOW_DELAY 15 -void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uint8_t disableNLeds) +void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t grouping, uint8_t disableNLeds, bool skipFirst) { - if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && disableNLeds == _disableNLeds) return; + if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && grouping == _grouping && disableNLeds == _disableNLeds) return; RESET_RUNTIME; _rgbwMode = supportWhite; _skipFirstMode = skipFirst; _length = countPixels; - - if (disableNLeds > 0) { - uint16_t groupCount = disableNLeds +1; - //since 1st led is lit, even partial group has a led lit, whereas int division truncates decimal. - bool hasExtraLight = _length % groupCount != 0; - _usableCount = _length/groupCount; - _usableCount += hasExtraLight ? 1 : 0; - } else { - _usableCount = _length; - } - + _grouping = grouping; _disableNLeds = disableNLeds; uint8_t ty = 1; @@ -63,12 +53,17 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uin _locked = new byte[_length]; _segments[0].start = 0; - _segments[0].stop = _usableCount; + _segments[0].stop = getUsableCount(); unlockAll(); setBrightness(_brightness); } +uint16_t WS2812FX::getUsableCount() { + uint16_t totalGroup = _grouping + _disableNLeds; + return (_length + totalGroup -1) / totalGroup; +} + void WS2812FX::service() { uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days now = nowUp + timebase; @@ -114,29 +109,40 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { - i = i * (_disableNLeds+1); if (_locked[i] && !_modeUsesLock) return; - if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment - byte tmpg = g; + + RgbwColor color; + color.W = w; switch (colorOrder) //0 = Grb, default { - case 0: break; //0 = Grb, default - case 1: g = r; r = tmpg; break; //1 = Rgb, common for WS2811 - case 2: g = b; b = tmpg; break; //2 = Brg - case 3: g = b; b = r; r = tmpg; //3 = Rbg + case 0: color.G = g; color.R = r; color.B = b; break; // 0 = GRB + case 1: color.G = r; color.R = g; color.B = b; break; // 1 = RGB, common for WS2811 + case 2: color.G = b; color.R = r; color.B = g; break; // 2 = BRG + case 3: color.G = r; color.R = b; color.B = g; break; // 3 = RBG } if (!_cronixieMode) { - if (reverseMode) i = _length -1 -i; - if (_skipFirstMode) + uint16_t totalGroup = SEGMENT.grouping + _disableNLeds; + uint16_t iMax = (SEGMENT.stop - SEGMENT.start) * totalGroup; + int16_t iGroup = (i - SEGMENT.start) * totalGroup; + + /* reverse just an individual segment */ + int16_t realIndex; + if IS_REVERSE + realIndex = SEGMENT.stop - iGroup -1; + else + realIndex = SEGMENT.start + iGroup; + /* Reverse the whole string */ + if (reverseMode) realIndex = _length - 1 - realIndex; + + /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ { - if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0)); - i += LED_SKIP_AMOUNT; - } - if (i < _lengthRaw) bus->SetPixelColor(i, RgbwColor(r,g,b,w)); - if (_disableNLeds > 0) { - for(uint16_t offCount=0; offCount < _disableNLeds; offCount++) { - if (i < _lengthRaw) bus->SetPixelColor((i + offCount + 1), RgbwColor(0,0,0,0)); + bool reversed = reverseMode ^ IS_REVERSE; + uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; + for (uint8_t l = 0; l < totalGroup; l++) { + int16_t indexSet = realIndex + (reversed ? -l : l); + if (indexSet >= SEGMENT.start && (indexSet < SEGMENT.start + iMax)) + bus->SetPixelColor(indexSet + skip, l < SEGMENT.grouping ? color : RgbwColor(0, 0, 0, 0)); } } } else { @@ -162,16 +168,16 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) if (_skipFirstMode) o += LED_SKIP_AMOUNT; switch(_cronixieDigits[i]) { - case 0: bus->SetPixelColor(o+5, RgbwColor(r,g,b,w)); break; - case 1: bus->SetPixelColor(o+0, RgbwColor(r,g,b,w)); break; - case 2: bus->SetPixelColor(o+6, RgbwColor(r,g,b,w)); break; - case 3: bus->SetPixelColor(o+1, RgbwColor(r,g,b,w)); break; - case 4: bus->SetPixelColor(o+7, RgbwColor(r,g,b,w)); break; - case 5: bus->SetPixelColor(o+2, RgbwColor(r,g,b,w)); break; - case 6: bus->SetPixelColor(o+8, RgbwColor(r,g,b,w)); break; - case 7: bus->SetPixelColor(o+3, RgbwColor(r,g,b,w)); break; - case 8: bus->SetPixelColor(o+9, RgbwColor(r,g,b,w)); break; - case 9: bus->SetPixelColor(o+4, RgbwColor(r,g,b,w)); break; + case 0: bus->SetPixelColor(o+5, color); break; + case 1: bus->SetPixelColor(o+0, color); break; + case 2: bus->SetPixelColor(o+6, color); break; + case 3: bus->SetPixelColor(o+1, color); break; + case 4: bus->SetPixelColor(o+7, color); break; + case 5: bus->SetPixelColor(o+2, color); break; + case 6: bus->SetPixelColor(o+8, color); break; + case 7: bus->SetPixelColor(o+3, color); break; + case 8: bus->SetPixelColor(o+9, color); break; + case 9: bus->SetPixelColor(o+4, color); break; } } } @@ -442,18 +448,14 @@ WS2812FX::Segment* WS2812FX::getSegments(void) { return _segments; } -uint16_t WS2812FX::getUsableCount(void) { - return _usableCount; -} - uint32_t WS2812FX::getLastShow(void) { return _lastShow; } -void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) { +void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping) { if (n >= MAX_NUM_SEGMENTS) return; Segment& seg = _segments[n]; - if (seg.start == i1 && seg.stop == i2) return; + if (seg.start == i1 && seg.stop == i2 && seg.grouping == grouping) return; if (seg.isActive() && modeUsesLock(seg.mode)) { _modeUsesLock = false; @@ -465,9 +467,11 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) { { seg.stop = 0; return; } + if (grouping > 0) seg.grouping = grouping; if (i1 < _length) seg.start = i1; + uint16_t maxStop = (_length - seg.start) / seg.grouping; seg.stop = i2; - if (i2 > _length) seg.stop = _length; + if (i2 > maxStop) seg.stop = maxStop; _segment_runtimes[n].reset(); } @@ -479,8 +483,9 @@ void WS2812FX::resetSegments() { _segments[0].colors[0] = DEFAULT_COLOR; _segments[0].start = 0; _segments[0].speed = DEFAULT_SPEED; - _segments[0].stop = _length; + _segments[0].stop = getUsableCount(); _segments[0].setOption(0, 1); //select + _segments[0].grouping = _grouping; } void WS2812FX::setIndividual(uint16_t i, uint32_t col) diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 9bf64374c..debb3d09d 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -274,7 +274,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage == 2) { - strip.init(useRGBW,ledCount,skipFirstLed,disableNLeds); + strip.init(useRGBW,ledCount,1,disableNLeds,skipFirstLed); } if (subPage == 4) alexaInit(); } @@ -375,7 +375,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) { stopI = getNumVal(&req, pos); } - strip.setSegment(main, startI, stopI); + strip.setSegment(main, startI, stopI, 1); main = strip.getMainSegmentId(); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index a07ef3d7b..2288646c3 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -30,7 +30,7 @@ void wledInit() DEBUG_PRINT("heap "); DEBUG_PRINTLN(ESP.getFreeHeap()); - strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204),disableNLeds); //init LEDs quickly + strip.init(EEPROM.read(372),ledCount,1,disableNLeds,EEPROM.read(2204)); //init LEDs quickly strip.setBrightness(0); DEBUG_PRINT("LEDs inited. heap usage ~"); diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index b232b0b6f..c187affff 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -15,7 +15,7 @@ void deserializeSegment(JsonObject elem, byte it) uint16_t len = elem["len"]; stop = (len > 0) ? start + len : seg.stop; } - strip.setSegment(id, start, stop); + strip.setSegment(id, start, stop, 1); JsonArray colarr = elem["col"]; if (!colarr.isNull()) @@ -177,6 +177,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["ix"] = seg.intensity; root["pal"] = seg.palette; root["sel"] = seg.isSelected(); + root["grp"] = seg.grouping; root["rev"] = seg.getOption(1); } From 55e2bc27c684afda1017890a2bc736c95b225cc1 Mon Sep 17 00:00:00 2001 From: Warren Spits Date: Thu, 5 Dec 2019 17:59:05 +1100 Subject: [PATCH 2/7] Converted segments to use lengths.Segment stop is now derived.Clears the skipped pixels.Fixed getPixelColor. --- wled00/FX.h | 27 ++++++----- wled00/FX_fcn.cpp | 101 ++++++++++++++++++++------------------- wled00/wled00.ino | 2 +- wled00/wled01_eeprom.ino | 4 +- wled00/wled02_xml.ino | 2 +- wled00/wled03_set.ino | 6 +-- wled00/wled05_init.ino | 6 +-- wled00/wled19_json.ino | 4 +- 8 files changed, 81 insertions(+), 71 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index 6eb7fdebe..f5f12230f 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -44,7 +44,7 @@ #define WLED_FPS 42 #define FRAMETIME 1000/WLED_FPS -/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of +/* each segment uses 41 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 @@ -180,14 +180,14 @@ class WS2812FX { // segment parameters public: - typedef struct Segment { // 24 bytes + typedef struct Segment { // 25 bytes uint16_t start; uint16_t stop; //segment invalid if stop == 0 + uint16_t rawLength; uint8_t speed; uint8_t intensity; uint8_t palette; uint8_t mode; - uint8_t grouping; uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected uint8_t group, spacing; uint8_t opacity; @@ -217,6 +217,9 @@ class WS2812FX { { return stop - start; } + uint16_t ledGroup() { + return group + spacing; + } } segment; // segment runtime parameters @@ -332,7 +335,7 @@ class WS2812FX { } void - init(bool supportWhite, uint16_t countPixels, uint8_t grouping, uint8_t disableNLeds, bool skipFirst), + init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst), service(void), blur(uint8_t), fade_out(uint8_t r), @@ -352,7 +355,7 @@ class WS2812FX { unlockAll(void), setTransitionMode(bool t), trigger(void), - setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping), + setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing), resetSegments(), setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), @@ -372,8 +375,8 @@ class WS2812FX { paletteBlend = 0, colorOrder = 0, milliampsPerLed = 55, - _disableNLeds = 0, - _grouping = 1, + _spacing = 0, + _group = 1, getBrightness(void), getMode(void), getSpeed(void), @@ -510,7 +513,7 @@ class WS2812FX { CRGBPalette16 targetPalette; uint32_t now; - uint16_t _length, _lengthRaw; + uint16_t _length; uint16_t _rand16seed; uint8_t _brightness; @@ -554,11 +557,13 @@ class WS2812FX { uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; - segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element - // start, stop, speed, intensity, palette, mode, options, 3 unused bytes (group, spacing, opacity), color[] - { 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} + segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 25 bytes per element + // start, stop, length, speed, intensity, palette, mode, options, group, spacing, opacity (unused), color[] + { 0, 7, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} }; segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element + + uint16_t realPixelIndex(uint16_t i); }; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 02cc7bd8d..158a766c2 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -30,38 +30,36 @@ #define LED_SKIP_AMOUNT 1 #define MIN_SHOW_DELAY 15 -void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t grouping, uint8_t disableNLeds, bool skipFirst) +void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst) { - if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && grouping == _grouping && disableNLeds == _disableNLeds) return; + if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && group == _group && spacing == _spacing) return; RESET_RUNTIME; _rgbwMode = supportWhite; _skipFirstMode = skipFirst; _length = countPixels; - _grouping = grouping; - _disableNLeds = disableNLeds; + _group = group; + _spacing = spacing; uint8_t ty = 1; if (supportWhite) ty =2; - _lengthRaw = _length; - if (_skipFirstMode) { - _lengthRaw += LED_SKIP_AMOUNT; - } + uint16_t lengthRaw = _length + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); - bus->Begin((NeoPixelType)ty, _lengthRaw); + bus->Begin((NeoPixelType)ty, lengthRaw); delete[] _locked; _locked = new byte[_length]; _segments[0].start = 0; _segments[0].stop = getUsableCount(); + _segments[0].rawLength = _length; unlockAll(); setBrightness(_brightness); } uint16_t WS2812FX::getUsableCount() { - uint16_t totalGroup = _grouping + _disableNLeds; - return (_length + totalGroup -1) / totalGroup; + uint16_t ledGroup = _group + _spacing; + return (_length + ledGroup -1) / ledGroup; } void WS2812FX::service() { @@ -107,6 +105,21 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { setPixelColor(n, r, g, b, w); } +uint16_t WS2812FX::realPixelIndex(uint16_t i) { + int16_t iGroup = (i - SEGMENT.start) * SEGMENT.ledGroup(); + + /* reverse just an individual segment */ + int16_t realIndex; + if IS_REVERSE + realIndex = SEGMENT.stop - iGroup -1; + else + realIndex = SEGMENT.start + iGroup; + /* Reverse the whole string */ + if (reverseMode) realIndex = _length - 1 - realIndex; + + return realIndex; +} + void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { if (_locked[i] && !_modeUsesLock) return; @@ -122,27 +135,16 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } if (!_cronixieMode) { - uint16_t totalGroup = SEGMENT.grouping + _disableNLeds; - uint16_t iMax = (SEGMENT.stop - SEGMENT.start) * totalGroup; - int16_t iGroup = (i - SEGMENT.start) * totalGroup; - - /* reverse just an individual segment */ - int16_t realIndex; - if IS_REVERSE - realIndex = SEGMENT.stop - iGroup -1; - else - realIndex = SEGMENT.start + iGroup; - /* Reverse the whole string */ - if (reverseMode) realIndex = _length - 1 - realIndex; - /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ - { - bool reversed = reverseMode ^ IS_REVERSE; - uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; - for (uint8_t l = 0; l < totalGroup; l++) { - int16_t indexSet = realIndex + (reversed ? -l : l); - if (indexSet >= SEGMENT.start && (indexSet < SEGMENT.start + iMax)) - bus->SetPixelColor(indexSet + skip, l < SEGMENT.grouping ? color : RgbwColor(0, 0, 0, 0)); + bool reversed = reverseMode ^ IS_REVERSE; + uint16_t realIndex = realPixelIndex(i); + uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; + for (uint16_t l = 0; l < SEGMENT.ledGroup(); l++) { + int16_t indexSet = realIndex + (reversed ? -l : l); + if (indexSet >= SEGMENT.start && (indexSet < SEGMENT.start + SEGMENT.rawLength)) + bus->SetPixelColor(indexSet + skip, l < SEGMENT.group ? color : RgbwColor(0, 0, 0, 0)); + for (uint16_t l = 0; indexSet == 0 && l < skip; l++) {// Clear the skipped pixels + bus->SetPixelColor(l, RgbwColor(0, 0, 0, 0)); } } } else { @@ -399,10 +401,7 @@ uint32_t WS2812FX::getColor(void) { uint32_t WS2812FX::getPixelColor(uint16_t i) { - i = i * (_disableNLeds+1); - if (reverseMode) i = _length- 1 -i; - if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment - if (_skipFirstMode) i += LED_SKIP_AMOUNT; + i = realPixelIndex(i) + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); if (_cronixieMode) { if(i>6)return 0; @@ -422,7 +421,8 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) default: return 0; } } - if (i >= _lengthRaw) return 0; + uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; + if (i >= (_length + skip)) return 0; RgbwColor lColor = bus->GetPixelColorRgbw(i); byte r = lColor.R, g = lColor.G, b = lColor.B; switch (colorOrder) @@ -452,10 +452,10 @@ uint32_t WS2812FX::getLastShow(void) { return _lastShow; } -void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping) { +void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing) { if (n >= MAX_NUM_SEGMENTS) return; Segment& seg = _segments[n]; - if (seg.start == i1 && seg.stop == i2 && seg.grouping == grouping) return; + if (seg.start == start && seg.rawLength == length && seg.group == group && seg.spacing == spacing) return; if (seg.isActive() && modeUsesLock(seg.mode)) { _modeUsesLock = false; @@ -463,16 +463,19 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping) _modeUsesLock = true; } _segment_index = n; fill(0); //turn old segment range off - if (i2 <= i1) //disable segment - { - seg.stop = 0; return; + + seg.rawLength = min(_length - start, length); + seg.spacing = spacing; + seg.group = group; + seg.start = start; + uint16_t ledGroup = seg.ledGroup(); + seg.stop = (seg.rawLength - seg.start + ledGroup -1) / ledGroup + seg.start; + if (seg.start >= seg.stop) { + seg.stop = 0; + } + else { + _segment_runtimes[n].reset(); } - if (grouping > 0) seg.grouping = grouping; - if (i1 < _length) seg.start = i1; - uint16_t maxStop = (_length - seg.start) / seg.grouping; - seg.stop = i2; - if (i2 > maxStop) seg.stop = maxStop; - _segment_runtimes[n].reset(); } void WS2812FX::resetSegments() { @@ -484,8 +487,10 @@ void WS2812FX::resetSegments() { _segments[0].start = 0; _segments[0].speed = DEFAULT_SPEED; _segments[0].stop = getUsableCount(); + _segments[0].rawLength = _length; _segments[0].setOption(0, 1); //select - _segments[0].grouping = _grouping; + _segments[0].group = _group; + _segments[0].spacing = _spacing; } void WS2812FX::setIndividual(uint16_t i, uint32_t col) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index f3ce48332..7052ee94c 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -149,7 +149,7 @@ uint16_t transitionDelay = 750; //default crossfade duration in ms //bool strip.reverseMode = false; //flip entire LED strip (reverses all effect directions) --> edit in WS2812FX.h bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -uint8_t disableNLeds = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look) +uint8_t spacing = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look) byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 879b345ec..38ea7c41a 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -229,7 +229,7 @@ void saveSettingsToEEPROM() saveCurrPresetCycConf = false; } - EEPROM.write(2213, disableNLeds); + EEPROM.write(2213, spacing); writeStringToEEPROM(2220, blynkApiKey, 35); @@ -480,7 +480,7 @@ void loadSettingsFromEEPROM(bool first) presetApplyFx = EEPROM.read(2212); } - disableNLeds = EEPROM.read(2213); + spacing = EEPROM.read(2213); bootPreset = EEPROM.read(389); wifiLock = EEPROM.read(393); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 094b0358f..8303f7fd0 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -237,7 +237,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('i',"PB",strip.paletteBlend); sappend('c',"RV",strip.reverseMode); sappend('c',"SL",skipFirstLed); - sappend('v',"DL",disableNLeds); + sappend('v',"DL",spacing); } if (subPage == 3) diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index debb3d09d..21332ddd1 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -93,7 +93,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (t >= 0 && t < 4) strip.paletteBlend = t; strip.reverseMode = request->hasArg("RV"); skipFirstLed = request->hasArg("SL"); - disableNLeds = request->arg("DL").toInt(); + spacing = request->arg("DL").toInt(); t = request->arg("BF").toInt(); if (t > 0) briMultiplier = t; } @@ -274,7 +274,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage == 2) { - strip.init(useRGBW,ledCount,1,disableNLeds,skipFirstLed); + strip.init(useRGBW,ledCount,1,spacing,skipFirstLed); } if (subPage == 4) alexaInit(); } @@ -375,7 +375,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) { stopI = getNumVal(&req, pos); } - strip.setSegment(main, startI, stopI, 1); + strip.setSegment(main, startI, stopI, 1, 0); main = strip.getMainSegmentId(); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 2288646c3..3559d7b65 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -8,9 +8,9 @@ void wledInit() ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30; - disableNLeds = EEPROM.read(2213); + spacing = EEPROM.read(2213); //this was reading 255 after inital flash causing bootloop. Don't know why. - disableNLeds = disableNLeds != 255 ? disableNLeds : 0; + spacing = spacing!= 255 ? spacing : 0; #ifdef ESP8266 #if LEDPIN == 3 @@ -30,7 +30,7 @@ void wledInit() DEBUG_PRINT("heap "); DEBUG_PRINTLN(ESP.getFreeHeap()); - strip.init(EEPROM.read(372),ledCount,1,disableNLeds,EEPROM.read(2204)); //init LEDs quickly + strip.init(EEPROM.read(372),ledCount,1,spacing,EEPROM.read(2204)); //init LEDs quickly strip.setBrightness(0); DEBUG_PRINT("LEDs inited. heap usage ~"); diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index c187affff..0d1b7d4b3 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -15,7 +15,7 @@ void deserializeSegment(JsonObject elem, byte it) uint16_t len = elem["len"]; stop = (len > 0) ? start + len : seg.stop; } - strip.setSegment(id, start, stop, 1); + strip.setSegment(id, start, stop, 1, 0); JsonArray colarr = elem["col"]; if (!colarr.isNull()) @@ -177,7 +177,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["ix"] = seg.intensity; root["pal"] = seg.palette; root["sel"] = seg.isSelected(); - root["grp"] = seg.grouping; + root["grp"] = seg.group; root["rev"] = seg.getOption(1); } From 2dce4462a06005bbe8a0400cfd28df3626726ad6 Mon Sep 17 00:00:00 2001 From: Warren Spits Date: Mon, 9 Dec 2019 23:16:16 +1100 Subject: [PATCH 3/7] Saving and loading of grouping and spacing. --- wled00/FX_fcn.cpp | 2 ++ wled00/data/settings_leds.htm | Bin 16312 -> 7982 bytes wled00/html_settings.h | 5 +++-- wled00/wled00.ino | 1 + wled00/wled01_eeprom.ino | 2 ++ wled00/wled02_xml.ino | 3 ++- wled00/wled03_set.ino | 5 +++-- wled00/wled05_init.ino | 3 ++- wled00/wled19_json.ino | 15 +++++++-------- 9 files changed, 22 insertions(+), 14 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 158a766c2..3a39b01b7 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -50,6 +50,8 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint _locked = new byte[_length]; _segments[0].start = 0; + _segments[0].group = _group; + _segments[0].spacing = _spacing; _segments[0].stop = getUsableCount(); _segments[0].rawLength = _length; diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 450512b0270776388ca3f5133829d469be188177..eb9774593584332f4a0e23e70d1617231e8f3041 100644 GIT binary patch literal 7982 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 JKizBb{{UG%Wp@Ao literal 16312 zcmds;eNP<85yt!9jg;>&;dD0688G&7xnS%QZ|AdOUo3-tI-O1t7%;@Vg#`n#l8>I` z`E_k=chAhSyI?y}v;uZ!x~uE;sp{(C-~U<&zY8nj&tW;Nho8fXuo|kc8&1PP*bk4x zZ^LiGLd*4b*a%y_=aptGX#BQjZRqPjmrpX%wU_}|uQ&m_@`Xsqe# zRG&T3cq`r(!c4sKaYzbRU9EPaQO9~}ydoc;_fe`!>ps%Yk;a`xuHo#iR@=~=6Rq+- z@-!D7M(uS(bw?u)HJ;UxqzXTT$#AFt{6qg+CrWl0>7R#bjXsW2Pf9+la;ocYm>2Ie zk^(7rMSD{t(b0kKF6!<{ygJgIce>iv-Jg1Tn2GecJJZm}7g1wdvXfaZ>1sl}CTafB z=e8-=(lz9oX<6^CT5 z$2WYe*~+hSzhF)!+v6eAvJU>X8g+_q<0VVsGCbAO$#7fVvKgP<7C%^TS7YADUfX(Z zy3W^t;+ixuEeRI&8(-X)<+pn)PR14P=;}NDN&r+CF{I?4x{IDbvF*{R$n7bGs4QPa~4xyT>tGLE~w}o~yk1 zPSpB`i0kfu{`ZaOKm~7~*YA&`gPn+9(0wSHCE9XlGiK5a;bBu!I7?hT$oLwrJ4TO7 zf37e0DD=tuS|x{aa%ZfuDc-B-F`*W(KDlB z6sO}{Dn=?Tlh0P(iPVU+z1|G-EUp&xvmfoW7rxR5Ov}0Ms8WO9Uo`jEk+Rt+QFkIP zHzku{Z&^`{gQ_N9({eekV#!f>Li1bViT%J~tOwqXoWY^*5wTokwMvzF6=oI7e8!Q@ zQEgQI*_RyOnE&UEnhpN{plaqO{MYRtMFWwCQ_(q zw`Ff4ZL(*nN|9h*xJ)V?yD$c;??#g6MbDxNc$5#u3W#il5ubIo7TynPDI{wp1o7R zt^>RWd#Z^0Rd4^>ZOB!RBDbuqjpngdnZ_QyyQC9}SI=z+%5m(pu>Focrq!%(uFB zO*oc2fAqwf{V(f^`TpPgcO6CWiTvXz`bW<3lsZTos&0<7I^Oq1^qrjoy&1DvjCmkL ze9##4rWkWy-j(aMBPvspYxr8-VvN-dzKbd?v?;!~qCRt(hzL43Q<8<60L@-T>0U>D zZ|N>wOd{h4-Pwy&jhwmZ>i;$TYD#*>rP*ex-e z)wlGQ{wo%vqfO8ETya|I&YbRF6yN+#u7CGBs*PNy9&hM_-Z(oGdWX5kwP^~ja{3-Y zIqlBaa_3qzi%lyMu?1d>4(YXzvU1rOgce?q{D+PweRJQ{8^V1)y@S6V$6fLEci9>) z@nh_n$79`(zrAwARJ7r7q((hhQcL!pmR3QB<5+Ly_8t`fAoz}`=e%(?0{?!VfDH7L z&02Vrcb81V>9k}%eAAFMac9-4W%>UlZ=Ac9Hzr%xF*}c;H{pBvC_RAT82$M?HQ9s+ zI*usu|6q~NkFZI9zbGy)rAy8k52euqMGRQ~t1O>KVjeA3_*!EQvgmWmSgll6McgC4 z)7dCBtk)AD5BSGZ&M@t)DnGZhy8A%?E|NbIn?`Y<-35u@QY&qqmL6U7r&MH*;P;k=8q>`W6n--*&pF$3B&Jsxtd zZnB=8HL~84B!Y{!RR^!Y&T&)P14p5L7fJzeq}_sF)69`w?Q94nQz7gZVcG5u${*UdV?PX`}ruIbr1@V~dTkNBhB zAm9UypQAqUey>Q82@PA-K}}^`kr}}q?94t1ZmiG5UWlD1p1|H}TK2O&XT2)`7q2ve z-4q&N4mP4LWJT{qranUzk%pDL2V=2pv!Da|`0o0mH=5IW;%Zx+oY^{)MQ{%O<_n8V(b_s;08!PDr->0I!a$bKyUs$&D)7n+!YAD~NpO z!?ROA{o^AGRl*i$fYPzLfh zk=k;Htw2W%{X)Ud�crVZ5DS2%EUD+S0tMd@BJxFauOKo#wQgxoi0P590cd^_%lJ zJF@_jtg1pIlj>}J+!gK3Q$GWQ{=JVV5!F1lAW!4hR4sVl)tWMYO*TlLTCWH4Snzry zy~Sm=BwOH9Sa?|Fp7ZIMzs<|pg_Cp4r!6Y+b?*mjIkFtneLz<>A!z;JqJ5IOO%L&zS+)3QWdJ$RB=^X5XDB*Fnms zrh%JDzZj)Y(lmVxZkJ_qJHNsDe%>+PKT9H}Q|y;nU|Dba=aRF7%dw=6=!QN|WZ$I$ zxC2MSsL-WgcZ!c7Q@)~k;wV(u0ebJi_eAt9mLlcr(|yq6Zb|$Nred~8dQE)u{}B(w z$BML`-np~?Ft8`YAQG;}s3vcw2(vs&U5EkYKOx@nM6wI#kUk=x zwH7_4Sy`6acq0u_{ep0&A+NSUecRzU*Cm%tFUT!E4B=l0zjDORB_Kv#MQ$p^BIoSn zaU?-*^h;gqwWn9gWv}u29hxUS&hR#BE%wh=ed9~EdcC)ne9>ckeE!>Zk~h;aIE#*v zggp$k!!Z8qc39GkW=9Ns!v@%+$zzTNOFCB@J*Mh?>{PY2Mb(#Ct}}#P7eCYr`Kf3d z0xxSE`|)l>YW%t>#W>!)9;Hkf+r6NTpGx@8zO-%4TyyKnBxufRSRxcJWWR2EES~x4 zHFvBt%6KGBJ42#rRdYR8Rzf+d8}f)%Gx&H@Yd6!#i=IYY6P_JicDgn6KI|#uE*H@6j`*+`S;?K2%x62 zK1Wlx$^GMeEYn zqz0Q*--p#%Q0ZwTIe z6|0?ply0CrTD}>ixn_l3_t=+x?x|S3iq3aIZ~(&7Ycq_S)p;RrTHnmKU#g?j=G$xP z64JZ2ch&fxXQF;kS7V%LS`(GF6<4$#-As!O%j
Reverse LED order (rotate 180):
Skip first LED:
-Disable repeating N LEDs:
-(Turns off N LEDs between each lit one, spacing out effects)
+LED spacing:
+(Turns off N LEDs between each lit one, spacing out effects)
+LED grouping:
)====="; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 7052ee94c..9e3d86cd2 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -150,6 +150,7 @@ uint16_t transitionDelay = 750; //default crossfade duration in ms //bool strip.reverseMode = false; //flip entire LED strip (reverses all effect directions) --> edit in WS2812FX.h bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) uint8_t spacing = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look) +uint8_t group = 1; //Group LEDs into one logical LED byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 38ea7c41a..1e3d26c82 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -230,6 +230,7 @@ void saveSettingsToEEPROM() } EEPROM.write(2213, spacing); + EEPROM.write(2214, group); writeStringToEEPROM(2220, blynkApiKey, 35); @@ -481,6 +482,7 @@ void loadSettingsFromEEPROM(bool first) } spacing = EEPROM.read(2213); + group = max(1, EEPROM.read(2214)); bootPreset = EEPROM.read(389); wifiLock = EEPROM.read(393); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 8303f7fd0..5adbd9002 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -237,7 +237,8 @@ void getSettingsJS(byte subPage, char* dest) sappend('i',"PB",strip.paletteBlend); sappend('c',"RV",strip.reverseMode); sappend('c',"SL",skipFirstLed); - sappend('v',"DL",spacing); + sappend('v',"SP",spacing); + sappend('v',"GR",group); } if (subPage == 3) diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 21332ddd1..9762ffba1 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -93,7 +93,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (t >= 0 && t < 4) strip.paletteBlend = t; strip.reverseMode = request->hasArg("RV"); skipFirstLed = request->hasArg("SL"); - spacing = request->arg("DL").toInt(); + spacing = request->arg("SP").toInt(); + group = request->arg("GR").toInt(); t = request->arg("BF").toInt(); if (t > 0) briMultiplier = t; } @@ -274,7 +275,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage == 2) { - strip.init(useRGBW,ledCount,1,spacing,skipFirstLed); + strip.init(useRGBW,ledCount,group,spacing,skipFirstLed); } if (subPage == 4) alexaInit(); } diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 3559d7b65..32511be7c 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -11,6 +11,7 @@ void wledInit() spacing = EEPROM.read(2213); //this was reading 255 after inital flash causing bootloop. Don't know why. spacing = spacing!= 255 ? spacing : 0; + group = max(1, EEPROM.read(2214)); #ifdef ESP8266 #if LEDPIN == 3 @@ -30,7 +31,7 @@ void wledInit() DEBUG_PRINT("heap "); DEBUG_PRINTLN(ESP.getFreeHeap()); - strip.init(EEPROM.read(372),ledCount,1,spacing,EEPROM.read(2204)); //init LEDs quickly + strip.init(EEPROM.read(372),ledCount,group,spacing,EEPROM.read(2204)); //init LEDs quickly strip.setBrightness(0); DEBUG_PRINT("LEDs inited. heap usage ~"); diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 0d1b7d4b3..cf3f6be8f 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -8,14 +8,12 @@ void deserializeSegment(JsonObject elem, byte it) if (id < strip.getMaxSegments()) { WS2812FX::Segment& seg = strip.getSegment(id); - uint16_t start = elem["start"] | seg.start; - int stop = elem["stop"] | -1; + uint16_t start = elem.containsKey("start") ? elem["start"] : seg.start; + uint16_t len = elem.containsKey("len") ? elem["len"] : seg.rawLength; + uint8_t group = max(1, elem["grp"] | seg.group); + uint8_t spacing = elem.containsKey("spc") ? elem["spc"] : seg.spacing; - if (stop < 0) { - uint16_t len = elem["len"]; - stop = (len > 0) ? start + len : seg.stop; - } - strip.setSegment(id, start, stop, 1, 0); + strip.setSegment(id, start, len, group, spacing); JsonArray colarr = elem["col"]; if (!colarr.isNull()) @@ -158,7 +156,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["id"] = id; root["start"] = seg.start; root["stop"] = seg.stop; - root["len"] = seg.stop - seg.start; + root["len"] = seg.rawLength; JsonArray colarr = root.createNestedArray("col"); @@ -178,6 +176,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["pal"] = seg.palette; root["sel"] = seg.isSelected(); root["grp"] = seg.group; + root["spc"] = seg.spacing; root["rev"] = seg.getOption(1); } From b1cbbeb93599ccf24e960bc399a60d367739d906 Mon Sep 17 00:00:00 2001 From: Warren Spits Date: Tue, 10 Dec 2019 11:34:11 +1100 Subject: [PATCH 4/7] Segment reverse fix --- wled00/FX_fcn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 3a39b01b7..f68e7d0f5 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -113,7 +113,7 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) { /* reverse just an individual segment */ int16_t realIndex; if IS_REVERSE - realIndex = SEGMENT.stop - iGroup -1; + realIndex = SEGMENT.rawLength + SEGMENT.start - iGroup -1; else realIndex = SEGMENT.start + iGroup; /* Reverse the whole string */ From ae6ba79f1eced7660b34c9b7998fdf6499b5a6bd Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 14 Jan 2020 10:57:23 +0100 Subject: [PATCH 5/7] Grouping and Spacing --- wled00/FX.cpp | 335 +++++++++++++++++++++-------------------- wled00/FX.h | 37 ++--- wled00/FX_fcn.cpp | 220 +++++++++++++-------------- wled00/wled19_json.ino | 26 ++-- 4 files changed, 318 insertions(+), 300 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 72d540a92..d7100f96a 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -69,7 +69,7 @@ uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_ uint32_t color = ((SEGENV.aux0 & 1) == 0) ? color1 : color2; if (color == color1 && do_palette) { - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } else fill(color); @@ -149,18 +149,18 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { if (rem > 255) rem = 255; uint32_t col1 = useRandomColors? color_wheel(SEGENV.aux1) : SEGCOLOR(1); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) + for (uint16_t i = 0; i < SEGLEN; i++) { - uint16_t index = (rev && back)? SEGMENT.stop -1 -i +SEGMENT.start : i; + uint16_t index = (rev && back)? SEGLEN -1 -i : i; uint32_t col0 = useRandomColors? color_wheel(SEGENV.aux0) : color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); - if (i - SEGMENT.start < ledIndex) + if (i < ledIndex) { setPixelColor(index, back? col1 : col0); } else { setPixelColor(index, back? col0 : col1); - if (i - SEGMENT.start == ledIndex) setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, rem)); + if (i == ledIndex) setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, rem)); } } return FRAMETIME; @@ -253,7 +253,7 @@ uint16_t WS2812FX::mode_dynamic(void) { } for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(SEGMENT.start + i, color_wheel(SEGENV.data[i])); + setPixelColor(i, color_wheel(SEGENV.data[i])); } return FRAMETIME; } @@ -272,7 +272,7 @@ uint16_t WS2812FX::mode_breath(void) { } uint8_t lum = 30 + var; - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } @@ -287,7 +287,7 @@ uint16_t WS2812FX::mode_fade(void) { uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)); uint8_t lum = triwave16(counter) >> 8; - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } @@ -303,7 +303,7 @@ uint16_t WS2812FX::scan(bool dual) uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; uint32_t perc = now % cycleTime; uint16_t prog = (perc * 65535) / cycleTime; - uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >>9); + uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9); uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16; fill(SEGCOLOR(1)); @@ -313,14 +313,13 @@ uint16_t WS2812FX::scan(bool dual) if (dual) { for (uint16_t j = led_offset; j < led_offset + size; j++) { - uint16_t i2 = SEGMENT.stop -1 -j; + uint16_t i2 = SEGLEN -1 -j; setPixelColor(i2, color_from_palette(i2, true, PALETTE_SOLID_WRAP, (SEGCOLOR(2))? 2:0)); } } for (uint16_t j = led_offset; j < led_offset + size; j++) { - uint16_t i = SEGMENT.start + j; - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + setPixelColor(j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -363,10 +362,10 @@ uint16_t WS2812FX::mode_rainbow_cycle(void) { uint16_t counter = (now * ((SEGMENT.speed >> 3) +2)) & 0xFFFF; counter = counter >> 8; - for(uint16_t i=0; i < SEGLEN; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { //intensity/29 = 0 (1/16) 1 (1/8) 2 (1/4) 3 (1/2) 4 (1) 5 (2) 6 (4) 7 (8) 8 (16) uint8_t index = (i * (16 << (SEGMENT.intensity /29)) / SEGLEN) + counter; - setPixelColor(SEGMENT.start + i, color_wheel(index)); + setPixelColor(i, color_wheel(index)); } return FRAMETIME; @@ -386,16 +385,16 @@ uint16_t WS2812FX::theater_chase(uint32_t color1, uint32_t color2, bool dopalett SEGENV.step = it; } - for(uint16_t i=0; i < SEGLEN; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { if((i % gap) == SEGENV.aux0) { if (dopalette) { - setPixelColor(SEGMENT.start + i, color_from_palette(SEGMENT.start + i, true, PALETTE_SOLID_WRAP, 0)); + setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } else { - setPixelColor(SEGMENT.start + i, color1); + setPixelColor(i, color1); } } else { - setPixelColor(SEGMENT.start + i, color2); + setPixelColor(i, color2); } } return FRAMETIME; @@ -427,7 +426,7 @@ uint16_t WS2812FX::running_base(bool saw) { uint8_t x_scale = SEGMENT.intensity >> 2; uint32_t counter = (now * SEGMENT.speed) >> 9; - for(uint16_t i=0; i < SEGLEN; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { uint8_t s = 0; uint8_t a = i*x_scale - counter; if (saw) { @@ -439,7 +438,7 @@ uint16_t WS2812FX::running_base(bool saw) { } } s = sin8(a); - setPixelColor(SEGMENT.start + i, color_blend(color_from_palette(SEGMENT.start + i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), s)); + setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), s)); } return FRAMETIME; } @@ -488,8 +487,7 @@ uint16_t WS2812FX::mode_twinkle(void) { { PRNG16 = (uint16_t)(PRNG16 * 2053) + 13849; // next 'random' number uint32_t p = (uint32_t)SEGLEN * (uint32_t)PRNG16; - uint16_t mapped = p >> 16; - uint16_t j = SEGMENT.start + mapped; + uint16_t j = p >> 16; setPixelColor(j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } @@ -508,7 +506,7 @@ uint16_t WS2812FX::dissolve(uint32_t color) { if (random8() <= SEGMENT.intensity) { for (uint8_t times = 0; times < 10; times++) //attempt to spawn a new pixel 5 times { - uint16_t i = SEGMENT.start + random16(SEGLEN); + uint16_t i = random16(SEGLEN); if (SEGENV.aux0) { //dissolve to primary/palette if (getPixelColor(i) == SEGCOLOR(1) || wa) { if (color == SEGCOLOR(0)) @@ -555,7 +553,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 = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2; @@ -566,7 +564,7 @@ uint16_t WS2812FX::mode_sparkle(void) { SEGENV.step = it; } - setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(0)); + setPixelColor(SEGENV.aux0, SEGCOLOR(0)); return FRAMETIME; } @@ -576,13 +574,13 @@ uint16_t WS2812FX::mode_sparkle(void) { * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ uint16_t WS2812FX::mode_flash_sparkle(void) { - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { 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)); + setPixelColor(SEGENV.aux0, SEGCOLOR(1)); return 20; } return 20 + (uint16_t)(255-SEGMENT.speed); @@ -594,13 +592,13 @@ 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 = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } if(random8(5) < 2) { - for(uint16_t i=0; i < max(1, SEGLEN/3); i++) { - setPixelColor(SEGMENT.start + random16(SEGLEN), SEGCOLOR(1)); + for(uint16_t i = 0; i < max(1, SEGLEN/3); i++) { + setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } return 20; } @@ -612,7 +610,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 = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } //blink(SEGCOLOR(0), SEGCOLOR(1), true, true); @@ -621,7 +619,7 @@ uint16_t WS2812FX::mode_multi_strobe(void) { uint16_t count = 2 * ((SEGMENT.speed / 10) + 1); if(SEGENV.step < count) { if((SEGENV.step & 1) == 0) { - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, SEGCOLOR(0)); } delay = 20; @@ -637,12 +635,8 @@ uint16_t WS2812FX::mode_multi_strobe(void) { * Android loading circle */ uint16_t WS2812FX::mode_android(void) { - if (SEGENV.call == 0) - { - SEGENV.step = SEGMENT.start; - } - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } @@ -666,19 +660,19 @@ uint16_t WS2812FX::mode_android(void) { if (SEGENV.call %3 != 1) SEGENV.aux1--; } - if (a >= SEGMENT.stop) a = SEGMENT.start; + if (a >= SEGLEN) a = 0; - if (a + SEGENV.aux1 < SEGMENT.stop) + if (a + SEGENV.aux1 < SEGLEN) { for(int i = a; i < a+SEGENV.aux1; i++) { setPixelColor(i, SEGCOLOR(0)); } } else { - for(int i = a; i < SEGMENT.stop; i++) { + for(int i = a; i < SEGLEN; i++) { setPixelColor(i, SEGCOLOR(0)); } - for(int i = SEGMENT.start; i < SEGENV.aux1 - (SEGMENT.stop -a); i++) { + for(int i = 0; i < SEGENV.aux1 - (SEGLEN -a); i++) { setPixelColor(i, SEGCOLOR(0)); } } @@ -699,11 +693,11 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool uint16_t b = (a + 1 + (SEGMENT.intensity * SEGLEN >> 10)) % SEGLEN; uint16_t c = (b + 1 + (SEGMENT.intensity * SEGLEN >> 10)) % SEGLEN; - if (dopalette) color1 = color_from_palette(SEGMENT.start + a, true, PALETTE_SOLID_WRAP, 1); + if (dopalette) color1 = color_from_palette(a, true, PALETTE_SOLID_WRAP, 1); - setPixelColor(SEGMENT.start + a, color1); - setPixelColor(SEGMENT.start + b, color2); - setPixelColor(SEGMENT.start + c, color3); + setPixelColor(a, color1); + setPixelColor(b, color2); + setPixelColor(c, color3); return FRAMETIME; } @@ -721,7 +715,7 @@ uint16_t WS2812FX::mode_chase_color(void) { * Primary running followed by random color. */ uint16_t WS2812FX::mode_chase_random(void) { - if(SEGENV.step == 0) { + if (SEGENV.step == 0) { SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); } return chase(color_wheel(SEGENV.aux0), SEGCOLOR(0), SEGCOLOR(0), false); @@ -764,23 +758,23 @@ uint16_t WS2812FX::mode_colorful(void) { SEGENV.step = it; } - uint16_t i = SEGMENT.start; - for (i; i < SEGMENT.stop -3; i+=4) + uint16_t i = 0; + for (i; i < SEGLEN -3; i+=4) { setPixelColor(i, cols[SEGENV.aux0]); setPixelColor(i+1, cols[SEGENV.aux0+1]); setPixelColor(i+2, cols[SEGENV.aux0+2]); setPixelColor(i+3, cols[SEGENV.aux0+3]); } - if(i < SEGMENT.stop) + if(i < SEGLEN) { setPixelColor(i, cols[SEGENV.aux0]); - if(i+1 < SEGMENT.stop) + if(i+1 < SEGLEN) { setPixelColor(i+1, cols[SEGENV.aux0+1]); - if(i+2 < SEGMENT.stop) + if(i+2 < SEGLEN) { setPixelColor(i+2, cols[SEGENV.aux0+2]); } @@ -795,10 +789,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=0; i < SEGLEN; i++) setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); uint32_t mdelay = 500; - for (int i = SEGMENT.start; i < SEGMENT.stop-2 ; i+=3) + for (int i = 0; i < SEGLEN-2 ; i+=3) { switch (SEGENV.aux0) { @@ -839,7 +833,7 @@ uint16_t WS2812FX::mode_chase_rainbow(void) { uint16_t WS2812FX::mode_chase_flash(void) { uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } @@ -848,8 +842,8 @@ uint16_t WS2812FX::mode_chase_flash(void) { if(flash_step % 2 == 0) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; - setPixelColor(SEGMENT.start + n, SEGCOLOR(1)); - setPixelColor(SEGMENT.start + m, SEGCOLOR(1)); + setPixelColor( n, SEGCOLOR(1)); + setPixelColor( m, SEGCOLOR(1)); delay = 20; } else { delay = 30; @@ -867,8 +861,8 @@ uint16_t WS2812FX::mode_chase_flash(void) { uint16_t WS2812FX::mode_chase_flash_random(void) { uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); - for(uint16_t i=0; i < SEGENV.step; i++) { - setPixelColor(SEGMENT.start + i, color_wheel(SEGENV.aux0)); + for(uint16_t i = 0; i < SEGENV.step; i++) { + setPixelColor(i, color_wheel(SEGENV.aux0)); } uint16_t delay = 1 + ((10 * (uint16_t)(255 - SEGMENT.speed)) / SEGLEN); @@ -876,12 +870,12 @@ uint16_t WS2812FX::mode_chase_flash_random(void) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; if(flash_step % 2 == 0) { - setPixelColor(SEGMENT.start + n, SEGCOLOR(0)); - setPixelColor(SEGMENT.start + m, SEGCOLOR(0)); + setPixelColor( n, SEGCOLOR(0)); + setPixelColor( m, SEGCOLOR(0)); delay = 20; } else { - setPixelColor(SEGMENT.start + n, color_wheel(SEGENV.aux0)); - setPixelColor(SEGMENT.start + m, SEGCOLOR(1)); + setPixelColor( n, color_wheel(SEGENV.aux0)); + setPixelColor( m, SEGCOLOR(1)); delay = 30; } } else { @@ -904,17 +898,17 @@ uint16_t WS2812FX::running(uint32_t color1, uint32_t color2) { uint32_t it = now / cycleTime; if (SEGMENT.speed == 0) it = 0; - for(uint16_t i=0; i < SEGLEN; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { if((i + SEGENV.aux0) % (pxw*2) < pxw) { if (color1 == SEGCOLOR(0)) { - setPixelColor(SEGMENT.stop -i -1, color_from_palette(SEGMENT.stop -i -1, true, PALETTE_SOLID_WRAP, 0)); + setPixelColor(SEGLEN -i -1, color_from_palette(SEGLEN -i -1, true, PALETTE_SOLID_WRAP, 0)); } else { - setPixelColor(SEGMENT.stop -i -1, color1); + setPixelColor(SEGLEN -i -1, color1); } } else { - setPixelColor(SEGMENT.stop -i -1, color2); + setPixelColor(SEGLEN -i -1, color2); } } @@ -962,13 +956,17 @@ uint16_t WS2812FX::mode_halloween(void) { * Random colored pixels running. */ uint16_t WS2812FX::mode_running_random(void) { + uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + if (SEGENV.aux1 == it) return FRAMETIME; + for(uint16_t i=SEGLEN-1; i > 0; i--) { - setPixelColor(SEGMENT.start + i, getPixelColor(SEGMENT.start + i - 1)); + setPixelColor( i, getPixelColor( i - 1)); } if(SEGENV.step == 0) { SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); - setPixelColor(SEGMENT.start, color_wheel(SEGENV.aux0)); + setPixelColor(0, color_wheel(SEGENV.aux0)); } SEGENV.step++; @@ -976,7 +974,9 @@ uint16_t WS2812FX::mode_running_random(void) { { SEGENV.step = 0; } - return SPEED_FORMULA_L; + + SEGENV.aux1 = it; + return FRAMETIME; } @@ -999,7 +999,7 @@ uint16_t WS2812FX::larson_scanner(bool dual) { for (uint16_t i = SEGENV.step; i < index; i++) { uint16_t j = (SEGENV.aux0)?i:SEGLEN-1-i; - setPixelColor(SEGMENT.start + j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); + setPixelColor( j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } if (dual) { uint32_t c; @@ -1011,7 +1011,7 @@ uint16_t WS2812FX::larson_scanner(bool dual) { for (uint16_t i = SEGENV.step; i < index; i++) { uint16_t j = (SEGENV.aux0)?SEGLEN-1-i:i; - setPixelColor(SEGMENT.start + j, c); + setPixelColor(j, c); } } @@ -1029,7 +1029,7 @@ uint16_t WS2812FX::mode_comet(void) { fade_out(SEGMENT.intensity); - setPixelColor(SEGMENT.start + index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + setPixelColor( index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); return FRAMETIME; } @@ -1044,8 +1044,8 @@ uint16_t WS2812FX::mode_fireworks() { SEGENV.aux0 = UINT16_MAX; SEGENV.aux1 = UINT16_MAX; } - bool valid1 = (SEGENV.aux0 < SEGMENT.stop && SEGENV.aux0 >= SEGMENT.start); - bool valid2 = (SEGENV.aux1 < SEGMENT.stop && SEGENV.aux1 >= SEGMENT.start); + bool valid1 = (SEGENV.aux0 < SEGLEN && SEGENV.aux0 >= 0); + bool valid2 = (SEGENV.aux1 < SEGLEN && SEGENV.aux1 >= 0); uint32_t sv1 = 0, sv2 = 0; if (valid1) sv1 = getPixelColor(SEGENV.aux0); if (valid2) sv2 = getPixelColor(SEGENV.aux1); @@ -1055,7 +1055,7 @@ uint16_t WS2812FX::mode_fireworks() { for(uint16_t i=0; i> 1)) == 0) { - uint16_t index = SEGMENT.start + random(SEGLEN); + uint16_t index = random(SEGLEN); setPixelColor(index, color_from_palette(random8(), false, false, 0)); SEGENV.aux1 = SEGENV.aux0; SEGENV.aux0 = index; @@ -1072,17 +1072,17 @@ uint16_t WS2812FX::mode_rain() if (SEGENV.step > SPEED_FORMULA_L) { SEGENV.step = 0; //shift all leds right - uint32_t ctemp = getPixelColor(SEGMENT.stop -1); - for(uint16_t i=SEGMENT.stop -1; i>SEGMENT.start; i--) { + uint32_t ctemp = getPixelColor(SEGLEN -1); + for(uint16_t i = SEGLEN -1; i > 0; i--) { setPixelColor(i, getPixelColor(i-1)); } - setPixelColor(SEGMENT.start, ctemp); + setPixelColor(0, ctemp); SEGENV.aux0++; SEGENV.aux1++; if (SEGENV.aux0 == 0) SEGENV.aux0 = UINT16_MAX; if (SEGENV.aux1 == 0) SEGENV.aux0 = UINT16_MAX; - if (SEGENV.aux0 == SEGMENT.stop) SEGENV.aux0 = SEGMENT.start; - if (SEGENV.aux1 == SEGMENT.stop) SEGENV.aux1 = SEGMENT.start; + if (SEGENV.aux0 == SEGLEN) SEGENV.aux0 = 0; + if (SEGENV.aux1 == SEGLEN) SEGENV.aux1 = 0; } return mode_fireworks(); } @@ -1092,13 +1092,17 @@ uint16_t WS2812FX::mode_rain() * Fire flicker function */ uint16_t WS2812FX::mode_fire_flicker(void) { + uint32_t cycleTime = 40 + (255 - SEGMENT.speed); + uint32_t it = now / cycleTime; + if (SEGENV.step == it) return FRAMETIME; + byte w = (SEGCOLOR(0) >> 24) & 0xFF; byte r = (SEGCOLOR(0) >> 16) & 0xFF; byte g = (SEGCOLOR(0) >> 8) & 0xFF; byte b = (SEGCOLOR(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 = 0; i < SEGLEN; 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)); @@ -1106,7 +1110,9 @@ uint16_t WS2812FX::mode_fire_flicker(void) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } } - return 20 + random((255 - SEGMENT.speed),(2 * (uint16_t)(255 - SEGMENT.speed))); + + SEGENV.step = it; + return FRAMETIME; } @@ -1116,7 +1122,7 @@ uint16_t WS2812FX::mode_fire_flicker(void) { uint16_t WS2812FX::gradient_base(bool loading) { uint16_t counter = now * (SEGMENT.speed >> 3) + 1; SEGENV.step = counter * SEGLEN >> 16; - if (SEGMENT.speed == 0) SEGENV.step = SEGMENT.start + (SEGLEN >> 1); + if (SEGMENT.speed == 0) SEGENV.step = SEGLEN >> 1; if (SEGENV.call == 0) SEGENV.step = 0; float per,val; //0.0 = sec 1.0 = pri float brd = SEGMENT.intensity; @@ -1126,7 +1132,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { int p1 = pp-SEGLEN; int p2 = pp+SEGLEN; - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) + for(uint16_t i = 0; i < SEGLEN; i++) { if (loading) { @@ -1172,8 +1178,8 @@ uint16_t WS2812FX::police_base(uint32_t color1, uint32_t color2) if (idexR > topindex) idexB -= SEGLEN; if (idexB >= SEGLEN) idexB = 0; //otherwise overflow on odd number of LEDs - setPixelColor(SEGMENT.start + idexR, color1); - setPixelColor(SEGMENT.start + idexB, color2); + setPixelColor(idexR, color1); + setPixelColor(idexB, color2); return FRAMETIME; } @@ -1221,14 +1227,14 @@ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) { uint8_t width = (1 + SEGMENT.intensity/32) * 3; //value of 1-8 for each colour uint8_t index = it % width; - for(uint16_t i=0; i < SEGLEN; i++, index++) { + for(uint16_t i = 0; i < SEGLEN; i++, index++) { if(index > width-1) index = 0; uint32_t color = color1; if(index > width*2/3-1) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); else if(index > width/3-1) color = color2; - setPixelColor(SEGMENT.stop - i -1, color); + setPixelColor(SEGLEN - i -1, color); } return FRAMETIME; @@ -1262,13 +1268,13 @@ uint16_t WS2812FX::mode_icu(void) { byte pindex = map(dest, 0, SEGLEN/2, 0, 255); uint32_t col = color_from_palette(pindex, false, false, 0); - setPixelColor(SEGMENT.start + dest, col); - setPixelColor(SEGMENT.start + dest + SEGLEN/2, col); + setPixelColor( dest, col); + setPixelColor( dest + SEGLEN/2, col); if(SEGENV.aux0 == dest) { // pause between eye movements if(random8(6) == 0) { // blink once in a while - setPixelColor(SEGMENT.start + dest, SEGCOLOR(1)); - setPixelColor(SEGMENT.start + dest + SEGLEN/2, SEGCOLOR(1)); + setPixelColor( dest, SEGCOLOR(1)); + setPixelColor( dest + SEGLEN/2, SEGCOLOR(1)); return 200; } SEGENV.aux0 = random16(SEGLEN/2); @@ -1283,8 +1289,8 @@ uint16_t WS2812FX::mode_icu(void) { dest--; } - setPixelColor(SEGMENT.start + dest, col); - setPixelColor(SEGMENT.start + dest + SEGLEN/2, col); + setPixelColor(dest, col); + setPixelColor(dest + SEGLEN/2, col); return SPEED_FORMULA_L; } @@ -1301,26 +1307,26 @@ uint16_t WS2812FX::mode_tricolor_wipe(void) uint16_t ledIndex = (prog * SEGLEN * 3) >> 16; uint16_t ledOffset = ledIndex; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) + for (uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2)); } if(ledIndex < SEGLEN) { //wipe from 0 to 1 - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) + for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, (i - SEGMENT.start > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); + setPixelColor(i, (i > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); } } else if (ledIndex < SEGLEN*2) { //wipe from 1 to 2 ledOffset = ledIndex - SEGLEN; - for (uint16_t i = SEGMENT.start +ledOffset +1; i < SEGMENT.stop; i++) + for (uint16_t i = ledOffset +1; i < SEGLEN; i++) { setPixelColor(i, SEGCOLOR(1)); } } else //wipe from 2 to 0 { ledOffset = ledIndex - SEGLEN*2; - for (uint16_t i = SEGMENT.start; i <= SEGMENT.start +ledOffset; i++) + for (uint16_t i = 0; i <= ledOffset; i++) { setPixelColor(i, SEGCOLOR(0)); } @@ -1359,7 +1365,7 @@ uint16_t WS2812FX::mode_tricolor_fade(void) byte stp = prog; // % 256 uint32_t color = 0; - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { + for(uint16_t i = 0; i < SEGLEN; i++) { if (stage == 2) { color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); } else if (stage == 1) { @@ -1370,10 +1376,7 @@ uint16_t WS2812FX::mode_tricolor_fade(void) setPixelColor(i, color); } - SEGENV.step += 4; - if(SEGENV.step >= 768) SEGENV.step = 0; - - return 5 + ((uint32_t)(255 - SEGMENT.speed) / 10); + return FRAMETIME; } @@ -1383,13 +1386,17 @@ uint16_t WS2812FX::mode_tricolor_fade(void) */ uint16_t WS2812FX::mode_multi_comet(void) { + uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + if (SEGENV.step == it) return FRAMETIME; + fade_out(SEGMENT.intensity); static uint16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; for(uint8_t i=0; i < 8; i++) { if(comets[i] < SEGLEN) { - uint16_t index = SEGMENT.start + comets[i]; + uint16_t index = comets[i]; if (SEGCOLOR(2) != 0) { setPixelColor(index, i % 2 ? color_from_palette(index, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(2)); @@ -1404,7 +1411,9 @@ uint16_t WS2812FX::mode_multi_comet(void) } } } - return SPEED_FORMULA_L; + + SEGENV.step = it; + return FRAMETIME; } @@ -1427,15 +1436,15 @@ uint16_t WS2812FX::mode_random_chase(void) uint32_t it = now / cycleTime; if (SEGENV.step == it) return FRAMETIME; - for(uint16_t i=SEGMENT.stop -1; i>SEGMENT.start; i--) { + for(uint16_t i = SEGLEN -1; i > 0; i--) { setPixelColor(i, getPixelColor(i-1)); } - uint32_t color = getPixelColor(SEGMENT.start); - if (SEGLEN > 1) color = getPixelColor(SEGMENT.start + 1); + uint32_t color = getPixelColor(0); + if (SEGLEN > 1) color = getPixelColor( 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(); - setPixelColor(SEGMENT.start, r, g, b); + setPixelColor(0, r, g, b); SEGENV.step = it; return FRAMETIME; @@ -1471,7 +1480,7 @@ uint16_t WS2812FX::mode_oscillate(void) uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed)); uint32_t it = now / cycleTime; - for(uint8_t i=0; i < numOscillators; i++) { + for(uint8_t i = 0; i < numOscillators; i++) { // if the counter has increased, move the oscillator by the random step if (it != SEGENV.step) oscillators[i].pos += oscillators[i].dir * oscillators[i].speed; oscillators[i].size = SEGLEN/(3+SEGMENT.intensity/8); @@ -1495,7 +1504,7 @@ uint16_t WS2812FX::mode_oscillate(void) color = (color == BLACK) ? SEGMENT.colors[j] : color_blend(color, SEGMENT.colors[j], 128); } } - setPixelColor(SEGMENT.start + i, color); + setPixelColor(i, color); } SEGENV.step = it; @@ -1505,8 +1514,8 @@ uint16_t WS2812FX::mode_oscillate(void) uint16_t WS2812FX::mode_lightning(void) { - uint16_t ledstart = SEGMENT.start + random16(SEGLEN); // Determine starting location of flash - uint16_t ledlen = random16(SEGMENT.stop -1 -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) + uint16_t ledstart = random16(SEGLEN); // Determine starting location of flash + uint16_t ledlen = random16(SEGLEN -1 -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/random8(1, 3); if (SEGENV.step == 0) @@ -1565,7 +1574,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 = 0 ; i < SEGLEN; i++) { hue16 += hueinc16; uint8_t hue8 = hue16 >> 8; @@ -1579,7 +1588,7 @@ uint16_t WS2812FX::mode_pride_2015(void) CRGB newcolor = CHSV( hue8, sat8, bri8); fastled_col = col_to_crgb(getPixelColor(i)); - nblend( fastled_col, newcolor, 64); + nblend(fastled_col, newcolor, 64); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step = sPseudotime; @@ -1594,7 +1603,7 @@ uint16_t WS2812FX::mode_juggle(void){ CRGB fastled_col; byte dothue = 0; for ( byte i = 0; i < 8; i++) { - uint16_t index = SEGMENT.start + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); + uint16_t index = 0 + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); fastled_col = col_to_crgb(getPixelColor(index)); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(currentPalette, dothue, 255); setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -1620,7 +1629,7 @@ uint16_t WS2812FX::mode_palette() if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end" - setPixelColor(SEGMENT.start + i, color_from_palette(colorIndex, false, true, 255)); + setPixelColor(i, color_from_palette(colorIndex, false, true, 255)); } return FRAMETIME; } @@ -1687,7 +1696,7 @@ uint16_t WS2812FX::mode_fire_2012() // Step 4. Map from heat cells to LED colors for (uint16_t j = 0; j < SEGLEN; j++) { CRGB color = ColorFromPalette(currentPalette, min(heat[j],240), 255, LINEARBLEND); - setPixelColor(SEGMENT.start + j, color.red, color.green, color.blue); + setPixelColor(j, color.red, color.green, color.blue); } return FRAMETIME; } @@ -1702,7 +1711,7 @@ uint16_t WS2812FX::mode_colorwaves() uint16_t sPseudotime = SEGENV.step; uint16_t sHue16 = SEGENV.aux0; - uint8_t brightdepth = beatsin88( 341, 96, 224); + uint8_t brightdepth = beatsin88(341, 96, 224); uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); uint8_t msmultiplier = beatsin88(147, 23, 60); @@ -1710,11 +1719,11 @@ uint16_t WS2812FX::mode_colorwaves() uint16_t hueinc16 = beatsin88(113, 300, 1500); sPseudotime += duration * msmultiplier; - sHue16 += duration * beatsin88( 400, 5, 9); + sHue16 += duration * beatsin88(400, 5, 9); uint16_t brightnesstheta16 = sPseudotime; CRGB fastled_col; - for ( uint16_t i = SEGMENT.start ; i < SEGMENT.stop; i++) { + for ( uint16_t i = 0 ; i < SEGLEN; i++) { hue16 += hueinc16; uint8_t hue8 = hue16 >> 8; uint16_t h16_128 = hue16 >> 7; @@ -1749,7 +1758,7 @@ uint16_t WS2812FX::mode_bpm() CRGB fastled_col; uint32_t stp = (now / 20) & 0xFF; uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { fastled_col = ColorFromPalette(currentPalette, stp + (i * 2), beat - stp + (i * 10)); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } @@ -1761,8 +1770,8 @@ uint16_t WS2812FX::mode_fillnoise8() { if (SEGENV.call == 0) SEGENV.step = random16(12345); CRGB fastled_col; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { - uint8_t index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN) % 255; + for (uint16_t i = 0; i < SEGLEN; i++) { + uint8_t index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN); fastled_col = ColorFromPalette(currentPalette, index, 255, LINEARBLEND); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } @@ -1777,7 +1786,7 @@ uint16_t WS2812FX::mode_noise16_1() CRGB fastled_col; SEGENV.step += (1 + SEGMENT.speed/16); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { uint16_t shift_x = beatsin8(11); // the x position of the noise field swings @ 17 bpm uint16_t shift_y = SEGENV.step/42; // the y position becomes slowly incremented @@ -1805,7 +1814,7 @@ uint16_t WS2812FX::mode_noise16_2() CRGB fastled_col; SEGENV.step += (1 + (SEGMENT.speed >> 1)); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { uint16_t shift_x = SEGENV.step >> 6; // x as a function of time uint16_t shift_y = SEGENV.step/42; @@ -1830,7 +1839,7 @@ uint16_t WS2812FX::mode_noise16_3() CRGB fastled_col; SEGENV.step += (1 + SEGMENT.speed); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { uint16_t shift_x = 4223; // no movement along x and y uint16_t shift_y = 1234; @@ -1856,8 +1865,8 @@ uint16_t WS2812FX::mode_noise16_4() { CRGB fastled_col; uint32_t stp = (now * SEGMENT.speed) >> 7; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { - int16_t index = inoise16(uint32_t(i - SEGMENT.start) << 12, stp); + for (uint16_t i = 0; i < SEGLEN; i++) { + int16_t index = inoise16(uint32_t(i) << 12, stp); fastled_col = ColorFromPalette(currentPalette, index); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } @@ -1873,11 +1882,11 @@ 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 = 0; i < SEGLEN; i++) { fastled_col = col_to_crgb(getPixelColor(i)); prev = fastled_col; - uint16_t index = (i - SEGMENT.start) >> 3; - uint8_t bitNum = (i - SEGMENT.start) & 0x07; + uint16_t index = i >> 3; + uint8_t bitNum = i & 0x07; bool fadeUp = bitRead(SEGENV.data[index], bitNum); if (fadeUp) { @@ -1906,11 +1915,11 @@ uint16_t WS2812FX::mode_colortwinkle() if (random8() <= SEGMENT.intensity) { for (uint8_t times = 0; times < 5; times++) //attempt to spawn a new pixel 5 times { - int i = SEGMENT.start + random16(SEGLEN); + int i = random16(SEGLEN); if(getPixelColor(i) == 0) { fastled_col = ColorFromPalette(currentPalette, random8(), 64, NOBLEND); - uint16_t index = (i - SEGMENT.start) >> 3; - uint8_t bitNum = (i - SEGMENT.start) & 0x07; + uint16_t index = i >> 3; + uint8_t bitNum = i & 0x07; bitWrite(SEGENV.data[index], bitNum, true); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); break; //only spawn 1 new pixel per frame per 50 LEDs @@ -1930,7 +1939,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 = 0; i < SEGLEN; i++) { int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; uint8_t lum = (index > wave3) ? index - wave3 : 0; @@ -1959,7 +1968,7 @@ uint16_t WS2812FX::mode_meteor() { { byte meteorTrailDecay = 128 + random8(127); trail[i] = scale8(trail[i], meteorTrailDecay); - setPixelColor(SEGMENT.start + i, color_from_palette(trail[i], false, true, 255)); + setPixelColor(i, color_from_palette(trail[i], false, true, 255)); } } @@ -1971,7 +1980,7 @@ uint16_t WS2812FX::mode_meteor() { } trail[index] = 240; - setPixelColor(SEGMENT.start + index, color_from_palette(trail[index], false, true, 255)); + setPixelColor(index, color_from_palette(trail[index], false, true, 255)); } return FRAMETIME; @@ -1997,7 +2006,7 @@ uint16_t WS2812FX::mode_meteor_smooth() { trail[i] += change; if (trail[i] > 245) trail[i] = 0; if (trail[i] > 240) trail[i] = 240; - setPixelColor(SEGMENT.start + i, color_from_palette(trail[i], false, true, 255)); + setPixelColor(i, color_from_palette(trail[i], false, true, 255)); } } @@ -2007,7 +2016,7 @@ uint16_t WS2812FX::mode_meteor_smooth() { if(in + j >= SEGLEN) { index = (in + j - SEGLEN); } - setPixelColor(SEGMENT.start + index, color_blend(getPixelColor(SEGMENT.start + index), color_from_palette(240, false, true, 255), 48)); + setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48)); trail[index] = 240; } @@ -2034,10 +2043,10 @@ uint16_t WS2812FX::mode_railway() if (p0 < 255) pos = p0; } if (SEGENV.aux0) pos = 255 - pos; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i += 2) + for (uint16_t i = 0; i < SEGLEN; i += 2) { setPixelColor(i, color_from_palette(255 - pos, false, false, 255)); - if (i < SEGMENT.stop -1) + if (i < SEGLEN -1) { setPixelColor(i + 1, color_from_palette(pos, false, false, 255)); } @@ -2088,12 +2097,12 @@ uint16_t WS2812FX::mode_ripple() for (int16_t v = left; v < left +4; v++) { uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp); - if (v < SEGMENT.stop && v >= SEGMENT.start) + if (v < SEGLEN && v >= 0) { 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 < SEGLEN && w >= 0) { setPixelColor(w, color_blend(getPixelColor(w), col, mag)); } @@ -2105,7 +2114,7 @@ uint16_t WS2812FX::mode_ripple() if (random16(IBN + 10000) <= SEGMENT.intensity) { ripples[i].state = 1; - ripples[i].pos = SEGMENT.start + random16(SEGLEN); + ripples[i].pos = random16(SEGLEN); ripples[i].color = random8(); //color } } @@ -2209,7 +2218,7 @@ uint16_t WS2812FX::twinklefox_base(bool cat) uint8_t backgroundBrightness = bg.getAverageLight(); - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number uint16_t myclockoffset16= PRNG16; // use that number as clock offset @@ -2270,7 +2279,7 @@ uint16_t WS2812FX::mode_halloween_eyes() if (stateTime == 0) stateTime = 2000; if (state == 0) { //spawn eyes - SEGENV.aux0 = random16(SEGMENT.start, SEGMENT.stop - eyeLength); //start pos + SEGENV.aux0 = random16(0, SEGLEN - eyeLength); //start pos SEGENV.aux1 = random8(); //color state = 1; } @@ -2320,7 +2329,7 @@ uint16_t WS2812FX::mode_static_pattern() bool drawingLit = true; uint16_t cnt = 0; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, (drawingLit) ? color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(1)); cnt++; if (cnt >= ((drawingLit) ? lit : unlit)) { @@ -2338,7 +2347,7 @@ uint16_t WS2812FX::mode_tri_static_pattern() uint8_t currSeg = 0; uint16_t currSegCount = 0; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { if ( currSeg % 3 == 0 ) { setPixelColor(i, SEGCOLOR(0)); } else if( currSeg % 3 == 1) { @@ -2373,7 +2382,7 @@ uint16_t WS2812FX::spots_base(uint16_t threshold) { uint16_t wave = triwave16((i * 0xFFFF) / zoneLen); if (wave > threshold) { - uint16_t index = SEGMENT.start + pos + i; + uint16_t index = 0 + pos + i; uint8_t s = (wave - threshold)*255 / (0xFFFF - threshold); setPixelColor(index, color_blend(color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); } @@ -2460,7 +2469,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { } uint16_t pos = round(balls[i].height * (SEGLEN - 1)); - setPixelColor(SEGMENT.start + pos, color); + setPixelColor(pos, color); } return FRAMETIME; @@ -2478,7 +2487,7 @@ uint16_t WS2812FX::sinelon_base(bool dual, bool rainbow=false) { if (rainbow) { color1 = color_wheel((pos & 0x07) * 32); } - setPixelColor(SEGMENT.start + pos, color1); + setPixelColor(pos, color1); if (dual) { uint32_t color2 = SEGCOLOR(2); @@ -2486,7 +2495,7 @@ uint16_t WS2812FX::sinelon_base(bool dual, bool rainbow=false) { if (!color2) color2 = color_from_palette(pos, true, false, 0); if (rainbow) color2 = color1; //rainbow - setPixelColor(SEGMENT.start + SEGLEN-1-pos, color2); + setPixelColor(SEGLEN-1-pos, color2); } return FRAMETIME; @@ -2512,7 +2521,7 @@ uint16_t WS2812FX::mode_glitter() if (SEGMENT.intensity > random8()) { - setPixelColor(SEGMENT.start + random16(SEGLEN), ULTRAWHITE); + setPixelColor(random16(SEGLEN), ULTRAWHITE); } return FRAMETIME; @@ -2553,16 +2562,16 @@ uint16_t WS2812FX::mode_popcorn(void) { for(uint8_t i = 0; i < numPopcorn; i++) { bool isActive = popcorn[i].pos >= 0.0f; - if(isActive) { // if kernel is active, update its position + if (isActive) { // if kernel is active, update its position popcorn[i].pos += popcorn[i].vel; popcorn[i].vel += gravity; uint32_t col = color_wheel(popcorn[i].colIndex); if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex); - uint16_t ledIndex = SEGMENT.start + popcorn[i].pos; - if(ledIndex >= SEGMENT.start && ledIndex < SEGMENT.stop) setPixelColor(ledIndex, col); + uint16_t ledIndex = popcorn[i].pos; + if (ledIndex < SEGLEN) setPixelColor(ledIndex, col); } else { // if kernel is inactive, randomly pop it - if(random8() < 2) { // POP!!! + if (random8() < 2) { // POP!!! popcorn[i].pos = 0.01f; uint16_t peakHeight = 128 + random8(128); //0-255 @@ -2607,7 +2616,7 @@ uint16_t WS2812FX::mode_candle() } SEGENV.aux0 = s; - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); } @@ -2747,7 +2756,7 @@ uint16_t WS2812FX::mode_starburst(void) { if (start == end) end++; if (end > SEGLEN) end = SEGLEN; for (int p = start; p < end; p++) { - setPixelColor(SEGMENT.start+p, c.r, c.g, c.b); + setPixelColor(p, c.r, c.g, c.b); } } } @@ -2795,7 +2804,7 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) // launch if (flare->vel > 12 * gravity) { // flare - setPixelColor(SEGMENT.start + int(flare->pos),flare->col,flare->col,flare->col); + setPixelColor(int(flare->pos),flare->col,flare->col,flare->col); flare->pos += flare->vel; flare->pos = constrain(flare->pos, 0, SEGLEN-1); @@ -2849,7 +2858,7 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) c.g = qsub8(c.g, cooling); c.b = qsub8(c.b, cooling * 2); } - setPixelColor(SEGMENT.start + int(sparks[i].pos), c.red, c.green, c.blue); + setPixelColor(int(sparks[i].pos), c.red, c.green, c.blue); } } dying_gravity *= .99; // as sparks burn out they fall slower diff --git a/wled00/FX.h b/wled00/FX.h index c08fe2f71..54ccd5031 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -59,7 +59,7 @@ #define SEGMENT _segments[_segment_index] #define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x]) #define SEGENV _segment_runtimes[_segment_index] -#define SEGLEN SEGMENT.length() +#define SEGLEN _virtualSegmentLength #define SEGACT SEGMENT.stop #define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN #define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes)) @@ -199,16 +199,15 @@ class WS2812FX { // segment parameters public: - typedef struct Segment { // 25 bytes + typedef struct Segment { // 24 bytes uint16_t start; uint16_t stop; //segment invalid if stop == 0 - uint16_t rawLength; uint8_t speed; uint8_t intensity; uint8_t palette; uint8_t mode; uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected - uint8_t group, spacing; + uint8_t grouping, spacing; uint8_t opacity; uint32_t colors[NUM_COLORS]; void setOption(uint8_t n, bool val) @@ -236,8 +235,14 @@ class WS2812FX { { return stop - start; } - uint16_t ledGroup() { - return group + spacing; + uint16_t groupLength() + { + return grouping + spacing; + } + uint16_t virtualLength() + { + uint16_t groupLen = groupLength(); + return (length() + groupLen -1) / groupLen; } } segment; @@ -381,7 +386,7 @@ class WS2812FX { } void - init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst), + init(bool supportWhite, uint16_t countPixels, bool skipFirst), service(void), blur(uint8_t), fade_out(uint8_t r), @@ -396,7 +401,7 @@ class WS2812FX { setShowCallback(show_callback cb), setTransitionMode(bool t), trigger(void), - setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0), resetSegments(), setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), @@ -416,8 +421,6 @@ class WS2812FX { paletteBlend = 0, colorOrder = 0, milliampsPerLed = 55, - _spacing = 0, - _group = 1, getBrightness(void), getMode(void), getSpeed(void), @@ -432,8 +435,7 @@ class WS2812FX { uint16_t ablMilliampsMax, currentMilliamps, - triwave16(uint16_t), - getUsableCount(); + triwave16(uint16_t); uint32_t timebase, @@ -564,7 +566,7 @@ class WS2812FX { CRGBPalette16 targetPalette; uint32_t now; - uint16_t _length; + uint16_t _length, _lengthRaw, _virtualSegmentLength; uint16_t _rand16seed; uint8_t _brightness; static uint16_t _usedSegmentData; @@ -610,14 +612,13 @@ class WS2812FX { uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; - segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 25 bytes per element - // start, stop, length, speed, intensity, palette, mode, options, group, spacing, opacity (unused), color[] - { 0, 7, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} + segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element + // start, stop, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[] + { 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} }; - segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element friend class Segment_runtime; - + uint16_t realPixelIndex(uint16_t i); }; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index fcfae088d..95b80eeb7 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -30,37 +30,29 @@ #define LED_SKIP_AMOUNT 1 #define MIN_SHOW_DELAY 15 -void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst) +void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { - if (supportWhite == _rgbwMode && countPixels == _length && disableNLeds == _disableNLeds) return; + if (supportWhite == _rgbwMode && countPixels == _length) return; RESET_RUNTIME; _rgbwMode = supportWhite; _skipFirstMode = skipFirst; _length = countPixels; - _group = group; - _spacing = spacing; uint8_t ty = 1; - if (supportWhite) ty =2; - uint16_t lengthRaw = _length + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); + if (supportWhite) ty = 2; + _lengthRaw = _length; + if (_skipFirstMode) { + _lengthRaw += LED_SKIP_AMOUNT; + } - bus->Begin((NeoPixelType)ty, lengthRaw); + bus->Begin((NeoPixelType)ty, _lengthRaw); _segments[0].start = 0; - - _segments[0].group = _group; - _segments[0].spacing = _spacing; - _segments[0].stop = getUsableCount(); - _segments[0].rawLength = _length; + _segments[0].stop = _length; setBrightness(_brightness); } -uint16_t WS2812FX::getUsableCount() { - uint16_t ledGroup = _group + _spacing; - return (_length + ledGroup -1) / ledGroup; -} - void WS2812FX::service() { uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days now = nowUp + timebase; @@ -73,6 +65,7 @@ void WS2812FX::service() { { if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary { + _virtualSegmentLength = SEGMENT.virtualLength(); doShow = true; handle_palette(); uint16_t delay = (this->*_mode[SEGMENT.mode])(); @@ -81,6 +74,7 @@ void WS2812FX::service() { } } } + _virtualSegmentLength = 0; if(doShow) { yield(); show(); @@ -97,82 +91,90 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { } uint16_t WS2812FX::realPixelIndex(uint16_t i) { - int16_t iGroup = (i - SEGMENT.start) * SEGMENT.ledGroup(); + int16_t iGroup = i * SEGMENT.groupLength(); - /* reverse just an individual segment */ - int16_t realIndex; - if IS_REVERSE - realIndex = SEGMENT.rawLength + SEGMENT.start - iGroup -1; - else - realIndex = SEGMENT.start + iGroup; - /* Reverse the whole string */ - if (reverseMode) realIndex = _length - 1 - realIndex; + /* reverse just an individual segment */ + int16_t realIndex = iGroup; + if (IS_REVERSE) realIndex = SEGMENT.length() -iGroup -1; - return realIndex; + realIndex += SEGMENT.start; + /* Reverse the whole string */ + if (reverseMode) realIndex = _length - 1 - realIndex; + + return realIndex; } void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { - - RgbwColor color; - color.W = w; - - switch (colorOrder) //0 = Grb, default + RgbwColor col; + switch (colorOrder) { - case 0: color.G = g; color.R = r; color.B = b; break; // 0 = GRB - case 1: color.G = r; color.R = g; color.B = b; break; // 1 = RGB, common for WS2811 - case 2: color.G = b; color.R = r; color.B = g; break; // 2 = BRG - case 3: color.G = r; color.R = b; color.B = g; break; // 3 = RBG + case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default + case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811 + case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG + case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG + case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR + default: col.G = g; col.R = b; col.B = r; break; //5 = GBR } + col.W = w; + if (!_cronixieMode) { - /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ - bool reversed = reverseMode ^ IS_REVERSE; - uint16_t realIndex = realPixelIndex(i); uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; - for (uint16_t l = 0; l < SEGMENT.ledGroup(); l++) { - int16_t indexSet = realIndex + (reversed ? -l : l); - if (indexSet >= SEGMENT.start && (indexSet < SEGMENT.start + SEGMENT.rawLength)) - bus->SetPixelColor(indexSet + skip, l < SEGMENT.group ? color : RgbwColor(0, 0, 0, 0)); - for (uint16_t l = 0; indexSet == 0 && l < skip; l++) {// Clear the skipped pixels - bus->SetPixelColor(l, RgbwColor(0, 0, 0, 0)); + if (SEGLEN) {//from segment + /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ + bool reversed = reverseMode ^ IS_REVERSE; + uint16_t realIndex = realPixelIndex(i); + for (uint16_t j = 0; j < SEGMENT.grouping; j++) { + int16_t indexSet = realIndex + (reversed ? -j : j); + if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) bus->SetPixelColor(indexSet + skip, col); + } + } else { //live data, etc. + if (reverseMode) i = _length - 1 - i; + bus->SetPixelColor(i + skip, col); + } + if (skip && i == 0) { + for (uint16_t j = 0; j < skip; j++) { + bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0)); } } - } else { - if(i>6)return; - byte o = 10*i; - if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) + return; + } + + //CRONIXIE + if(i>6)return; + byte o = 10*i; + if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) + { + byte r2 = _segments[0].colors[1] >>16; + byte g2 = _segments[0].colors[1] >> 8; + byte b2 = _segments[0].colors[1]; + byte w2 = _segments[0].colors[1] >>24; + for (int j=o; j< o+19; j++) { - byte r2 = _segments[0].colors[1] >>16; - byte g2 = _segments[0].colors[1] >> 8; - byte b2 = _segments[0].colors[1]; - byte w2 = _segments[0].colors[1] >>24; - for (int j=o; j< o+19; j++) - { - bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2)); - } - } else - { - for (int j=o; j< o+19; j++) - { - bus->SetPixelColor(j, RgbwColor(0,0,0,0)); - } + bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2)); } - if (_skipFirstMode) o += LED_SKIP_AMOUNT; - switch(_cronixieDigits[i]) + } else + { + for (int j=o; j< o+19; j++) { - case 0: bus->SetPixelColor(o+5, color); break; - case 1: bus->SetPixelColor(o+0, color); break; - case 2: bus->SetPixelColor(o+6, color); break; - case 3: bus->SetPixelColor(o+1, color); break; - case 4: bus->SetPixelColor(o+7, color); break; - case 5: bus->SetPixelColor(o+2, color); break; - case 6: bus->SetPixelColor(o+8, color); break; - case 7: bus->SetPixelColor(o+3, color); break; - case 8: bus->SetPixelColor(o+9, color); break; - case 9: bus->SetPixelColor(o+4, color); break; + bus->SetPixelColor(j, RgbwColor(0,0,0,0)); } } + if (_skipFirstMode) o += LED_SKIP_AMOUNT; + switch(_cronixieDigits[i]) + { + case 0: bus->SetPixelColor(o+5, col); break; + case 1: bus->SetPixelColor(o+0, col); break; + case 2: bus->SetPixelColor(o+6, col); break; + case 3: bus->SetPixelColor(o+1, col); break; + case 4: bus->SetPixelColor(o+7, col); break; + case 5: bus->SetPixelColor(o+2, col); break; + case 6: bus->SetPixelColor(o+8, col); break; + case 7: bus->SetPixelColor(o+3, col); break; + case 8: bus->SetPixelColor(o+9, col); break; + case 9: bus->SetPixelColor(o+4, col); break; + } } void WS2812FX::driverModeCronixie(bool b) @@ -387,6 +389,7 @@ uint32_t WS2812FX::getColor(void) { uint32_t WS2812FX::getPixelColor(uint16_t i) { i = realPixelIndex(i) + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); + if (_cronixieMode) { if(i>6)return 0; @@ -406,18 +409,20 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) default: return 0; } } - uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; - if (i >= (_length + skip)) return 0; - RgbwColor lColor = bus->GetPixelColorRgbw(i); - byte r = lColor.R, g = lColor.G, b = lColor.B; + if (i >= _lengthRaw) return 0; + + RgbwColor col = bus->GetPixelColorRgbw(i); switch (colorOrder) { - case 0: break; //0 = Grb - case 1: r = lColor.G; g = lColor.R; break; //1 = Rgb, common for WS2811 - case 2: g = lColor.B; b = lColor.G; break; //2 = Brg - case 3: r = lColor.B; g = lColor.R; b = lColor.G; //3 = Rbg + // W G R B + case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default + case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 + case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG + case 3: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //3 = RBG + case 4: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //4 = BGR + case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR } - return ( (lColor.W << 24) | (r << 16) | (g << 8) | (b) ); + return 0; } WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { @@ -437,26 +442,26 @@ uint32_t WS2812FX::getLastShow(void) { return _lastShow; } -void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing) { +void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) { if (n >= MAX_NUM_SEGMENTS) return; Segment& seg = _segments[n]; - if (seg.start == start && seg.rawLength == length && seg.group == group && seg.spacing == spacing) return; + //return if neither bounds nor grouping have changed + if (seg.start == i1 && seg.stop == i2 && (!grouping || (seg.grouping == grouping && seg.spacing == spacing))) return; - _segment_index = n; fill(0); //turn old segment range off - - seg.rawLength = min(_length - start, length); - seg.spacing = spacing; - seg.group = group; - seg.start = start; - uint16_t ledGroup = seg.ledGroup(); - seg.stop = (seg.rawLength - seg.start + ledGroup -1) / ledGroup + seg.start; - if (seg.start >= seg.stop) { - seg.stop = 0; + if (seg.stop) setRange(seg.start, seg.stop -1, 0); //turn old segment range off + if (i2 <= i1) //disable segment + { + seg.stop = 0; return; } - else { - _segment_runtimes[n].reset(); + if (i1 < _length) seg.start = i1; + seg.stop = i2; + if (i2 > _length) seg.stop = _length; + if (grouping) { + seg.grouping = grouping; + seg.spacing = spacing; } + _segment_runtimes[n].reset(); } void WS2812FX::resetSegments() { @@ -467,16 +472,13 @@ void WS2812FX::resetSegments() { _segments[0].colors[0] = DEFAULT_COLOR; _segments[0].start = 0; _segments[0].speed = DEFAULT_SPEED; - _segments[0].stop = getUsableCount(); - _segments[0].rawLength = _length; + _segments[0].stop = _length; + _segments[0].grouping = 1; _segments[0].setOption(0, 1); //select - - _segments[0].group = _group; - _segments[0].spacing = _spacing; - for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) { _segments[i].colors[0] = color_wheel(i*51); + _segments[i].grouping = 1; _segment_runtimes[i].reset(); } _segment_runtimes[0].reset(); @@ -536,7 +538,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 = 0; i < SEGLEN; i++) { setPixelColor(i, c); } } @@ -554,7 +556,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 = 0; i < SEGLEN; i++) { color = getPixelColor(i); int w1 = (color >> 24) & 0xff; int r1 = (color >> 16) & 0xff; @@ -584,14 +586,14 @@ 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 = 0; i < SEGLEN; i++) { CRGB cur = col_to_crgb(getPixelColor(i)); CRGB part = cur; part.nscale8(seep); cur.nscale8(keep); cur += carryover; - if(i > SEGMENT.start) { + if(i > 0) { uint32_t c = getPixelColor(i-1); uint8_t r = (c >> 16 & 0xFF); uint8_t g = (c >> 8 & 0xFF); @@ -756,7 +758,7 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8 { if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default uint8_t paletteIndex = i; - if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop-1,0,255); + if (mapping) paletteIndex = (i*255)/(SEGLEN -1); 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/wled19_json.ino b/wled00/wled19_json.ino index 5e7b461e1..5f36c58b4 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -8,12 +8,16 @@ void deserializeSegment(JsonObject elem, byte it) if (id < strip.getMaxSegments()) { WS2812FX::Segment& seg = strip.getSegment(id); - uint16_t start = elem.containsKey("start") ? elem["start"] : seg.start; - uint16_t len = elem.containsKey("len") ? elem["len"] : seg.rawLength; - uint8_t group = max(1, elem["grp"] | seg.group); - uint8_t spacing = elem.containsKey("spc") ? elem["spc"] : seg.spacing; + uint16_t start = elem["start"] | seg.start; + int stop = elem["stop"] | -1; - strip.setSegment(id, start, len, group, spacing); + if (stop < 0) { + uint16_t len = elem["len"]; + stop = (len > 0) ? start + len : seg.stop; + } + uint16_t grp = elem["grp"] | seg.grouping; + uint16_t spc = elem["spc"] | seg.spacing; + strip.setSegment(id, start, stop, grp, spc); JsonArray colarr = elem["col"]; if (!colarr.isNull()) @@ -163,7 +167,9 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["id"] = id; root["start"] = seg.start; root["stop"] = seg.stop; - root["len"] = seg.rawLength; + root["len"] = seg.stop - seg.start; + root["grp"] = seg.grouping; + root["spc"] = seg.spacing; JsonArray colarr = root.createNestedArray("col"); @@ -182,8 +188,6 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["ix"] = seg.intensity; root["pal"] = seg.palette; root["sel"] = seg.isSelected(); - root["grp"] = seg.group; - root["spc"] = seg.spacing; root["rev"] = seg.getOption(1); } @@ -257,7 +261,9 @@ void serializeInfo(JsonObject root) JsonObject wifi_info = root.createNestedObject("wifi"); wifi_info["bssid"] = WiFi.BSSIDstr(); - wifi_info["signal"] = getSignalQuality(WiFi.RSSI()); + int qrssi = WiFi.RSSI(); + wifi_info["rssi"] = qrssi; + wifi_info["signal"] = getSignalQuality(qrssi); wifi_info["channel"] = WiFi.channel(); #ifdef ARDUINO_ARCH_ESP32 @@ -357,7 +363,7 @@ void serveJson(AsyncWebServerRequest* request) void serveLiveLeds(AsyncWebServerRequest* request) { - byte used = strip.getUsableCount(); + byte used = ledCount; byte n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS char buffer[2000] = "{\"leds\":["; olen = 9; From 081a6888fa0d6cbc29cdfdc282f7e1377fe852f9 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 14 Jan 2020 10:59:57 +0100 Subject: [PATCH 6/7] Remove G and S options (only segment properties now) --- wled00/data/settings_leds.htm | Bin 7982 -> 16312 bytes wled00/html_settings.h | 7 +++---- wled00/wled00.ino | 4 +--- wled00/wled01_eeprom.ino | 6 ------ wled00/wled02_xml.ino | 2 -- wled00/wled03_set.ino | 6 ++---- wled00/wled05_init.ino | 7 +------ 7 files changed, 7 insertions(+), 25 deletions(-) diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index eb9774593584332f4a0e23e70d1617231e8f3041..450512b0270776388ca3f5133829d469be188177 100644 GIT binary patch literal 16312 zcmds;eNP<85yt!9jg;>&;dD0688G&7xnS%QZ|AdOUo3-tI-O1t7%;@Vg#`n#l8>I` z`E_k=chAhSyI?y}v;uZ!x~uE;sp{(C-~U<&zY8nj&tW;Nho8fXuo|kc8&1PP*bk4x zZ^LiGLd*4b*a%y_=aptGX#BQjZRqPjmrpX%wU_}|uQ&m_@`Xsqe# zRG&T3cq`r(!c4sKaYzbRU9EPaQO9~}ydoc;_fe`!>ps%Yk;a`xuHo#iR@=~=6Rq+- z@-!D7M(uS(bw?u)HJ;UxqzXTT$#AFt{6qg+CrWl0>7R#bjXsW2Pf9+la;ocYm>2Ie zk^(7rMSD{t(b0kKF6!<{ygJgIce>iv-Jg1Tn2GecJJZm}7g1wdvXfaZ>1sl}CTafB z=e8-=(lz9oX<6^CT5 z$2WYe*~+hSzhF)!+v6eAvJU>X8g+_q<0VVsGCbAO$#7fVvKgP<7C%^TS7YADUfX(Z zy3W^t;+ixuEeRI&8(-X)<+pn)PR14P=;}NDN&r+CF{I?4x{IDbvF*{R$n7bGs4QPa~4xyT>tGLE~w}o~yk1 zPSpB`i0kfu{`ZaOKm~7~*YA&`gPn+9(0wSHCE9XlGiK5a;bBu!I7?hT$oLwrJ4TO7 zf37e0DD=tuS|x{aa%ZfuDc-B-F`*W(KDlB z6sO}{Dn=?Tlh0P(iPVU+z1|G-EUp&xvmfoW7rxR5Ov}0Ms8WO9Uo`jEk+Rt+QFkIP zHzku{Z&^`{gQ_N9({eekV#!f>Li1bViT%J~tOwqXoWY^*5wTokwMvzF6=oI7e8!Q@ zQEgQI*_RyOnE&UEnhpN{plaqO{MYRtMFWwCQ_(q zw`Ff4ZL(*nN|9h*xJ)V?yD$c;??#g6MbDxNc$5#u3W#il5ubIo7TynPDI{wp1o7R zt^>RWd#Z^0Rd4^>ZOB!RBDbuqjpngdnZ_QyyQC9}SI=z+%5m(pu>Focrq!%(uFB zO*oc2fAqwf{V(f^`TpPgcO6CWiTvXz`bW<3lsZTos&0<7I^Oq1^qrjoy&1DvjCmkL ze9##4rWkWy-j(aMBPvspYxr8-VvN-dzKbd?v?;!~qCRt(hzL43Q<8<60L@-T>0U>D zZ|N>wOd{h4-Pwy&jhwmZ>i;$TYD#*>rP*ex-e z)wlGQ{wo%vqfO8ETya|I&YbRF6yN+#u7CGBs*PNy9&hM_-Z(oGdWX5kwP^~ja{3-Y zIqlBaa_3qzi%lyMu?1d>4(YXzvU1rOgce?q{D+PweRJQ{8^V1)y@S6V$6fLEci9>) z@nh_n$79`(zrAwARJ7r7q((hhQcL!pmR3QB<5+Ly_8t`fAoz}`=e%(?0{?!VfDH7L z&02Vrcb81V>9k}%eAAFMac9-4W%>UlZ=Ac9Hzr%xF*}c;H{pBvC_RAT82$M?HQ9s+ zI*usu|6q~NkFZI9zbGy)rAy8k52euqMGRQ~t1O>KVjeA3_*!EQvgmWmSgll6McgC4 z)7dCBtk)AD5BSGZ&M@t)DnGZhy8A%?E|NbIn?`Y<-35u@QY&qqmL6U7r&MH*;P;k=8q>`W6n--*&pF$3B&Jsxtd zZnB=8HL~84B!Y{!RR^!Y&T&)P14p5L7fJzeq}_sF)69`w?Q94nQz7gZVcG5u${*UdV?PX`}ruIbr1@V~dTkNBhB zAm9UypQAqUey>Q82@PA-K}}^`kr}}q?94t1ZmiG5UWlD1p1|H}TK2O&XT2)`7q2ve z-4q&N4mP4LWJT{qranUzk%pDL2V=2pv!Da|`0o0mH=5IW;%Zx+oY^{)MQ{%O<_n8V(b_s;08!PDr->0I!a$bKyUs$&D)7n+!YAD~NpO z!?ROA{o^AGRl*i$fYPzLfh zk=k;Htw2W%{X)Ud�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 JKizBb{{UG%Wp@Ao diff --git a/wled00/html_settings.h b/wled00/html_settings.h index e66c99020..25bed845f 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -123,6 +123,8 @@ Color order: + +

Defaults

Turn LEDs on after power up/reset:
@@ -150,10 +152,7 @@ Palette blending:
Reverse LED order (rotate 180):
-Skip first LED:
-LED spacing:
-(Turns off N LEDs between each lit one, spacing out effects)
-LED grouping:
+Skip first LED:
)====="; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 996b0a0a2..111304e55 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -98,7 +98,7 @@ //version code in format yymmddb (b = daily build) -#define VERSION 2001051 +#define VERSION 2001071 char versionString[] = "0.9.0-b2"; @@ -149,8 +149,6 @@ bool enableSecTransition = true; //also enable transition for secon uint16_t transitionDelay = 750; //default crossfade duration in ms bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -uint8_t spacing = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look) -uint8_t group = 1; //Group LEDs into one logical LED byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index da6ae783f..790ed1a46 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -230,9 +230,6 @@ void saveSettingsToEEPROM() saveCurrPresetCycConf = false; } - EEPROM.write(2213, spacing); - EEPROM.write(2214, group); - writeStringToEEPROM(2220, blynkApiKey, 35); for (int i = 0; i < 8; ++i) @@ -491,9 +488,6 @@ void loadSettingsFromEEPROM(bool first) presetApplyFx = EEPROM.read(2212); } - spacing = EEPROM.read(2213); - group = max(1, EEPROM.read(2214)); - bootPreset = EEPROM.read(389); wifiLock = EEPROM.read(393); utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index b758bbcfd..b7110dcbc 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -237,8 +237,6 @@ void getSettingsJS(byte subPage, char* dest) sappend('i',"PB",strip.paletteBlend); sappend('c',"RV",strip.reverseMode); sappend('c',"SL",skipFirstLed); - sappend('v',"SP",spacing); - sappend('v',"GR",group); } if (subPage == 3) diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 5504cc265..3db104258 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -104,8 +104,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (t >= 0 && t < 4) strip.paletteBlend = t; strip.reverseMode = request->hasArg("RV"); skipFirstLed = request->hasArg("SL"); - spacing = request->arg("SP").toInt(); - group = request->arg("GR").toInt(); t = request->arg("BF").toInt(); if (t > 0) briMultiplier = t; } @@ -291,7 +289,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage == 2) { - strip.init(useRGBW,ledCount,group,spacing,skipFirstLed); + strip.init(useRGBW,ledCount,skipFirstLed); } if (subPage == 4) alexaInit(); } @@ -392,7 +390,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) { stopI = getNumVal(&req, pos); } - strip.setSegment(main, startI, stopI, 1, 0); + strip.setSegment(main, startI, stopI); main = strip.getMainSegmentId(); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index f31383f29..0d113b46d 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -8,11 +8,6 @@ void wledInit() ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30; - spacing = EEPROM.read(2213); - //this was reading 255 after inital flash causing bootloop. Don't know why. - spacing = spacing!= 255 ? spacing : 0; - group = max(1, EEPROM.read(2214)); - #ifdef ESP8266 #if LEDPIN == 3 if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram @@ -31,7 +26,7 @@ void wledInit() DEBUG_PRINT("heap "); DEBUG_PRINTLN(ESP.getFreeHeap()); - strip.init(EEPROM.read(372),ledCount,group,spacing,EEPROM.read(2204)); //init LEDs quickly + strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly strip.setBrightness(0); DEBUG_PRINT("LEDs inited. heap usage ~"); From e99e9fed110d291149bc2112d7e4d6c41d120df5 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 14 Jan 2020 11:46:21 +0100 Subject: [PATCH 7/7] Remove unneccessary null checks --- wled00/FX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index b4defa744..653f323c1 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1048,8 +1048,8 @@ uint16_t WS2812FX::mode_fireworks() { SEGENV.aux0 = UINT16_MAX; SEGENV.aux1 = UINT16_MAX; } - bool valid1 = (SEGENV.aux0 < SEGLEN && SEGENV.aux0 >= 0); - bool valid2 = (SEGENV.aux1 < SEGLEN && SEGENV.aux1 >= 0); + bool valid1 = (SEGENV.aux0 < SEGLEN); + bool valid2 = (SEGENV.aux1 < SEGLEN); uint32_t sv1 = 0, sv2 = 0; if (valid1) sv1 = getPixelColor(SEGENV.aux0); if (valid2) sv2 = getPixelColor(SEGENV.aux1);