diff --git a/wled00/FX.h b/wled00/FX.h index 669d03660..5683b452c 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -259,7 +259,7 @@ class WS2812FX { uint8_t grouping, spacing; uint8_t opacity; uint32_t colors[NUM_COLORS]; - int16_t cct; //-1==auto (no RGB balance correction), 0==1900K, 255==10091K + uint16_t cct; //0==1900K, 255==10091K, or Kelvin value >=1900 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; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index eb7f7b5d5..e590554d9 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -138,7 +138,7 @@ void WS2812FX::service() { if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen _virtualSegmentLength = SEGMENT.virtualLength(); - busses.setSegmentCCT(SEGMENT.cct, correctWB); + 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]; if (!IS_SEGMENT_ON) _bri_t = 0; for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) { @@ -605,7 +605,7 @@ void WS2812FX::resetSegments() { _segments[0].setOption(SEG_OPTION_SELECTED, 1); _segments[0].setOption(SEG_OPTION_ON, 1); _segments[0].opacity = 255; - _segments[0].cct = -1; + _segments[0].cct = 127; for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) { @@ -613,7 +613,7 @@ void WS2812FX::resetSegments() { _segments[i].grouping = 1; _segments[i].setOption(SEG_OPTION_ON, 1); _segments[i].opacity = 255; - _segments[i].cct = -1; + _segments[i].cct = 127; _segments[i].speed = DEFAULT_SPEED; _segments[i].intensity = DEFAULT_INTENSITY; _segment_runtimes[i].reset(); diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 8539a486f..faeab4db6 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -81,6 +81,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); uint8_t rgbwMode = hw_led[F("rgbwm")] | RGBW_MODE_DUAL; // use global setting (legacy) CJSON(correctWB, hw_led["cct"]); + CJSON(cctFromRgb, hw_led[F("cr")]); JsonArray ins = hw_led["ins"]; @@ -521,6 +522,7 @@ void serializeConfig() { hw_led[F("maxpwr")] = strip.ablMilliampsMax; hw_led[F("ledma")] = strip.milliampsPerLed; hw_led["cct"] = correctWB; + hw_led[F("cr")] = cctFromRgb; JsonArray hw_led_ins = hw_led.createNestedArray("ins"); diff --git a/wled00/data/index.css b/wled00/data/index.css index 45a979309..a7588ddbc 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -471,7 +471,9 @@ img { #rwrap .sliderdisplay { --bg: #f00; } #gwrap .sliderdisplay { --bg: #0f0; } #bwrap .sliderdisplay { --bg: #00f; } -#wbal .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #cbdbff); } +#wbal .sliderdisplay, #kwrap .sliderdisplay { + background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #cbdbff); +} .sliderbubble { width: 36px; @@ -534,7 +536,7 @@ input[type=range]:active + .sliderbubble { display: inline; transform: translateX(-50%); } -#wwrap { +#wwrap, #wbal { display: none; } diff --git a/wled00/data/index.htm b/wled00/data/index.htm index a98d17136..25787aa34 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -47,13 +47,13 @@
- +

-
+
- +
@@ -79,6 +79,13 @@
+
+

White balance

+
+ +
+
+
diff --git a/wled00/data/index.js b/wled00/data/index.js index ebbe5dfe5..959d198bf 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -4,7 +4,6 @@ var noNewSegs = false; var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true, isRgbw = false; var whites = [0,0,0]; var selColors; -var mcct = false; //manual CCT (if false, CCT from RGB) var expanded = [false]; var powered = [true]; var nlDur = 60, nlTar = 0; @@ -70,6 +69,7 @@ function applyCfg() d.getElementById('hexw').style.display = ccfg.hex ? "block":"none"; d.getElementById('picker').style.display = ccfg.picker ? "block":"none"; d.getElementById('vwrap').style.display = ccfg.picker ? "block":"none"; + d.getElementById('kwrap').style.display = ccfg.picker ? "block":"none"; d.getElementById('rgbwrap').style.display = ccfg.rgb ? "block":"none"; d.getElementById('qcs-w').style.display = ccfg.quick ? "block":"none"; var l = cfg.comp.labels; @@ -922,8 +922,9 @@ function updateUI() updateTrail(d.getElementById('sliderBri')); updateTrail(d.getElementById('sliderSpeed')); updateTrail(d.getElementById('sliderIntensity')); - //updateTrail(d.getElementById('sliderW')); d.getElementById('wwrap').style.display = (isRgbw) ? "block":"none"; + d.getElementById('wbal').style.display = (lastinfo.leds.cct) ? "block":"none"; + d.getElementById('kwrap').style.display = (lastinfo.leds.cct) ? "none":"block"; updatePA(); //updateHex(); @@ -1006,7 +1007,7 @@ function readState(s,command=false) { selectSlot(csel); } //d.getElementById('sliderW').value = whites[csel]; - if (mcct & i.cct && i.cct>=0) d.getElementById("sliderA").value = i.cct; + if (i.cct != null && i.cct>=0) d.getElementById("sliderA").value = i.cct; d.getElementById('sliderSpeed').value = i.sx; d.getElementById('sliderIntensity').value = i.ix; @@ -1154,9 +1155,6 @@ function requestJson(command, rinfo = true) { } d.title = name; isRgbw = info.leds.wv; - mcct = info.leds.cct; - let wsld = d.getElementById("wbal"); - if (mcct) wsld.parentNode.insertBefore(wsld,d.getElementById('qcs-w')); ledCount = info.leds.count; syncTglRecv = info.str; maxSeg = info.leds.maxseg; @@ -1742,7 +1740,7 @@ function updatePSliders() { var cs = 'rgb('+c.r+','+c.g+','+c.b+')'; v.parentNode.getElementsByClassName('sliderdisplay')[0].style.setProperty('--bg',cs); updateTrail(v); - if (!mcct) d.getElementById('sliderA').value = cpick.color.kelvin; + d.getElementById('sliderK').value = cpick.color.kelvin; } function updateRgb() @@ -1789,9 +1787,9 @@ function fromV() cpick.color.setChannel('hsv', 'v', d.getElementById('sliderV').value); } -function fromA() +function fromK() { - if (!mcct) cpick.color.set({ kelvin: d.getElementById('sliderA').value }); + cpick.color.set({ kelvin: d.getElementById('sliderK').value }); } function fromRgb() @@ -1822,7 +1820,6 @@ function setColor(sr) { function setBalance(b) { - if (!mcct) {setColor(0); return;} var obj = {"seg": {"cct": parseInt(b)}}; requestJson(obj); } diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index b141b4d0f..582a4aefd 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -511,7 +511,7 @@ ${i+1}: Make a segment for each output:
Custom bus start indices:
White Balance correction:
- Calculate CCT from RGB: TODO
+ Calculate CCT from RGB:
CCT blending mode: TODO

diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 9cd514e8a..1bc13bc41 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -118,22 +118,22 @@ id="wreason">800 LEDs per output for the best experience!

Make a segment for each output:
Custom bus start indices:
White Balance correction:
Calculate CCT from RGB: TODO
-CCT blending mode: TODO

-Touch threshold:
IR GPIO: - ×
IR info
-Relay GPIO: Invert
Calculate CCT from RGB:
CCT blending mode: TODO

+
Touch threshold:
IR GPIO:  ×
+IR info +
Relay GPIO: Invert  ×

Defaults

Turn LEDs on after power up/reset:
Default brightness: = 1900) cct = (cct - 1900) >> 5; //convert K to 0-255 + if (cct > 255) cct = 255; + root["cct"] = cct; if (segmentBounds && seg.name != nullptr) root["n"] = reinterpret_cast(seg.name); //not good practice, but decreases required JSON buffer @@ -512,7 +515,7 @@ void serializeInfo(JsonObject root) switch (bus->getType()) { case TYPE_ANALOG_5CH: case TYPE_ANALOG_2CH: - leds["cct"] = true; + if (!cctFromRgb) leds["cct"] = true; break; } switch (bus->getAutoWhiteMode()) { diff --git a/wled00/set.cpp b/wled00/set.cpp index 8e513a6aa..ff659cd97 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -96,6 +96,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) autoSegments = request->hasArg(F("MS")); correctWB = request->hasArg(F("CCT")); + cctFromRgb = request->hasArg(F("CR")); for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) { char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin diff --git a/wled00/wled.h b/wled00/wled.h index 8e3047830..2127622e7 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -269,7 +269,8 @@ WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load //if false, only one segment spanning the total LEDs is created, //but not on LED settings save if there is more than one segment currently WLED_GLOBAL bool autoSegments _INIT(false); -WLED_GLOBAL bool correctWB _INIT(false); //CCT color correction +WLED_GLOBAL bool correctWB _INIT(false); //CCT color correction of RGB color +WLED_GLOBAL bool cctFromRgb _INIT(true); //CCT is calculated from RGB instead of using seg.cct WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color. WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 929b712db..ba0767be7 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -371,6 +371,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('c',SET_F("MS"),autoSegments); sappend('c',SET_F("CCT"),correctWB); + sappend('c',SET_F("CR"),cctFromRgb); for (uint8_t s=0; s < busses.getNumBusses(); s++) { Bus* bus = busses.getBus(s);