From a305f435e80934f3cc56b9094eec6ff4b45f1cbb Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 15:15:39 +1000 Subject: [PATCH 1/9] First pass at led pwm settings * Added settings for ledpwm_on and ledpwm_off with defaults that mimic current digitalwrite function * Changed ledpoweridx from digitalwrite to analogwrite * Add commands to change new settings --- tasmota/i18n.h | 4 ++++ tasmota/settings.h | 4 +++- tasmota/settings.ino | 9 +++++++++ tasmota/support_command.ino | 28 ++++++++++++++++++++++++++-- tasmota/support_tasmota.ino | 8 +++++++- 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index e8286e585..18c073d0d 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -586,6 +586,10 @@ // Commands xsns_02_analog.ino #define D_CMND_ADCPARAM "AdcParam" +// Commands led pwm settings +#define D_CMND_SETLEDPWMOFF "SetLedPwmOff" +#define D_CMND_SETLEDPWMON "SetLedPwmOn" + /********************************************************************************************/ // Log message prefix diff --git a/tasmota/settings.h b/tasmota/settings.h index edd3de523..11546fea3 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -569,8 +569,10 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E + uint16_t ledpwm_on; // F3F + uint16_t ledpwm_off; // F41 - uint8_t free_f3f[121]; // F3F - Decrement if adding new Setting variables just above and below + uint8_t free_f42[117]; // F42 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 5214add7a..7a6a27ac3 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1055,6 +1055,10 @@ void SettingsDefaultSet2(void) Settings.flag2 = flag2; Settings.flag3 = flag3; Settings.flag4 = flag4; + + // Led PWM + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 1023; } /********************************************************************************************/ @@ -1419,4 +1423,9 @@ void SettingsDelta(void) Settings.version = VERSION; SettingsSave(1); } + // ledpwm + if (Settings.version < 0x080300002) { + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 1023; + } } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index f262b5fcb..5adcc708f 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" + D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -50,7 +50,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, + &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -1890,3 +1890,27 @@ void CmndDriver(void) { XdrvCall(FUNC_COMMAND_DRIVER); } + +void CmndSetLedPwmOff(void) +{ + if ((XdrvMailbox.payload < 0) { + Settings.ledpwm_off = 0; + } else if (XdrvMailbox.payload > Settings.pwm_range) { + Settings.ledpwm_off = Settings.pwm_range; + } else { + Settings.ledpwm_off = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings.ledpwm_off); +} + +void CmndSetLedPwmOn(void) +{ + if ((XdrvMailbox.payload < 0) { + Settings.ledpwm_on = 0; + } else if (XdrvMailbox.payload > Settings.pwm_range) { + Settings.ledpwm_on = Settings.pwm_range; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings.ledpwm_on); +} \ No newline at end of file diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 90df92a37..65d842686 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -351,7 +351,13 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_power &= (0xFF ^ mask); } - DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); + uint16_t led_pwm_set = 0; + if (bitRead(led_inverted, led)) { + led_pwm_set = state ? Settings.pwm_range - Settings.ledpwm_on : Settings.pwm_range - Settings.ledpwm_off; + } else { + led_pwm_set = state ? Settings.ledpwm_on : Settings.ledpwm_off; + } + analogWrite(led, led_pwm_set) } #ifdef USE_BUZZER if (led == 0) { From ce2696fef0066ee303423d89a40a0614d90df9a4 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 15:44:19 +1000 Subject: [PATCH 2/9] Fix compile errors Missing brackets and semicolons of course. Blame python. --- tasmota/support_command.ino | 6 +++--- tasmota/support_tasmota.ino | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 5adcc708f..b48723575 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1893,7 +1893,7 @@ void CmndDriver(void) void CmndSetLedPwmOff(void) { - if ((XdrvMailbox.payload < 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_off = Settings.pwm_range; @@ -1905,7 +1905,7 @@ void CmndSetLedPwmOff(void) void CmndSetLedPwmOn(void) { - if ((XdrvMailbox.payload < 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_on = Settings.pwm_range; @@ -1913,4 +1913,4 @@ void CmndSetLedPwmOn(void) Settings.ledpwm_on = XdrvMailbox.payload; } ResponseCmndNumber(Settings.ledpwm_on); -} \ No newline at end of file +} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 65d842686..2508566ea 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -357,7 +357,7 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_pwm_set = state ? Settings.ledpwm_on : Settings.ledpwm_off; } - analogWrite(led, led_pwm_set) + analogWrite(led, led_pwm_set); } #ifdef USE_BUZZER if (led == 0) { From bd33574ee7c4a50de1fa97c03c964148edff8fe5 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 16:38:21 +1000 Subject: [PATCH 3/9] Align new settings to 2B boundaries Attempting to fix settings not working correctly (might have mucked up the boundaries and compiler put a padding byte in). --- tasmota/settings.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 11546fea3..10c28a2ca 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -569,12 +569,12 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E - uint16_t ledpwm_on; // F3F - uint16_t ledpwm_off; // F41 - uint8_t free_f42[117]; // F42 - Decrement if adding new Setting variables just above and below + uint8_t free_f3f[117]; // F3F - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below + uint16_t ledpwm_on; // FB4 + uint16_t ledpwm_off; // FB6 uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA uint32_t keeloq_master_msb; // FBC From fb179c27aff44b90e037469dc7b2521fb6dae2db Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 21:43:11 +1000 Subject: [PATCH 4/9] Fixes * Setting commands don't update if no data is sent * Didn't understand how pin mapping worked duh. Fixed. --- tasmota/support_command.ino | 21 ++++++++++++--------- tasmota/support_tasmota.ino | 14 +++++++++++--- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b48723575..b5ce6d074 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1893,24 +1893,27 @@ void CmndDriver(void) void CmndSetLedPwmOff(void) { - if (XdrvMailbox.payload < 0) { + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { + } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_off = Settings.pwm_range; - } else { - Settings.ledpwm_off = XdrvMailbox.payload; - } + } else { + Settings.ledpwm_off = XdrvMailbox.payload; + } ResponseCmndNumber(Settings.ledpwm_off); } void CmndSetLedPwmOn(void) { - if (XdrvMailbox.payload < 0) { + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { + } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_on = Settings.pwm_range; - } else { - Settings.ledpwm_on = XdrvMailbox.payload; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } } ResponseCmndNumber(Settings.ledpwm_on); } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 2508566ea..ba4b0fb1d 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -353,11 +353,19 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } uint16_t led_pwm_set = 0; if (bitRead(led_inverted, led)) { - led_pwm_set = state ? Settings.pwm_range - Settings.ledpwm_on : Settings.pwm_range - Settings.ledpwm_off; + if (state) { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; + } else { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; + } } else { - led_pwm_set = state ? Settings.ledpwm_on : Settings.ledpwm_off; + if (state) { + led_pwm_set = Settings.ledpwm_on; + } else { + led_pwm_set = Settings.ledpwm_off; + } } - analogWrite(led, led_pwm_set); + analogWrite(Pin(GPIO_LED1, led), led_pwm_set); } #ifdef USE_BUZZER if (led == 0) { From bea58f223fb68e42b300356663487f10cef37f40 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 22:01:40 +1000 Subject: [PATCH 5/9] Oops Compile error. Forgot bracket. --- tasmota/support_command.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b5ce6d074..263f5f713 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1901,6 +1901,7 @@ void CmndSetLedPwmOff(void) } else { Settings.ledpwm_off = XdrvMailbox.payload; } + } ResponseCmndNumber(Settings.ledpwm_off); } From e21cbfdc5d96a9acd3943b30a53d5f7492a13b7b Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 11:25:32 +1000 Subject: [PATCH 6/9] More sensible behaviour * When setting PWM values, updates all the LEDs (instant response). Uses led_power values. * If LEDLINK not set, but LED1 is, LED1 is the status led. When turning on/off, setledlink uses digitalwrite (which does not respect the new pwm operation). In this case only, we will use the setledpoweridx instead of digitalwrite - costly (every 250ms this runs), but edge case / legacy. Allows more intuitive operation - if we blink an LED with the max and min PWM limits, we'd expect it to respect these. In this case, blink will also now update the led_power status, which keeps this accurate e.g. if ledpower 1 cmnd was sent, then blink occurred, led_state would read a 1 for that bit but the led would be off (but nothing was reading it for status so it didn't cause any trouble). Leaving digitalwrite when LEDLINK is defined as this is more efficient and the use case for pwm leds is to find buttons - link indicator would become more ambiguous for no benefit. --- tasmota/support_command.ino | 2 ++ tasmota/support_tasmota.ino | 13 +++++++++---- tasmota/tasmota.ino | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 263f5f713..314097235 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1901,6 +1901,7 @@ void CmndSetLedPwmOff(void) } else { Settings.ledpwm_off = XdrvMailbox.payload; } + UpdateLedPowerAll(); } ResponseCmndNumber(Settings.ledpwm_off); } @@ -1915,6 +1916,7 @@ void CmndSetLedPwmOn(void) } else { Settings.ledpwm_on = XdrvMailbox.payload; } + UpdateLedPowerAll(); } ResponseCmndNumber(Settings.ledpwm_on); } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index ba4b0fb1d..5a28b76d6 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -336,6 +336,13 @@ void SetPowerOnState(void) blink_powersave = power; } +void UpdateLedPowerAll() +{ + for (uint32_t i = 0; i < leds_present; i++) { + SetLedPowerIdx(i, bitRead(led_power, i)); + } +} + void SetLedPowerIdx(uint32_t led, uint32_t state) { if (!PinUsed(GPIO_LEDLNK) && (0 == led)) { // Legacy - LED1 is link led only if LED2 is present @@ -400,10 +407,8 @@ void SetLedLink(uint32_t state) uint32_t led_pin = Pin(GPIO_LEDLNK); uint32_t led_inv = ledlnk_inverted; if (99 == led_pin) { // Legacy - LED1 is status - led_pin = Pin(GPIO_LED1); - led_inv = bitRead(led_inverted, 0); - } - if (led_pin < 99) { + SetLedPowerIdx(0, state); + } else if (led_pin < 99) { if (state) { state = 1; } digitalWrite(led_pin, (led_inv) ? !state : state); } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index ecf1127ec..92e3169b2 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -1,4 +1,4 @@ -/* + /* tasmota.ino - Tasmota firmware for iTead Sonoff, Wemos and NodeMCU hardware Copyright (C) 2020 Theo Arends From 603b628f97cf41f1bdaf0285377cdc0274497f47 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 12:13:05 +1000 Subject: [PATCH 7/9] Add pwm mode masking * Extra setting & command to set - allows masking of pwm mode. Use case is for leds attached to buttons for seeing at night; this way user can combine both pwm and digital leds (i.e. pwm for the button leds but non-button status leds can stay on/off). --- tasmota/i18n.h | 1 + tasmota/settings.h | 3 ++- tasmota/settings.ino | 2 ++ tasmota/support_command.ino | 28 ++++++++++++++++++++++++++-- tasmota/support_tasmota.ino | 28 ++++++++++++++++------------ 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 18c073d0d..d2c232658 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -589,6 +589,7 @@ // Commands led pwm settings #define D_CMND_SETLEDPWMOFF "SetLedPwmOff" #define D_CMND_SETLEDPWMON "SetLedPwmOn" +#define D_CMND_SETLEDPWMMODE "SetLedPwmMode" /********************************************************************************************/ diff --git a/tasmota/settings.h b/tasmota/settings.h index 10c28a2ca..0cc171601 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -569,8 +569,9 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E + uint8_t ledpwm_mask; // F3F - uint8_t free_f3f[117]; // F3F - Decrement if adding new Setting variables just above and below + uint8_t free_f40[116]; // F40 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t ledpwm_on; // FB4 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 7a6a27ac3..d9d913c0a 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1059,6 +1059,7 @@ void SettingsDefaultSet2(void) // Led PWM Settings.ledpwm_off = 0; Settings.ledpwm_on = 1023; + Settings.ledpwm_mask = 0; } /********************************************************************************************/ @@ -1427,5 +1428,6 @@ void SettingsDelta(void) if (Settings.version < 0x080300002) { Settings.ledpwm_off = 0; Settings.ledpwm_on = 1023; + Settings.ledpwm_mask = 0; } } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 314097235..2f327b9a1 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" + D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" D_CMND_SETLEDPWMMODE "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -50,7 +50,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, + &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, &CmndSetLedPwmMode, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -1920,3 +1920,27 @@ void CmndSetLedPwmOn(void) } ResponseCmndNumber(Settings.ledpwm_on); } + +void CmndSetLedPwmMode(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { + if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { + uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to configure + switch (XdrvMailbox.payload) { + case 0: // digital + Settings.ledpwm_mask &= (0xFF ^ mask); + break; + case 1: // pwm + Settings.ledpwm_mask |= mask; + break; + case 2: // toggle + Settings.ledpwm_mask ^= mask; + break; + } + UpdateLedPowerAll(); + } + bool state = bitRead(Settings.ledpwm_mask, XdrvMailbox.index -1); + ResponseCmndIdxChar(GetStateText(state)); + } +} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 5a28b76d6..d96751e32 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -359,20 +359,24 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) led_power &= (0xFF ^ mask); } uint16_t led_pwm_set = 0; - if (bitRead(led_inverted, led)) { - if (state) { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; - } else { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; - } + if (bitRead(Settings.ledpwm_mask, led)) { + if (bitRead(led_inverted, led)) { + if (state) { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; + } else { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; + } + } else { + if (state) { + led_pwm_set = Settings.ledpwm_on; + } else { + led_pwm_set = Settings.ledpwm_off; + } + } + analogWrite(Pin(GPIO_LED1, led), led_pwm_set); } else { - if (state) { - led_pwm_set = Settings.ledpwm_on; - } else { - led_pwm_set = Settings.ledpwm_off; - } + DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); } - analogWrite(Pin(GPIO_LED1, led), led_pwm_set); } #ifdef USE_BUZZER if (led == 0) { From 833d89203f643fac9db10f6409754892cfb7cef2 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 12:38:24 +1000 Subject: [PATCH 8/9] Fix settings delta fail bugfix - settings always default on boot *Moved block to right scope *Got version number right duh --- tasmota/settings.ino | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index d9d913c0a..85a205da2 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1416,6 +1416,13 @@ void SettingsDelta(void) if (Settings.rules[1][0] == 0) { Settings.rules[1][1] = 0; } if (Settings.rules[2][0] == 0) { Settings.rules[2][1] = 0; } } + + // ledpwm + if (Settings.version < 0x08030001) { + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 1023; + Settings.ledpwm_mask = 0; + } if (Settings.version < 0x08030002) { SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); @@ -1424,10 +1431,5 @@ void SettingsDelta(void) Settings.version = VERSION; SettingsSave(1); } - // ledpwm - if (Settings.version < 0x080300002) { - Settings.ledpwm_off = 0; - Settings.ledpwm_on = 1023; - Settings.ledpwm_mask = 0; - } + } From e780f2528328cf3a10f032b618054cd7dc98ca18 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 23 May 2020 17:13:04 +1000 Subject: [PATCH 9/9] Gamma correction Implement changes proposed by @s-hadinger review. * Use 0-255 range in settings * Apply gamma correction from xdrv_light & use changuintscale helper fn (as per pwm light routine) --- tasmota/settings.h | 8 ++++---- tasmota/settings.ino | 4 ++-- tasmota/support_command.ino | 8 ++++---- tasmota/support_tasmota.ino | 24 ++++++++---------------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 0cc171601..e8bae5182 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -570,12 +570,12 @@ struct { int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E uint8_t ledpwm_mask; // F3F - - uint8_t free_f40[116]; // F40 - Decrement if adding new Setting variables just above and below + uint8_t ledpwm_on; // F40 + uint8_t ledpwm_off; // F41 + + uint8_t free_f42[118]; // F42 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below - uint16_t ledpwm_on; // FB4 - uint16_t ledpwm_off; // FB6 uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA uint32_t keeloq_master_msb; // FBC diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 85a205da2..8d771a109 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1058,7 +1058,7 @@ void SettingsDefaultSet2(void) // Led PWM Settings.ledpwm_off = 0; - Settings.ledpwm_on = 1023; + Settings.ledpwm_on = 255; Settings.ledpwm_mask = 0; } @@ -1420,7 +1420,7 @@ void SettingsDelta(void) // ledpwm if (Settings.version < 0x08030001) { Settings.ledpwm_off = 0; - Settings.ledpwm_on = 1023; + Settings.ledpwm_on = 255; Settings.ledpwm_mask = 0; } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 2f327b9a1..f52fb7ea5 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1896,8 +1896,8 @@ void CmndSetLedPwmOff(void) if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { - Settings.ledpwm_off = Settings.pwm_range; + } else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_off = 255; } else { Settings.ledpwm_off = XdrvMailbox.payload; } @@ -1911,8 +1911,8 @@ void CmndSetLedPwmOn(void) if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { - Settings.ledpwm_on = Settings.pwm_range; + } else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_on = 255; } else { Settings.ledpwm_on = XdrvMailbox.payload; } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index d96751e32..374cb6884 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -358,24 +358,16 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_power &= (0xFF ^ mask); } - uint16_t led_pwm_set = 0; + uint16_t pwm = 0; if (bitRead(Settings.ledpwm_mask, led)) { - if (bitRead(led_inverted, led)) { - if (state) { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; - } else { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; - } - } else { - if (state) { - led_pwm_set = Settings.ledpwm_on; - } else { - led_pwm_set = Settings.ledpwm_off; - } - } - analogWrite(Pin(GPIO_LED1, led), led_pwm_set); + #ifdef USE_LIGHT + pwm = changeUIntScale(ledGamma10(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 1023, 0, Settings.pwm_range); // gamma corrected + #else //USE_LIGHT + pwm = changeUIntScale((uint16_t)(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 255, 0, Settings.pwm_range); // linear + #endif //USE_LIGHT + analogWrite(Pin(GPIO_LED1, led), bitRead(led_inverted, led) ? Settings.pwm_range - pwm : pwm); } else { - DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); + DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); } } #ifdef USE_BUZZER