diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino index f79e7da82e72..f5e48f1741ee 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino @@ -1911,21 +1911,14 @@ void LightAnimate(void) cur_col_10[i] = change8to10(Light.new_color[i]); } - bool rgbwwtable_applied_white = false; // did we already applied RGBWWTable to white channels (ex: in white_blend_mode or virtual_ct) if (Light.pwm_multi_channels) { calcGammaMultiChannels(cur_col_10); } else { // AddLog(LOG_LEVEL_INFO, PSTR(">>> calcGammaBulbs In %03X,%03X,%03X,%03X,%03X"), cur_col_10[0], cur_col_10[1], cur_col_10[2], cur_col_10[3], cur_col_10[4]); - rgbwwtable_applied_white = calcGammaBulbs(cur_col_10); // true means that one PWM channel is used for CT + calcGammaBulbs(cur_col_10); // AddLog(LOG_LEVEL_INFO, PSTR(">>> calcGammaBulbs Out %03X,%03X,%03X,%03X,%03X"), cur_col_10[0], cur_col_10[1], cur_col_10[2], cur_col_10[3], cur_col_10[4]); } - // Apply RGBWWTable only if not Settings->flag4.white_blend_mode - for (uint32_t i = 0; i < (rgbwwtable_applied_white ? 3 : Light.subtype); i++) { - uint32_t adjust = change8to10(Settings->rgbwwTable[i]); - cur_col_10[i] = changeUIntScale(cur_col_10[i], 0, 1023, 0, adjust); - } - // final adjusments for PMW ranges, post-gamma correction for (uint32_t i = 0; i < LST_MAX; i++) { // scale from 0..1023 to 0..pwm_range, but keep any non-zero value to at least 1 @@ -2320,9 +2313,8 @@ void calcGammaBulb5Channels_8(uint8_t in8[LST_MAX], uint16_t col10[LST_MAX]) { calcGammaBulb5Channels(col10, nullptr, nullptr); } -bool calcGammaBulbs(uint16_t cur_col_10[5]) { +void calcGammaBulbs(uint16_t cur_col_10[5]) { bool rgbwwtable_applied_white = false; - bool pwm_ct = false; bool white_free_cw = false; // true if White channels are uncorrelated. Happens when CW+WW>255, i.e. manually setting white channels to exceed to total power of a single channel (may harm the power supply) // Various values needed for accurate White calculation // CT value streteched to 0..1023 (from within CT range, so not necessarily from 153 to 500). 0=Cold, 1023=Warm @@ -2340,24 +2332,7 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) { calcGammaBulbCW(cur_col_10, &white_bri10, &white_free_cw); } - // Now we know ct_10 and white_bri10 (gamma corrected if needed) - - if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) { -#ifdef ESP8266 - if ((PHILIPS == TasmotaGlobal.module_type) || (Settings->flag4.pwm_ct_mode)) { // channel 1 is the color tone, mapped to cold channel (0..255) -#else - if (Settings->flag4.pwm_ct_mode) { // channel 1 is the color tone, mapped to cold channel (0..255) -#endif // ESP8266 - pwm_ct = true; - // Xiaomi Philips bulbs follow a different scheme: - // channel 0=intensity, channel1=temperature - cur_col_10[cw0] = white_bri10; - cur_col_10[cw0+1] = ct_10; - return false; // avoid any interference - } - } - - // Now see if we need to mix RGB and White + // Now see if we need to mix RGB and White // Valid only for LST_RGBW, LST_RGBCW, SetOption105 1, and white is zero (see doc) if ((LST_RGBW <= Light.subtype) && (Settings->flag4.white_blend_mode) && (0 == cur_col_10[3]+cur_col_10[4])) { uint32_t min_rgb_10 = min3(cur_col_10[0], cur_col_10[1], cur_col_10[2]); @@ -2421,7 +2396,28 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) { cur_col_10[cw0] = white_bri10 - cur_col_10[cw0+1]; } } - return rgbwwtable_applied_white; + + // Apply RGBWWTable (RGB: always, CW: only if white_blend_mode is not engaged) + for (uint32_t i = 0; i < (rgbwwtable_applied_white ? 3 : Light.subtype); i++) { + uint32_t adjust = change8to10(Settings->rgbwwTable[i]); + cur_col_10[i] = changeUIntScale(cur_col_10[i], 0, 1023, 0, adjust); + } + + // Implement SO92: Some lights like Xiaomi Philips bulbs follow the scheme + // cw0=intensity, cw0+1=temperature + if (ChannelCT() >= 0) { + // Need to compute white_bri10 and ct_10 from cur_col_10[] for compatibility with VirtualCT + white_bri10 = cur_col_10[cw0] + cur_col_10[cw0+1]; + ct_10 = changeUIntScale(cur_col_10[cw0+1], 0, white_bri10, 0, 1023); + if (white_bri10 > 1023) { + // In white_free_cw mode, the combined brightness of cw and ww may be larger than 1023. + // This cannot be represented in pwm_ct_mode, so we set the maximum brightness instead. + white_bri10 = 1023; + } + + cur_col_10[cw0] = white_bri10; + cur_col_10[cw0+1] = ct_10; + } } #ifdef USE_DEVICE_GROUPS