From 603b628f97cf41f1bdaf0285377cdc0274497f47 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 12:13:05 +1000 Subject: [PATCH] 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) {