diff --git a/wled00/FX.h b/wled00/FX.h index 5683b452c..c75e730b8 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -247,36 +247,44 @@ class WS2812FX { // segment parameters public: - typedef struct Segment { // 31 (32 in memory) bytes + typedef struct Segment { // 30 (32 in memory) bytes uint16_t start; uint16_t stop; //segment invalid if stop == 0 uint16_t offset; - uint8_t speed; - uint8_t intensity; - uint8_t palette; - uint8_t mode; - uint8_t options; //bit pattern: msb first: transitional needspixelstate tbd tbd (paused) on reverse selected - uint8_t grouping, spacing; - uint8_t opacity; + uint8_t speed; + uint8_t intensity; + uint8_t palette; + uint8_t mode; + uint8_t options; //bit pattern: msb first: transitional needspixelstate tbd tbd (paused) on reverse selected + uint8_t grouping, spacing; + uint8_t opacity; uint32_t colors[NUM_COLORS]; - uint16_t cct; //0==1900K, 255==10091K, or Kelvin value >=1900 + uint8_t cct; //0==1900K, 255==10091K char *name; bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false; if (c == colors[slot]) return false; - ColorTransition::startTransition(opacity, colors[slot], instance->_transitionDur, segn, slot); + uint8_t b = (slot == 1) ? cct : opacity; + ColorTransition::startTransition(b, colors[slot], instance->_transitionDur, segn, slot); colors[slot] = c; return true; } + void setCCT(uint16_t k, uint8_t segn) { + if (segn >= MAX_NUM_SEGMENTS) return; + if (k > 255) { //kelvin value, convert to 0-255 + if (k < 1900) k = 1900; + if (k > 10091) k = 10091; + k = (k - 1900) >> 5; + } + if (cct == k) return; + ColorTransition::startTransition(cct, colors[1], instance->_transitionDur, segn, 1); + cct = k; + } void setOpacity(uint8_t o, uint8_t segn) { if (segn >= MAX_NUM_SEGMENTS) return; if (opacity == o) return; ColorTransition::startTransition(opacity, colors[0], instance->_transitionDur, segn, 0); opacity = o; } - /*uint8_t actualOpacity() { //respects On/Off state - if (!getOption(SEG_OPTION_ON)) return 0; - return opacity; - }*/ void setOption(uint8_t n, bool val, uint8_t segn = 255) { bool prevOn = false; @@ -446,7 +454,7 @@ class WS2812FX { if (t.segment == s) //this is an active transition on the same segment+color { bool wasTurningOff = (oldBri == 0); - t.briOld = t.currentBri(wasTurningOff); + t.briOld = t.currentBri(wasTurningOff, slot); t.colorOld = t.currentColor(oldCol); } else { t.briOld = oldBri; @@ -478,11 +486,15 @@ class WS2812FX { uint32_t currentColor(uint32_t colorNew) { return instance->color_blend(colorOld, colorNew, progress(true), true); } - uint8_t currentBri(bool turningOff = false) { + uint8_t currentBri(bool turningOff = false, uint8_t slot = 0) { uint8_t segn = segment & 0x3F; if (segn >= MAX_NUM_SEGMENTS) return 0; uint8_t briNew = instance->_segments[segn].opacity; - if (!instance->_segments[segn].getOption(SEG_OPTION_ON) || turningOff) briNew = 0; + if (slot == 0) { + if (!instance->_segments[segn].getOption(SEG_OPTION_ON) || turningOff) briNew = 0; + } else { //transition slot 1 brightness for CCT transition + briNew = instance->_segments[segn].cct; + } uint32_t prog = progress() + 1; return ((briNew * prog) + (briOld * (0x10000 - prog))) >> 16; } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e590554d9..a6a407f01 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -138,15 +138,17 @@ void WS2812FX::service() { if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen _virtualSegmentLength = SEGMENT.virtualLength(); - if (!cctFromRgb || correctWB) busses.setSegmentCCT(SEGMENT.cct, correctWB); _bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2]; + uint8_t _cct_t = SEGMENT.cct; if (!IS_SEGMENT_ON) _bri_t = 0; for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) { if ((transitions[t].segment & 0x3F) != i) continue; uint8_t slot = transitions[t].segment >> 6; if (slot == 0) _bri_t = transitions[t].currentBri(); + if (slot == 1) _cct_t = transitions[t].currentBri(false, 1); _colors_t[slot] = transitions[t].currentColor(SEGMENT.colors[slot]); } + if (!cctFromRgb || correctWB) busses.setSegmentCCT(_cct_t, correctWB); for (uint8_t c = 0; c < 3; c++) _colors_t[c] = gamma32(_colors_t[c]); handle_palette(); delay = (this->*_mode[SEGMENT.mode])(); //effect function diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index af15d6953..6adce9330 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -560,11 +560,8 @@ class BusManager { } void setSegmentCCT(int16_t cct, bool allowWBCorrection = false) { - if (cct > 255) { //kelvin value, convert to 0-255 - if (cct < 1900) cct = 1900; - if (cct > 10091) cct = 10091; - if (!allowWBCorrection) cct = (cct - 1900) >> 5; - } else if (cct > -1) { + if (cct > 255) cct = 255; + if (cct >= 0) { //if white balance correction allowed, save as kelvin value instead of 0-255 if (allowWBCorrection) cct = 1900 + (cct << 5); } else cct = -1; diff --git a/wled00/json.cpp b/wled00/json.cpp index 324f658ac..67684d594 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -86,7 +86,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) if (elem["on"].is() && elem["on"].as()[0] == 't') on = !on; seg.setOption(SEG_OPTION_ON, on, id); - seg.cct = elem["cct"] | seg.cct; + seg.setCCT(elem["cct"] | seg.cct, id); JsonArray colarr = elem["col"]; if (!colarr.isNull())