From f1afa9636ec83ee239177cdc72f76e7783aa7520 Mon Sep 17 00:00:00 2001 From: openshwprojects Date: Tue, 13 Dec 2022 18:33:53 +0100 Subject: [PATCH] support for led with 4 pwms - RGBW - cool emulation by rgb --- src/cmnds/cmd_newLEDDriver.c | 35 +++++++++++++++++++++++++++++++---- src/httpserver/http_fns.c | 6 +++++- src/new_pins.h | 3 ++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/cmnds/cmd_newLEDDriver.c b/src/cmnds/cmd_newLEDDriver.c index 46c7dd8ab..0dc536335 100644 --- a/src/cmnds/cmd_newLEDDriver.c +++ b/src/cmnds/cmd_newLEDDriver.c @@ -191,6 +191,7 @@ void LED_RunQuickColorLerp(int deltaMS) { float deltaSeconds; byte finalRGBCW[5]; int maxPossibleIndexToSet; + int emulatedCool = -1; if (CFG_HasFlag(OBK_FLAG_LED_FORCE_MODE_RGB)) { // only allow setting pwm 0, 1 and 2, force-skip 3 and 4 @@ -200,6 +201,7 @@ void LED_RunQuickColorLerp(int deltaMS) { maxPossibleIndexToSet = 5; } + deltaSeconds = deltaMS * 0.001f; // The color order is RGBCW. @@ -210,6 +212,9 @@ void LED_RunQuickColorLerp(int deltaMS) { } else { firstChannelIndex = 1; } + if (CFG_HasFlag(OBK_FLAG_LED_EMULATE_COOL_WITH_RGB)) { + emulatedCool = firstChannelIndex + 3; + } for(i = 0; i < 5; i++) { // This is the most silly and primitive approach, but it works @@ -242,7 +247,16 @@ void LED_RunQuickColorLerp(int deltaMS) { // This also could work for a SINGLE COLOR strips for(i = 0; i < maxPossibleIndexToSet; i++) { finalRGBCW[i] = led_rawLerpCurrent[i]; - CHANNEL_Set(firstChannelIndex + i, led_rawLerpCurrent[i] * g_cfg_colorScaleToChannel, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + float chVal = led_rawLerpCurrent[i] * g_cfg_colorScaleToChannel; + int channelToUse = firstChannelIndex + i; + if (channelToUse == emulatedCool && g_lightMode == Light_Temperature) { + CHANNEL_Set(firstChannelIndex + 0, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(firstChannelIndex + 1, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(firstChannelIndex + 2, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + } + else { + CHANNEL_Set(channelToUse, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + } } } } @@ -264,6 +278,7 @@ void apply_smart_light() { int channelToUse; byte finalRGBCW[5]; int maxPossibleIndexToSet; + int emulatedCool = -1; // The color order is RGBCW. // some people set RED to channel 0, and some of them set RED to channel 1 @@ -274,6 +289,10 @@ void apply_smart_light() { firstChannelIndex = 1; } + if (CFG_HasFlag(OBK_FLAG_LED_EMULATE_COOL_WITH_RGB)) { + emulatedCool = firstChannelIndex + 3; + } + if (CFG_HasFlag(OBK_FLAG_LED_FORCE_MODE_RGB)) { // only allow setting pwm 0, 1 and 2, force-skip 3 and 4 maxPossibleIndexToSet = 3; @@ -339,18 +358,26 @@ void apply_smart_light() { //ADDLOG_INFO(LOG_FEATURE_CMD, "apply_smart_light: ch %i raw is %f, bright %f, final %f, enableAll is %i", // channelToUse,raw,g_brightness,final,g_lightEnableAll); + float chVal = final * g_cfg_colorScaleToChannel; if(CFG_HasFlag(OBK_FLAG_LED_SMOOTH_TRANSITIONS) == false) { if(isCWMode()) { // in CW mode, we have only set two channels // We don't have RGB channels // so, do simple mapping if(i == 3) { - CHANNEL_Set(firstChannelIndex+0, final * g_cfg_colorScaleToChannel, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(firstChannelIndex+0, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); } else if(i == 4) { - CHANNEL_Set(firstChannelIndex+1, final * g_cfg_colorScaleToChannel, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(firstChannelIndex+1, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); } } else { - CHANNEL_Set(channelToUse, final * g_cfg_colorScaleToChannel, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + if (channelToUse == emulatedCool && g_lightMode == Light_Temperature) { + CHANNEL_Set(firstChannelIndex + 0, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(firstChannelIndex + 1, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(firstChannelIndex + 2, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + } + else { + CHANNEL_Set(channelToUse, chVal, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT); + } } } } diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index 6881ccc43..cb2b4ed4a 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -683,7 +683,7 @@ int http_fn_index(http_request_t* request) { hprintf255(request, ""); poststr(request, ""); } - if (c_pwms == 2 || c_pwms == 5) { + if (c_pwms == 2 || c_pwms >= 4) { // TODO: temperature slider int pwmValue; const char* inputName; @@ -2455,6 +2455,10 @@ const char* g_obk_flagNames[] = { "[MQTT] Retain power channels (Relay channels, etc)", "[IR] Do MQTT publish (Tasmota JSON format) for incoming IR data", "[LED] Automatically enable Light on any change of brightness, color or temperature", + "[LED] Emulate Cool White with RGB in device with four PWMS - Red is 0, Green 1, Blue 2, and Warm is 4", + "error", + "error", + "error", "error", "error", }; diff --git a/src/new_pins.h b/src/new_pins.h index 541e06e93..a09ba8404 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -173,9 +173,10 @@ typedef struct pinsState_s { #define OBK_FLAG_MQTT_RETAIN_POWER_CHANNELS 21 #define OBK_FLAG_IR_PUBLISH_RECEIVED_IN_JSON 22 #define OBK_FLAG_LED_AUTOENABLE_ON_ANY_ACTION 23 +#define OBK_FLAG_LED_EMULATE_COOL_WITH_RGB 24 -#define OBK_TOTAL_FLAGS 24 +#define OBK_TOTAL_FLAGS 25 #define CGF_MQTT_CLIENT_ID_SIZE 64