diff --git a/wled00/FX.h b/wled00/FX.h index 01453265e..0413a41e9 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -364,6 +364,7 @@ class WS2812FX { reverseMode = false, gammaCorrectBri = false, gammaCorrectCol = true, + segmentsAreIdentical(Segment* a, Segment* b), setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p); uint8_t @@ -379,14 +380,15 @@ class WS2812FX { getModeCount(void), getPaletteCount(void), getMaxSegments(void), - getFirstSelectedSegment(void), + //getFirstSelectedSegment(void), getMainSegmentId(void), gamma8(uint8_t), get_random_wheel_index(uint8_t); uint16_t ablMilliampsMax, - currentMilliamps; + currentMilliamps, + getUsableCount(); uint32_t timebase, diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index d4018a5d8..ff66b7115 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -105,18 +105,18 @@ bool WS2812FX::modeUsesLock(uint8_t m) } void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { - uint8_t w = (c >> 24) & 0xFF; - uint8_t r = (c >> 16) & 0xFF; - uint8_t g = (c >> 8) & 0xFF; - uint8_t b = c & 0xFF; + uint8_t w = (c >> 24); + uint8_t r = (c >> 16); + uint8_t g = (c >> 8); + uint8_t b = c ; setPixelColor(n, r, g, b, w); } void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { - uint16_t actualPixelLocation = i * (_disableNLeds+1); + i = i * (_disableNLeds+1); if (_locked[i] && !_modeUsesLock) return; - if (IS_REVERSE) actualPixelLocation = SEGMENT.stop -1 -actualPixelLocation + SEGMENT.start; //reverse just individual segment + if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment byte tmpg = g; switch (colorOrder) //0 = Grb, default { @@ -127,16 +127,16 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } if (!_cronixieMode) { - if (reverseMode) actualPixelLocation = _length -1 -actualPixelLocation; + if (reverseMode) i = _length -1 -i; if (_skipFirstMode) { - if (actualPixelLocation < LED_SKIP_AMOUNT) bus->SetPixelColor(actualPixelLocation, RgbwColor(0,0,0,0)); - actualPixelLocation += LED_SKIP_AMOUNT; + if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0)); + i += LED_SKIP_AMOUNT; } - if (actualPixelLocation < _lengthRaw) bus->SetPixelColor(actualPixelLocation, RgbwColor(r,g,b,w)); + if (i < _lengthRaw) bus->SetPixelColor(i, RgbwColor(r,g,b,w)); if (_disableNLeds > 0) { for(uint16_t offCount=0; offCount < _disableNLeds; offCount++) { - if (actualPixelLocation < _lengthRaw) bus->SetPixelColor((actualPixelLocation+offCount+1), RgbwColor(0,0,0,0)); + if (i < _lengthRaw) bus->SetPixelColor((i + offCount + 1), RgbwColor(0,0,0,0)); } } } else { @@ -144,10 +144,10 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) byte o = 10*i; if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) { - byte r2 = (_segments[0].colors[1] >>16) & 0xFF; - byte g2 = (_segments[0].colors[1] >> 8) & 0xFF; - byte b2 = (_segments[0].colors[1] ) & 0xFF; - byte w2 = (_segments[0].colors[1] >>24) & 0xFF; + 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)); @@ -385,7 +385,7 @@ uint8_t WS2812FX::getMaxSegments(void) { return MAX_NUM_SEGMENTS; } -uint8_t WS2812FX::getFirstSelectedSegment(void) +/*uint8_t WS2812FX::getFirstSelectedSegment(void) { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { @@ -396,13 +396,10 @@ uint8_t WS2812FX::getFirstSelectedSegment(void) if (_segments[i].isActive()) return i; } return 0; -} +}*/ uint8_t WS2812FX::getMainSegmentId(void) { - if (mainSegment >= MAX_NUM_SEGMENTS || !_segments[mainSegment].isActive()) - { - return getFirstSelectedSegment(); - } + if (mainSegment >= MAX_NUM_SEGMENTS) return 0; return mainSegment; } @@ -461,6 +458,10 @@ WS2812FX::Segment* WS2812FX::getSegments(void) { return _segments; } +uint16_t WS2812FX::getUsableCount(void) { + return _usableCount; +} + uint32_t WS2812FX::getLastShow(void) { return _lastShow; } @@ -811,6 +812,22 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8 return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b; } +bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b) +{ + //if (a->start != b->start) return false; + //if (a->stop != b->stop) return false; + for (uint8_t i = 0; i < NUM_COLORS; i++) + { + if (a->colors[i] != b->colors[i]) return false; + } + if (a->mode != b->mode) return false; + if (a->speed != b->speed) return false; + if (a->intensity != b->intensity) return false; + if (a->palette != b->palette) return false; + //if (a->getOption(1) != b->getOption(1)) return false; //reverse + return true; +} + //gamma 2.4 lookup table used for color correction const byte gammaT[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/wled00/wled00.ino b/wled00/wled00.ino index edcd2e98f..df9d35824 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -99,7 +99,7 @@ //version code in format yymmddb (b = daily build) -#define VERSION 1911302 +#define VERSION 1912011 char versionString[] = "0.8.7-dev"; @@ -422,6 +422,8 @@ char* obuf; uint16_t olen = 0; uint16_t savedPresets = 0; +int8_t currentPreset = -1; +bool isPreset = false; byte errorFlag = 0; diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index ba6df0c72..d60256413 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -600,6 +600,8 @@ bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool load effectIntensity = EEPROM.read(i+16); effectPalette = EEPROM.read(i+17); } + currentPreset = index; + isPreset = true; return true; } @@ -621,6 +623,8 @@ void savePreset(byte index) EEPROM.write(i+16, effectIntensity); EEPROM.write(i+17, effectPalette); commit(); + currentPreset = index; + isPreset = true; } diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index f2e11cabf..60af19fa4 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -77,8 +77,9 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest } else { oappend(serverDescription); } - - oappend(""); + oappend(""); + oappendi(strip.getMainSegmentId()); + oappend(""); if (includeTheme) { char cs[6][9]; diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index ce2fafc75..2782de16e 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -383,6 +383,27 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) //if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise } + //segment select (sets main segment) + pos = req.indexOf("SS="); + if (pos > 0) { + strip.mainSegment = getNumVal(&req, pos); + } + byte main = strip.getMainSegmentId(); + + uint16_t startI = strip.getSegment(main).start; + uint16_t stopI = strip.getSegment(main).stop; + pos = req.indexOf("S="); //segment start + if (pos > 0) { + startI = getNumVal(&req, pos); + } + pos = req.indexOf("S2="); //segment stop + if (pos > 0) { + stopI = getNumVal(&req, pos); + } + strip.setSegment(main, startI, stopI); + + main = strip.getMainSegmentId(); + //set brightness updateVal(&req, "&A=", &bri); @@ -606,7 +627,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) //Segment reverse pos = req.indexOf("RV="); - if (pos > 0) strip.getSegment(0).setOption(1, req.charAt(pos+3) != '0'); + if (pos > 0) strip.getSegment(main).setOption(1, req.charAt(pos+3) != '0'); //deactivate nightlight if target brightness is reached if (bri == nightlightTargetBri) nightlightActive = false; diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index d5c8cd7c8..226c59985 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -31,7 +31,7 @@ void deserializeSegment(JsonObject elem, byte it) byte cp = copyArray(colX, rgbw); seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))); if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0; - if (id == 0) //temporary + if (id == strip.getMainSegmentId()) //temporary { if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];} if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];} @@ -45,10 +45,10 @@ void deserializeSegment(JsonObject elem, byte it) seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse //int cln = seg_0["cln"]; //temporary, strip object gets updated via colorUpdated() - if (id == 0) { + if (id == strip.getMainSegmentId()) { effectCurrent = elem["fx"] | effectCurrent; effectSpeed = elem["sx"] | effectSpeed; - effectIntensity = elem["ix"] | effectIntensity ; + effectIntensity = elem["ix"] | effectIntensity; effectPalette = elem["pal"] | effectPalette; } else { //permanent byte fx = elem["fx"] | seg.mode; @@ -104,6 +104,8 @@ bool deserializeState(JsonObject root) int timein = root["time"] | -1; if (timein != -1) setTime(timein); + strip.mainSegment = root["mainseg"] | strip.mainSegment; + int it = 0; JsonVariant segVar = root["seg"]; if (segVar.is()) @@ -175,7 +177,8 @@ void serializeState(JsonObject root) root["bri"] = briLast; root["transition"] = transitionDelay/100; //in 100ms - root["ps"] = -1; // + root["ps"] = currentPreset; + root["pss"] = savedPresets; root["pl"] = (presetCyclingEnabled) ? 0: -1; JsonObject nl = root.createNestedObject("nl"); @@ -187,6 +190,8 @@ void serializeState(JsonObject root) JsonObject udpn = root.createNestedObject("udpn"); udpn["send"] = notifyDirect; udpn["recv"] = receiveNotifications; + + root["mainseg"] = strip.getMainSegmentId(); JsonArray seg = root.createNestedArray("seg"); for (byte s = 0; s < strip.getMaxSegments(); s++) @@ -214,6 +219,7 @@ void serializeInfo(JsonObject root) leds["pwr"] = strip.currentMilliamps; leds["maxpwr"] = strip.ablMilliampsMax; leds["maxseg"] = strip.getMaxSegments(); + leds["seglock"] = false; //will be used in the future to prevent modifications to segment config root["name"] = serverDescription; root["udpport"] = udpPort; @@ -323,12 +329,13 @@ void serveJson(AsyncWebServerRequest* request) void serveLiveLeds(AsyncWebServerRequest* request) { - byte n = (ledCount -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS + byte used = strip.getUsableCount(); + 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; obuf = buffer; - for (uint16_t i= 0; i < ledCount; i += n) + for (uint16_t i= 0; i < used; i += n) { olen += sprintf(buffer + olen, "\"%06X\",", strip.getPixelColor(i)); }