diff --git a/CHANGELOG.md b/CHANGELOG.md index 27f8564d..1626051d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ### Development versions after 0.9.1 release +#### Build 2004230 + +- Added brightness and power for individual segments +- Added `on` and `bri` properties to Segment object in JSON API +- Added `C3` an `SB` commands to HTTP get API +- Merged pull request #865 for 5CH_Shojo_PCB environment + #### Build 2004220 - Added Candle Multi effect diff --git a/wled00/FX.cpp b/wled00/FX.cpp index c03db766..a23a33f6 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -35,7 +35,7 @@ */ uint16_t WS2812FX::mode_static(void) { fill(SEGCOLOR(0)); - return (SEGMENT.getOption(7)) ? FRAMETIME : 500; //update faster if in transition + return (SEGMENT.getOption(SEG_OPTION_TRANSITIONAL)) ? FRAMETIME : 500; //update faster if in transition } diff --git a/wled00/FX.h b/wled00/FX.h index 41f7793c..7022fede 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -84,16 +84,19 @@ // options // bit 7: segment is in transition mode -// bits 2-6: TBD +// bits 3-6: TBD +// bit 2: segment is on // bit 1: reverse segment // bit 0: segment is selected #define NO_OPTIONS (uint8_t)0x00 #define TRANSITIONAL (uint8_t)0x80 +#define SEGMENT_ON (uint8_t)0x04 #define REVERSE (uint8_t)0x02 #define SELECTED (uint8_t)0x01 #define IS_TRANSITIONAL ((SEGMENT.options & TRANSITIONAL) == TRANSITIONAL) -#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) -#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED ) +#define IS_SEGMENT_ON ((SEGMENT.options & SEGMENT_ON ) == SEGMENT_ON ) +#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) +#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED ) #define MODE_COUNT 103 diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 3614db49..c6d8987b 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -146,11 +146,23 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) default: col.G = g; col.R = b; col.B = r; break; //5 = GBR } col.W = w; - - //color_blend(BLACK, (uint32_t)col, SEGMENT.opacity); uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; if (SEGLEN) {//from segment + + //color_blend(getpixel, col, SEGMENT.opacity); (pseudocode for future blending of segments) + if (IS_SEGMENT_ON) + { + if (SEGMENT.opacity < 255) { + col.R = scale8(col.R, SEGMENT.opacity); + col.G = scale8(col.G, SEGMENT.opacity); + col.B = scale8(col.B, SEGMENT.opacity); + col.W = scale8(col.W, SEGMENT.opacity); + } + } else { + col = BLACK; + } + /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ bool reversed = reverseMode ^ IS_REVERSE; uint16_t realIndex = realPixelIndex(i); @@ -484,10 +496,15 @@ void WS2812FX::resetSegments() { _segments[0].stop = _length; _segments[0].grouping = 1; _segments[0].setOption(0, 1); //select + _segments[0].setOption(2, 1); //on + _segments[0].opacity = 255; + for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) { _segments[i].colors[0] = color_wheel(i*51); _segments[i].grouping = 1; + _segments[i].setOption(2, 1); //on + _segments[i].opacity = 255; _segment_runtimes[i].reset(); } _segment_runtimes[0].reset(); diff --git a/wled00/const.h b/wled00/const.h index 5cd4b02f..17604378 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -77,6 +77,12 @@ #define HUE_ERROR_TIMEOUT 251 #define HUE_ERROR_ACTIVE 255 +//Segment option byte bits +#define SEG_OPTION_SELECTED 0 +#define SEG_OPTION_REVERSED 1 +#define SEG_OPTION_ON 2 +#define SEG_OPTION_TRANSITIONAL 7 + //EEPROM size #define EEPSIZE 2560 //Maximum is 4096 diff --git a/wled00/json.cpp b/wled00/json.cpp index 31208bf5..72d60738 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -20,6 +20,16 @@ void deserializeSegment(JsonObject elem, byte it) uint16_t grp = elem["grp"] | seg.grouping; uint16_t spc = elem["spc"] | seg.spacing; strip.setSegment(id, start, stop, grp, spc); + + int segbri = elem["bri"] | -1; + if (segbri == 0) { + seg.setOption(SEG_OPTION_ON, 0); + } else if (segbri > 0) { + seg.opacity = segbri; + seg.setOption(SEG_OPTION_ON, 1); + } + + seg.setOption(SEG_OPTION_ON, elem["on"] | seg.getOption(SEG_OPTION_ON)); JsonArray colarr = elem["col"]; if (!colarr.isNull()) @@ -47,9 +57,9 @@ void deserializeSegment(JsonObject elem, byte it) } //if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal); - seg.setOption(0, elem["sel"] | seg.getOption(0)); //selected - seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse - //int cln = seg_0["cln"]; + seg.setOption(SEG_OPTION_SELECTED, elem["sel"] | seg.getOption(SEG_OPTION_SELECTED)); + seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED)); + //temporary, strip object gets updated via colorUpdated() if (id == strip.getMainSegmentId()) { effectCurrent = elem["fx"] | effectCurrent; @@ -177,6 +187,9 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["len"] = seg.stop - seg.start; root["grp"] = seg.grouping; root["spc"] = seg.spacing; + root["on"] = seg.getOption(SEG_OPTION_ON); + byte segbri = seg.opacity; + root["bri"] = (segbri) ? segbri : 255; JsonArray colarr = root.createNestedArray("col"); @@ -204,7 +217,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["ix"] = seg.intensity; root["pal"] = seg.palette; root["sel"] = seg.isSelected(); - root["rev"] = seg.getOption(1); + root["rev"] = seg.getOption(SEG_OPTION_REVERSED); } diff --git a/wled00/set.cpp b/wled00/set.cpp index b568dff2..18ca71e7 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -513,6 +513,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) { colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str()); } + pos = req.indexOf("C3="); + if (pos > 0) { + byte t[4]; + colorFromDecOrHexString(t, (char*)req.substring(pos + 3).c_str()); + strip.setColor(2, t[0], t[1], t[2], t[3]); + } //set to random hue SR=0->1st SR=1->2nd pos = req.indexOf("SR"); @@ -626,7 +632,17 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) //Segment reverse pos = req.indexOf("RV="); - if (pos > 0) strip.getSegment(main).setOption(1, req.charAt(pos+3) != '0'); + if (pos > 0) strip.getSegment(main).setOption(SEG_OPTION_REVERSED, req.charAt(pos+3) != '0'); + + //Segment brightness/opacity + pos = req.indexOf("SB="); + if (pos > 0) { + byte segbri = getNumVal(&req, pos); + strip.getSegment(main).setOption(SEG_OPTION_ON, segbri); + if (segbri) { + strip.getSegment(main).opacity = segbri; + } + } //deactivate nightlight if target brightness is reached if (bri == nightlightTargetBri) nightlightActive = false; diff --git a/wled00/wled.h b/wled00/wled.h index 0e64930a..64210d42 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2004220 +#define VERSION 2004230 // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 2bf7eeff..807d3a44 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -611,8 +611,10 @@ bool applyPreset(byte index, bool loadBri) } if (index > 16 || index < 1) return false; uint16_t i = 380 + index*20; + byte ver = EEPROM.read(i); + if (index < 16) { - if (EEPROM.read(i) != 1) return false; + if (ver != 1) return false; strip.applyToAllSelected = true; if (loadBri) bri = EEPROM.read(i+1); @@ -628,11 +630,18 @@ bool applyPreset(byte index, bool loadBri) effectIntensity = EEPROM.read(i+16); effectPalette = EEPROM.read(i+17); } else { - if (EEPROM.read(i) != 2) return false; + if (ver != 2 && ver != 3) return false; strip.applyToAllSelected = false; if (loadBri) bri = EEPROM.read(i+1); WS2812FX::Segment* seg = strip.getSegments(); memcpy(seg, EEPROM.getDataPtr() +i+2, 240); + if (ver == 2) { //versions before 2004230 did not have opacity + for (byte j = 0; j < strip.getMaxSegments(); j++) + { + strip.getSegment(j).opacity = 255; + strip.getSegment(j).setOption(SEG_OPTION_ON, 1); + } + } setValuesFromMainSeg(); } currentPreset = index; @@ -666,7 +675,7 @@ void savePreset(byte index, bool persist) EEPROM.write(i+16, effectIntensity); EEPROM.write(i+17, effectPalette); } else { //segment 16 can save segments - EEPROM.write(i, 2); + EEPROM.write(i, 3); EEPROM.write(i+1, bri); WS2812FX::Segment* seg = strip.getSegments(); memcpy(EEPROM.getDataPtr() +i+2, seg, 240);