mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-31 14:37:49 +00:00
Merge pull request #6032 from s-hadinger/white_blend
Add blend RGB leds with White leds for better whites #5895 #5704
This commit is contained in:
commit
56383d3758
@ -1,4 +1,7 @@
|
|||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
* 6.6.0.1 20190707
|
||||||
|
* Add blend RGB leds with White leds for better whites #5895 #5704
|
||||||
|
*
|
||||||
* 6.6.0 20190707
|
* 6.6.0 20190707
|
||||||
* Remove support of TLS on core 2.3.0 and extent support on core 2.4.2 and up
|
* Remove support of TLS on core 2.3.0 and extent support on core 2.4.2 and up
|
||||||
* Remove MQTT uptime message every hour
|
* Remove MQTT uptime message every hour
|
||||||
|
@ -101,23 +101,27 @@
|
|||||||
*
|
*
|
||||||
* 3. In LightAnimate(), final PWM values are computed at next tick.
|
* 3. In LightAnimate(), final PWM values are computed at next tick.
|
||||||
* .a If color did not change since last tick - ignore.
|
* .a If color did not change since last tick - ignore.
|
||||||
* .b Apply color balance correction from rgbwwTable[]
|
* .b Extend resolution from 8 bits to 10 bits, which makes a significant
|
||||||
* .c Extend resolution from 8 bits to 10 bits, which makes a significant
|
|
||||||
* difference when applying gamma correction at low brightness.
|
* difference when applying gamma correction at low brightness.
|
||||||
* .d Apply Gamma Correction if LedTable==1 (by default).
|
* .c Apply Gamma Correction if LedTable==1 (by default).
|
||||||
* Gamma Correction uses an adaptative resolution table from 11 to 8 bits.
|
* Gamma Correction uses an adaptative resolution table from 11 to 8 bits.
|
||||||
* .e For Warm/Cold-white channels, Gamma correction is calculated in combined mode.
|
* .d For Warm/Cold-white channels, Gamma correction is calculated in combined mode.
|
||||||
* Ie. total white brightness (C+W) is used for Gamma correction and gives
|
* Ie. total white brightness (C+W) is used for Gamma correction and gives
|
||||||
* the overall light power required. Then this light power is split among
|
* the overall light power required. Then this light power is split among
|
||||||
* Wamr/Cold channels.
|
* Wamr/Cold channels.
|
||||||
* .f Gamma correction is still applied to 8 bits channels for compatibility
|
* .e Gamma correction is still applied to 8 bits channels for compatibility
|
||||||
* with other non-PMW modules.
|
* with other non-PMW modules.
|
||||||
* .g Avoid PMW values between 1008 and 1022, issue #1146
|
* .f Apply color balance correction from rgbwwTable[].
|
||||||
* .h Scale ranges from 10 bits to 0..PWMRange (by default 1023) so no change
|
* Note: correction is done after Gamma correction, it is meant
|
||||||
|
* to adjust leds with different power
|
||||||
|
* .g If rgbwwTable[4] is zero, blend RGB with White and adjust the level of
|
||||||
|
* White channel according to rgbwwTable[3]
|
||||||
|
* .h Avoid PMW values between 1008 and 1022, issue #1146
|
||||||
|
* .i Scale ranges from 10 bits to 0..PWMRange (by default 1023) so no change
|
||||||
* by default.
|
* by default.
|
||||||
* .i Apply port remapping from Option37
|
* .j Apply port remapping from Option37
|
||||||
* .j Invert PWM value if port is of type PMWxi instead of PMWx
|
* .k Invert PWM value if port is of type PMWxi instead of PMWx
|
||||||
* .k Apply PWM value with analogWrite() - if pin is configured
|
* .l Apply PWM value with analogWrite() - if pin is configured
|
||||||
*
|
*
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
@ -243,6 +247,10 @@ uint8_t light_fixed_color_index = 1;
|
|||||||
|
|
||||||
unsigned long strip_timer_counter = 0; // Bars and Gradient
|
unsigned long strip_timer_counter = 0; // Bars and Gradient
|
||||||
|
|
||||||
|
static uint32_t min3(uint32_t a, uint32_t b, uint32_t c) {
|
||||||
|
return (a < b && a < c) ? a : (b < c) ? b : c;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// changeUIntScale
|
// changeUIntScale
|
||||||
// Change a value for range a..b to c..d, using only unsigned int math
|
// Change a value for range a..b to c..d, using only unsigned int math
|
||||||
@ -1791,19 +1799,14 @@ void LightAnimate(void)
|
|||||||
uint16_t cur_col_10bits[LST_MAX]; // 10 bits version of cur_col for PWM
|
uint16_t cur_col_10bits[LST_MAX]; // 10 bits version of cur_col for PWM
|
||||||
light_update = 0;
|
light_update = 0;
|
||||||
|
|
||||||
// first adjust all colors to RgbwwTable if needed
|
// first set 8 and 10 bits channels
|
||||||
for (uint32_t i = 0; i < LST_MAX; i++) {
|
for (uint32_t i = 0; i < LST_MAX; i++) {
|
||||||
light_last_color[i] = light_new_color[i];
|
cur_col[i] = light_last_color[i] = light_new_color[i];
|
||||||
// adjust from 0.255 to 0..Settings.rgbwwTable[i] -- RgbwwTable command
|
|
||||||
// protect against overflow of rgbwwTable which is of size 5
|
|
||||||
cur_col[i] = changeUIntScale(light_last_color[i], 0, 255, 0, (i<5)? Settings.rgbwwTable[i] : 255);
|
|
||||||
// Extend from 8 to 10 bits if no correction (in case no gamma correction is required)
|
// Extend from 8 to 10 bits if no correction (in case no gamma correction is required)
|
||||||
cur_col_10bits[i] = changeUIntScale(cur_col[i], 0, 255, 0, 1023);
|
cur_col_10bits[i] = changeUIntScale(cur_col[i], 0, 255, 0, 1023);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (PHILIPS == my_module_type) {
|
if (PHILIPS == my_module_type) {
|
||||||
// TODO
|
|
||||||
// Xiaomi Philips bulbs follow a different scheme:
|
// Xiaomi Philips bulbs follow a different scheme:
|
||||||
// channel 0=intensity, channel2=temperature
|
// channel 0=intensity, channel2=temperature
|
||||||
uint16_t pxBri = cur_col[0] + cur_col[1];
|
uint16_t pxBri = cur_col[0] + cur_col[1];
|
||||||
@ -1815,14 +1818,10 @@ void LightAnimate(void)
|
|||||||
} else {
|
} else {
|
||||||
cur_col_10bits[0] = changeUIntScale(pxBri, 0, 255, 0, 1023); // no gamma, extend to 10 bits
|
cur_col_10bits[0] = changeUIntScale(pxBri, 0, 255, 0, 1023); // no gamma, extend to 10 bits
|
||||||
}
|
}
|
||||||
} else {
|
} else { // PHILIPS != my_module_type
|
||||||
// Apply gamma correction for 8 and 10 bits resolutions, if needed
|
// Apply gamma correction for 8 and 10 bits resolutions, if needed
|
||||||
if (Settings.light_correction) {
|
if (Settings.light_correction) {
|
||||||
// first apply gamma correction to all channels independently, from 8 bits value
|
// First apply combined correction to the overall white power
|
||||||
for (uint32_t i = 0; i < LST_MAX; i++) {
|
|
||||||
cur_col_10bits[i] = ledGamma(cur_col[i], 10);
|
|
||||||
}
|
|
||||||
// then apply a different correction for CW white channels
|
|
||||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||||
uint8_t w_idx[2] = {0, 1}; // if LST_COLDWARM, channels 0 and 1
|
uint8_t w_idx[2] = {0, 1}; // if LST_COLDWARM, channels 0 and 1
|
||||||
if (LST_RGBWC == light_subtype) { // if LST_RGBWC, channels 3 and 4
|
if (LST_RGBWC == light_subtype) { // if LST_RGBWC, channels 3 and 4
|
||||||
@ -1834,14 +1833,57 @@ void LightAnimate(void)
|
|||||||
if (white_bri <= 255) {
|
if (white_bri <= 255) {
|
||||||
// we calculate the gamma corrected sum of CW + WW
|
// we calculate the gamma corrected sum of CW + WW
|
||||||
uint16_t white_bri_10bits = ledGamma(white_bri, 10);
|
uint16_t white_bri_10bits = ledGamma(white_bri, 10);
|
||||||
|
uint8_t white_bri_8bits = ledGamma(white_bri);
|
||||||
// then we split the total energy among the cold and warm leds
|
// then we split the total energy among the cold and warm leds
|
||||||
cur_col_10bits[w_idx[0]] = changeUIntScale(cur_col[w_idx[0]], 0, white_bri, 0, white_bri_10bits);
|
cur_col_10bits[w_idx[0]] = changeUIntScale(cur_col[w_idx[0]], 0, white_bri, 0, white_bri_10bits);
|
||||||
cur_col_10bits[w_idx[1]] = changeUIntScale(cur_col[w_idx[1]], 0, white_bri, 0, white_bri_10bits);
|
cur_col_10bits[w_idx[1]] = changeUIntScale(cur_col[w_idx[1]], 0, white_bri, 0, white_bri_10bits);
|
||||||
|
cur_col[w_idx[0]] = changeUIntScale(cur_col[w_idx[0]], 0, white_bri, 0, white_bri_8bits);
|
||||||
|
cur_col[w_idx[1]] = changeUIntScale(cur_col[w_idx[1]], 0, white_bri, 0, white_bri_8bits);
|
||||||
|
} else {
|
||||||
|
cur_col_10bits[w_idx[0]] = ledGamma(cur_col[w_idx[0]], 10);
|
||||||
|
cur_col_10bits[w_idx[1]] = ledGamma(cur_col[w_idx[1]], 10);
|
||||||
|
cur_col[w_idx[0]] = ledGamma(cur_col[w_idx[0]]);
|
||||||
|
cur_col[w_idx[1]] = ledGamma(cur_col[w_idx[1]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// still keep an 8 bits gamma corrected version
|
// then apply gamma correction to RGB channels
|
||||||
for (uint32_t i = 0; i < LST_MAX; i++) {
|
if (LST_RGB <= light_subtype) {
|
||||||
cur_col[i] = ledGamma(cur_col[i]);
|
for (uint32_t i = 0; i < 3; i++) {
|
||||||
|
cur_col_10bits[i] = ledGamma(cur_col[i], 10);
|
||||||
|
cur_col[i] = ledGamma(cur_col[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If RGBW or Single channel, also adjust White channel
|
||||||
|
if (LST_COLDWARM != light_subtype) {
|
||||||
|
cur_col_10bits[3] = ledGamma(cur_col[3], 10);
|
||||||
|
cur_col[3] = ledGamma(cur_col[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now see if we need to mix RGB and True White
|
||||||
|
// Valid only for LST_RGBW, LST_RGBWC, rgbwwTable[4] is zero, and white is zero (see doc)
|
||||||
|
if ((LST_RGBW <= light_subtype) && (0 == Settings.rgbwwTable[4]) && (0 == cur_col[3]+cur_col[4])) {
|
||||||
|
uint32_t min_rgb_10 = min3(cur_col_10bits[0], cur_col_10bits[1], cur_col_10bits[2]);
|
||||||
|
uint8_t min_rgb = min3(cur_col[0], cur_col[1], cur_col[2]);
|
||||||
|
for (uint32_t i=0; i<3; i++) {
|
||||||
|
// substract white and adjust according to rgbwwTable
|
||||||
|
cur_col_10bits[i] = changeUIntScale(cur_col_10bits[i] - min_rgb_10, 0, 255, 0, Settings.rgbwwTable[i]);
|
||||||
|
cur_col[i] = changeUIntScale(cur_col[i] - min_rgb, 0, 255, 0, Settings.rgbwwTable[i]);
|
||||||
|
}
|
||||||
|
// compute the adjusted white levels for 10 and 8 bits
|
||||||
|
uint32_t white_10 = changeUIntScale(min_rgb_10, 0, 255, 0, Settings.rgbwwTable[3]); // set white power down corrected with rgbwwTable[3]
|
||||||
|
uint32_t white = changeUIntScale(min_rgb, 0, 255, 0, Settings.rgbwwTable[3]); // set white power down corrected with rgbwwTable[3]
|
||||||
|
if (LST_RGBW == light_subtype) {
|
||||||
|
// we simply set the white channel
|
||||||
|
cur_col_10bits[3] = white_10;
|
||||||
|
cur_col[3] = white;
|
||||||
|
} else { // LST_RGBWC
|
||||||
|
// we distribute white between cold and warm according to CT value
|
||||||
|
uint32_t ct = light_state.getCT();
|
||||||
|
cur_col_10bits[4] = changeUIntScale(ct, 153, 500, 0, white_10);
|
||||||
|
cur_col_10bits[3] = white_10 - cur_col_10bits[4];
|
||||||
|
cur_col[4] = changeUIntScale(ct, 153, 500, 0, white);
|
||||||
|
cur_col[3] = white - cur_col[4];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1873,7 +1915,7 @@ void LightAnimate(void)
|
|||||||
if (light_type < LT_PWM6) { // only for direct PWM lights, not for Tuya, Armtronix...
|
if (light_type < LT_PWM6) { // only for direct PWM lights, not for Tuya, Armtronix...
|
||||||
for (uint32_t i = 0; i < light_subtype; i++) {
|
for (uint32_t i = 0; i < light_subtype; i++) {
|
||||||
if (pin[GPIO_PWM1 +i] < 99) {
|
if (pin[GPIO_PWM1 +i] < 99) {
|
||||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d, Pwm%d %d"), i, cur_col[i], i+1, curcol);
|
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d, Pwm%d %d"), i, cur_col_10bits[i], i+1, cur_col[i]);
|
||||||
analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col_10bits[i] : cur_col_10bits[i]);
|
analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col_10bits[i] : cur_col_10bits[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1906,6 +1948,7 @@ void LightAnimate(void)
|
|||||||
}
|
}
|
||||||
#endif // ifdef USE_SM16716
|
#endif // ifdef USE_SM16716
|
||||||
else if (light_type > LT_WS2812) {
|
else if (light_type > LT_WS2812) {
|
||||||
|
//AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Cur_Col %d,%d,%d,%d,%d"), cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
|
||||||
LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
|
LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
|
||||||
}
|
}
|
||||||
XdrvMailbox.data = tmp_data;
|
XdrvMailbox.data = tmp_data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user