Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix interaction of SO92, VirtualCT, and RGBWWTable #18768

Merged
merged 5 commits into from
Jun 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 25 additions & 29 deletions tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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]);
Expand Down Expand Up @@ -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
Expand Down