From c6ddba8fd71dc849a3d3049820ec0c8a338bb81a Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Sat, 19 Jan 2019 14:37:22 +0000 Subject: [PATCH 01/24] Started SM16716 support --- sonoff/language/bg-BG.h | 2 + sonoff/language/cs-CZ.h | 2 + sonoff/language/de-DE.h | 2 + sonoff/language/en-GB.h | 2 + sonoff/language/es-AR.h | 2 + sonoff/language/fr-FR.h | 2 + sonoff/language/he-HE.h | 2 + sonoff/language/hu-HU.h | 2 + sonoff/language/it-IT.h | 2 + sonoff/language/nl-NL.h | 2 + sonoff/language/pl-PL.h | 2 + sonoff/language/pt-BR.h | 2 + sonoff/language/pt-PT.h | 2 + sonoff/language/ru-RU.h | 2 + sonoff/language/sk-SK.h | 2 + sonoff/language/sv-SE.h | 2 + sonoff/language/tr-TR.h | 2 + sonoff/language/uk-UK.h | 2 + sonoff/language/zh-CN.h | 2 + sonoff/language/zh-TW.h | 2 + sonoff/xdrv_20_sm16717.ino | 325 +++++++++++++++++++++++++++++++++++++ 21 files changed, 365 insertions(+) create mode 100644 sonoff/xdrv_20_sm16717.ino diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index d7d812385855..03c1b9f32737 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index e10ec2c4ff33..c87260f7105a 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index bea56f0f6140..692c74e1761e 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 4ac9186e512d..9644e8b4d29f 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 8add1a3ba6b5..a2f8bcf8aaf9 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index aca69fac6ca5..b9fa0d423461 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index d4b41f0b56c8..22f9677b5fe2 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index ee071da54924..b6dd5b55ab2e 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 5ebef743d225..fa3c0b533ebf 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 1235ab26d03c..684545acf5f6 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 6327f87d0138..bc4dad5cad23 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 8f1364771750..1d708f0726e0 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index f863a214823c..baa0e28a5f7e 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index 20f9a2d9fd07..19c09a7fc48d 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sk-SK.h b/sonoff/language/sk-SK.h index 0edd9bea0823..e2551f9bc72f 100644 --- a/sonoff/language/sk-SK.h +++ b/sonoff/language/sk-SK.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index 21246a8f3a0e..2b7b672a45dd 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index 3ef7dd3f5242..bdab28afbcdb 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 59d9ab8b4ce3..4e3c255d5163 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index c64c1b5c3e4f..d4ff8eba8041 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 3560ddf34690..186c5bae3126 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/xdrv_20_sm16717.ino b/sonoff/xdrv_20_sm16717.ino new file mode 100644 index 000000000000..98416019c3c8 --- /dev/null +++ b/sonoff/xdrv_20_sm16717.ino @@ -0,0 +1,325 @@ +/* + xdrv_20_sm16716.ino - SM16716 RGB led controller support for Sonoff-Tasmota + + Copyright (C) 2019 Gabor Simon + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_SM16716 +/*********************************************************************************************\ + * SM16716 - Controlling RGB over a synchronous serial line + * + * Source: https://community.home-assistant.io/t/cheap-uk-wifi-bulbs-with-tasmota-teardown-help-tywe3s/40508/27 + * +\*********************************************************************************************/ + +#define D_LOG_SM16716 "SM16716: " +#define XDRV_20 20 + +#define CLK_USEC 10 // Clock interval in microseconds + +enum SM16716_Commands { + CMND_SM16716_POWER, CMND_SM16716_DIMMER, CMND_SM16716_COLOR }; + +const char k_SM16716_Commands[] PROGMEM = + D_CMND_POWER "|" D_CMND_DIMMER "|" D_CMND_COLOR ; + +uint8_t sm61716_pin_clk = 100; +uint8_t sm61716_pin_dat = 100; + +uint8_t sm61716_colour[3] = {0, 0, 0}; + +uint8_t sm61716_eff_red = 0; +uint8_t sm61716_eff_green = 0; +uint8_t sm61716_eff_blue = 0; + +int8_t sm61716_colour_preset = 0; + +/*********************************************************************************************/ + +void SM16716_SendBit(uint8_t v) +{ + digitalWrite(sm61716_pin_dat, v ? HIGH : LOW); + digitalWrite(sm61716_pin_clk, HIGH); + delayMicroseconds(CLK_USEC); + digitalWrite(sm61716_pin_clk, LOW); + delayMicroseconds(CLK_USEC); +} + +void SM16716_SendByte(uint8_t v) +{ + uint8_t mask; + + for (mask = 0x80; mask; mask >>= 1) + SM16716_SendBit(v & mask); +} + +/*********************************************************************************************/ +void SM16716_Append_JSON(void) +{ + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Append_JSON;")); + AddLog(LOG_LEVEL_DEBUG); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SM16716\":{\"Red\":%d,\"Green\":%d,\"Blue\":%d}"), mqtt_data, sm61716_colour[0], sm61716_colour[1], sm61716_colour[2]); +} + +/*********************************************************************************************/ +boolean SM16716_Show_State(void) +{ + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COLOR "\":\"%02x%02x%02x\"}"), + sm61716_colour[0], sm61716_colour[1], sm61716_colour[2]); + return true; +} + +/*********************************************************************************************/ +void SM16716_Update() +{ + uint8_t eff_red, eff_green, eff_blue; + + if (Settings.power) { // any bit is ok for us + eff_red = (uint16_t)sm61716_colour[0] * Settings.light_dimmer / 100; + eff_green = (uint16_t)sm61716_colour[1] * Settings.light_dimmer / 100; + eff_blue = (uint16_t)sm61716_colour[2] * Settings.light_dimmer / 100; + } + else { + eff_red = eff_green = eff_blue = 0; + } + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Update; pwr=%02x, rgb=%02x%02x%02x, dimmer=%d, eff=%02x%02x%02x"), + Settings.power, sm61716_colour[0], sm61716_colour[1], sm61716_colour[2], Settings.light_dimmer, eff_red, eff_green, eff_blue); + AddLog(LOG_LEVEL_DEBUG); + + if ((eff_red != sm61716_eff_red) || (eff_green != sm61716_eff_green) || (eff_blue != sm61716_eff_blue)) { + sm61716_eff_red = eff_red; + sm61716_eff_green = eff_green; + sm61716_eff_blue = eff_blue; + + SM16716_SendBit(1); + SM16716_SendByte(eff_red); + SM16716_SendByte(eff_green); + SM16716_SendByte(eff_blue); + } + SM16716_Show_State(); +} + +/*********************************************************************************************/ +boolean SM16716_ModuleSelected(void) +{ + sm61716_pin_clk = pin[GPIO_SM16716_CLK]; + sm61716_pin_dat = pin[GPIO_SM16716_DAT]; + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), sm61716_pin_clk, sm61716_pin_dat); + AddLog(LOG_LEVEL_DEBUG); + return (sm61716_pin_clk < 99) && (sm61716_pin_dat < 99); +} + +/*********************************************************************************************/ +boolean SM16716_Init(void) +{ + uint8_t t_init; + if (!SM16716_ModuleSelected()) + return false; + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Init;")); + + pinMode(sm61716_pin_clk, OUTPUT); + digitalWrite(sm61716_pin_clk, LOW); + + pinMode(sm61716_pin_dat, OUTPUT); + digitalWrite(sm61716_pin_dat, LOW); + + AddLog(LOG_LEVEL_DEBUG); + for (t_init = 0; t_init < 50; ++t_init) + SM16716_SendBit(0); + + return true; +} + +boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { + char component[3]; + char *endptr = NULL; + uint8_t candidate[3]; + int i; + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_RRGGBB; data='%s', data_len=%d"), data, data_len); + AddLog(LOG_LEVEL_DEBUG); + + if (data_len != 6) + return false; + + component[2] = '\0'; + + for (i = 0; i < 3; ++i) { + component[0] = data[0]; + component[1] = data[1]; + candidate[i] = (uint8_t)strtoul(component, &endptr, 16); + if (!endptr || *endptr) + return false; + data += 2; + } + + sm61716_colour[0] = candidate[0]; + sm61716_colour[1] = candidate[1]; + sm61716_colour[2] = candidate[2]; + return true; +} + +boolean SM16716_Parse_Colour(char *data, int data_len) { + /* NOTE: Very similar to 'LightColorEntry', but it's not reusable, because + * 'light_type' must be PWM, but then it won't parse the colour components. + * It's indeed more effective to not do the parsing when the current light + * type couldn't handle it, but enum LightTypes is not to be changed, so + * I can't implement new light types. + * + * If the parsing/handling of light attributes were separated from the + * technical details of actually sending it to the device, then only the + * device-specific parts should've been adapted, but unfortunately this is + * not the case here, so, here we go */ + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_Colour; data='%s', data_len=%d"), data, data_len); + AddLog(LOG_LEVEL_DEBUG); + + if (data_len < 3) { // Colour preset + switch (data[0]) { + case '+': + ++sm61716_colour_preset; + if (sm61716_colour_preset >= MAX_FIXED_COLOR) + sm61716_colour_preset = 0; + break; + + case '-': + --sm61716_colour_preset; + if (sm61716_colour_preset < 0) + sm61716_colour_preset = MAX_FIXED_COLOR - 1; + break; + + default: + { + char *endptr = NULL; + uint8_t candidate = (uint8_t)strtoul(data, &endptr, 10); + if (!endptr || *endptr || (candidate < 0) || (MAX_FIXED_COLOR <= candidate)) + return false; + sm61716_colour_preset = candidate; + } + break; + } + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_Colour; preset=%d"), sm61716_colour_preset); + AddLog(LOG_LEVEL_DEBUG); + memcpy_P(sm61716_colour, &kFixedColor[sm61716_colour_preset], 3); + } + else if (data[0] == '#') { // #RRGGBB + if (!SM16716_Parse_RRGGBB(data + 1, data_len - 1)) + return false; + } + else if (SM16716_Parse_RRGGBB(data, data_len)) { // RRGGBB + } + else { // rrr,g,bb + uint8_t candidate[3]; + char *tok, *last, *endptr = NULL; + int i; + + for (i = 0; i < 3; ++i) { + tok = strtok_r(data, ",", &last); + if (!tok) + return false; + candidate[i] = (uint8_t)strtoul(tok, &endptr, 0); + if (!endptr || *endptr) + return false; + data = NULL; + } + tok = strtok_r(NULL, ",", &last); + if (tok) + return false; // junk at the end + sm61716_colour[0] = candidate[0]; + sm61716_colour[1] = candidate[1]; + sm61716_colour[2] = candidate[2]; + } + return true; +} + +/*********************************************************************************************/ +bool SM16716_Command(void) +{ + char command [CMDSZ]; + int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, k_SM16716_Commands); + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Command; topic='%s', data_len=%d, data='%s', code=%d"), + XdrvMailbox.topic, XdrvMailbox.data_len, XdrvMailbox.data, command_code); + AddLog(LOG_LEVEL_DEBUG); + + switch (command_code) { + case CMND_SM16716_POWER: + SM16716_Update(); + return false; // Don't catch the event, only handle the change + + case CMND_SM16716_DIMMER: + SM16716_Update(); + return false; // Don't catch the event, only handle the change + + case CMND_SM16716_COLOR: + if (XdrvMailbox.data_len == 0) + return SM16716_Show_State(); + if (!SM16716_Parse_Colour(XdrvMailbox.data, XdrvMailbox.data_len)) + return false; + SM16716_Update(); + return true; + } + return false; // Unknown command +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ +boolean Xdrv20(byte function) +{ + //snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Xdrv20; function=%d, index=%d"), function, XdrvMailbox.index); + //AddLog(LOG_LEVEL_DEBUG); + + switch (function) { + case FUNC_MODULE_INIT: + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_MODULE_INIT")); + AddLog(LOG_LEVEL_DEBUG); + return SM16716_ModuleSelected(); + + case FUNC_INIT: + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_INIT")); + AddLog(LOG_LEVEL_DEBUG); + return SM16716_Init(); + + case FUNC_COMMAND: + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_COMMAND")); + AddLog(LOG_LEVEL_DEBUG); + return SM16716_Command(); + + case FUNC_SET_POWER: + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_SET_POWER, index=%02x, payload=%02x"), XdrvMailbox.index, XdrvMailbox.payload); + AddLog(LOG_LEVEL_DEBUG); + return false; + + case FUNC_SET_DEVICE_POWER: + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_SET_DEVICE_POWER, index=%02x, payload=%02x"), XdrvMailbox.index, XdrvMailbox.payload); + AddLog(LOG_LEVEL_DEBUG); + return false; + + case FUNC_JSON_APPEND: + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_JSON_APPEND")); + AddLog(LOG_LEVEL_DEBUG); + SM16716_Append_JSON(); + break; + } + return false; +} + +#endif // USE_SM16716 + +// vim: set ft=c sw=2 ts=2 et: From 553738335278c8ef12446ae40b1e2237b65c562e Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Sat, 19 Jan 2019 22:28:58 +0000 Subject: [PATCH 02/24] sm16716 works via mqtt --- sonoff/sonoff_template.h | 37 +++++- sonoff/xdrv_20_sm16717.ino | 261 +++++++++++++++++++++---------------- 2 files changed, 181 insertions(+), 117 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 39eb8737d9b9..250bd9f46271 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -146,6 +146,8 @@ enum UserSelectablePins { GPIO_MAX31855CS, // MAX31855 Serial interface GPIO_MAX31855CLK, // MAX31855 Serial interface GPIO_MAX31855DO, // MAX31855 Serial interface + GPIO_SM16716_CLK, // SM16716 CLK + GPIO_SM16716_DAT, // SM16716 DAT GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -209,7 +211,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|" D_SENSOR_RF_SENSOR "|" D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|" - D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO; + D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" + D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT; /********************************************************************************************/ @@ -281,6 +284,7 @@ enum SupportedModules { KA10, ZX2820, MI_DESK_LAMP, + SYF05, MAXMODULE }; /********************************************************************************************/ @@ -506,6 +510,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_MAX31855CLK, // MAX31855 Serial interface GPIO_MAX31855DO, // MAX31855 Serial interface #endif +#ifdef USE_SM16716 + GPIO_SM16716_CLK, // SM16716 CLK + GPIO_SM16716_DAT, // SM16716 DAT +#endif // USE_SM16716 }; const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { @@ -574,7 +582,8 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { PHILIPS, YTF_IR_BRIDGE, WITTY, // Development Devices - WEMOS + WEMOS, + SYF05 }; // Default module settings @@ -1774,6 +1783,30 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_ROT_A, // GPIO12 Rotary switch A pin GPIO_ROT_B, // GPIO13 Rotary switch B pin 0, 0, 0, 0 + }, + { "SYF05", // Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726 + // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n + // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html + // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771 + GPIO_USER, // GPIO00 N.C. + 0, + GPIO_USER, // GPIO02 N.C. + 0, + GPIO_SM16716_CLK, // GPIO04 + GPIO_PWM1, // GPIO05 Cold White + // GPIO06 + // GPIO07 + // GPIO08 + 0, // GPIO09 + 0, // GPIO10 + // GPIO11 + GPIO_USER, // GPIO12 Warm White, not used on the LED panel + GPIO_USER, // GPIO13 N.C. (used as LED if you add it) + GPIO_SM16716_DAT, // GPIO14 + 0, // GPIO15 + GPIO_USER, // GPIO16 N.C. + GPIO_FLAG_ADC0 // ADC0 A0 Analog input +// + GPIO_FLAG_PULLUP // Allow input pull-up control } }; diff --git a/sonoff/xdrv_20_sm16717.ino b/sonoff/xdrv_20_sm16717.ino index 98416019c3c8..1779d1e7484b 100644 --- a/sonoff/xdrv_20_sm16717.ino +++ b/sonoff/xdrv_20_sm16717.ino @@ -18,6 +18,7 @@ */ #ifdef USE_SM16716 + /*********************************************************************************************\ * SM16716 - Controlling RGB over a synchronous serial line * @@ -25,134 +26,156 @@ * \*********************************************************************************************/ -#define D_LOG_SM16716 "SM16716: " #define XDRV_20 20 -#define CLK_USEC 10 // Clock interval in microseconds +// Enable this for debug logging +//#define D_LOG_SM16716 "SM16716: " enum SM16716_Commands { - CMND_SM16716_POWER, CMND_SM16716_DIMMER, CMND_SM16716_COLOR }; + CMND_SM16716_COLOR }; const char k_SM16716_Commands[] PROGMEM = - D_CMND_POWER "|" D_CMND_DIMMER "|" D_CMND_COLOR ; - -uint8_t sm61716_pin_clk = 100; -uint8_t sm61716_pin_dat = 100; + D_CMND_COLOR ; -uint8_t sm61716_colour[3] = {0, 0, 0}; +uint8_t sm16716_pin_clk = 100; +uint8_t sm16716_pin_dat = 100; -uint8_t sm61716_eff_red = 0; -uint8_t sm61716_eff_green = 0; -uint8_t sm61716_eff_blue = 0; +boolean sm16716_is_selected = false; +boolean sm16716_is_on = false; +uint8_t sm16716_color[3] = {0, 0, 0}; +int8_t sm16716_color_preset = 0; -int8_t sm61716_colour_preset = 0; /*********************************************************************************************/ - void SM16716_SendBit(uint8_t v) { - digitalWrite(sm61716_pin_dat, v ? HIGH : LOW); - digitalWrite(sm61716_pin_clk, HIGH); - delayMicroseconds(CLK_USEC); - digitalWrite(sm61716_pin_clk, LOW); - delayMicroseconds(CLK_USEC); + /* NOTE: + * According to the spec sheet, max freq is 30 MHz, that is 16.6 ns per high/low half of the + * clk square wave. That is less than the overhead of 'digitalWrite' at this clock rate, + * so no additional delays are needed yet. */ + + digitalWrite(sm16716_pin_dat, (v != 0) ? HIGH : LOW); + //delayMicroseconds(1); + digitalWrite(sm16716_pin_clk, HIGH); + //delayMicroseconds(1); + digitalWrite(sm16716_pin_clk, LOW); } + +/*********************************************************************************************/ void SM16716_SendByte(uint8_t v) { uint8_t mask; - for (mask = 0x80; mask; mask >>= 1) + for (mask = 0x80; mask; mask >>= 1) { SM16716_SendBit(v & mask); + } } + /*********************************************************************************************/ void SM16716_Append_JSON(void) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Append_JSON;")); - AddLog(LOG_LEVEL_DEBUG); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SM16716\":{\"Red\":%d,\"Green\":%d,\"Blue\":%d}"), mqtt_data, sm61716_colour[0], sm61716_colour[1], sm61716_colour[2]); + snprintf_P(mqtt_data, sizeof(mqtt_data), + PSTR("%s,\"SM16716\":{\"Red\":%d,\"Green\":%d,\"Blue\":%d}"), + mqtt_data, sm16716_color[0], sm16716_color[1], sm16716_color[2]); } + /*********************************************************************************************/ boolean SM16716_Show_State(void) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COLOR "\":\"%02x%02x%02x\"}"), - sm61716_colour[0], sm61716_colour[1], sm61716_colour[2]); + snprintf_P(mqtt_data, sizeof(mqtt_data), + PSTR("{\"" D_CMND_COLOR "\":\"%02x%02x%02x\"}"), + sm16716_color[0], sm16716_color[1], sm16716_color[2]); return true; } + /*********************************************************************************************/ void SM16716_Update() { - uint8_t eff_red, eff_green, eff_blue; - - if (Settings.power) { // any bit is ok for us - eff_red = (uint16_t)sm61716_colour[0] * Settings.light_dimmer / 100; - eff_green = (uint16_t)sm61716_colour[1] * Settings.light_dimmer / 100; - eff_blue = (uint16_t)sm61716_colour[2] * Settings.light_dimmer / 100; +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Update; pwr=%02x, rgb=%02x%02x%02x"), + sm16716_is_on, sm16716_color[0], sm16716_color[1], sm16716_color[2]); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + + // send start bit + SM16716_SendBit(1); + // send 24-bit rgb data + if (sm16716_is_on) { + SM16716_SendByte(sm16716_color[0]); + SM16716_SendByte(sm16716_color[1]); + SM16716_SendByte(sm16716_color[2]); } else { - eff_red = eff_green = eff_blue = 0; - } - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Update; pwr=%02x, rgb=%02x%02x%02x, dimmer=%d, eff=%02x%02x%02x"), - Settings.power, sm61716_colour[0], sm61716_colour[1], sm61716_colour[2], Settings.light_dimmer, eff_red, eff_green, eff_blue); - AddLog(LOG_LEVEL_DEBUG); - - if ((eff_red != sm61716_eff_red) || (eff_green != sm61716_eff_green) || (eff_blue != sm61716_eff_blue)) { - sm61716_eff_red = eff_red; - sm61716_eff_green = eff_green; - sm61716_eff_blue = eff_blue; - - SM16716_SendBit(1); - SM16716_SendByte(eff_red); - SM16716_SendByte(eff_green); - SM16716_SendByte(eff_blue); + SM16716_SendByte(0); + SM16716_SendByte(0); + SM16716_SendByte(0); } + // send a 'do it' pulse + // (if multiple chips are chained, each one processes the 1st '1rgb' 25-bit block and + // passes on the rest, right until the one starting with 0) + SM16716_SendBit(0); + SM16716_SendByte(0); + SM16716_SendByte(0); + SM16716_SendByte(0); SM16716_Show_State(); } + /*********************************************************************************************/ boolean SM16716_ModuleSelected(void) { - sm61716_pin_clk = pin[GPIO_SM16716_CLK]; - sm61716_pin_dat = pin[GPIO_SM16716_DAT]; - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), sm61716_pin_clk, sm61716_pin_dat); + sm16716_pin_clk = pin[GPIO_SM16716_CLK]; + sm16716_pin_dat = pin[GPIO_SM16716_DAT]; +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), + sm16716_pin_clk, sm16716_pin_dat); AddLog(LOG_LEVEL_DEBUG); - return (sm61716_pin_clk < 99) && (sm61716_pin_dat < 99); +#endif // D_LOG_SM16716 + sm16716_is_selected = (sm16716_pin_clk < 99) && (sm16716_pin_dat < 99); + return sm16716_is_selected; } + /*********************************************************************************************/ boolean SM16716_Init(void) { uint8_t t_init; + if (!SM16716_ModuleSelected()) return false; - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Init;")); - - pinMode(sm61716_pin_clk, OUTPUT); - digitalWrite(sm61716_pin_clk, LOW); + pinMode(sm16716_pin_clk, OUTPUT); + digitalWrite(sm16716_pin_clk, LOW); - pinMode(sm61716_pin_dat, OUTPUT); - digitalWrite(sm61716_pin_dat, LOW); + pinMode(sm16716_pin_dat, OUTPUT); + digitalWrite(sm16716_pin_dat, LOW); - AddLog(LOG_LEVEL_DEBUG); for (t_init = 0; t_init < 50; ++t_init) SM16716_SendBit(0); return true; } + +/*********************************************************************************************/ boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { char component[3]; char *endptr = NULL; uint8_t candidate[3]; int i; - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_RRGGBB; data='%s', data_len=%d"), data, data_len); +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Parse_RRGGBB; data='%s', data_len=%d"), + data, data_len); AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 if (data_len != 6) return false; @@ -168,39 +191,37 @@ boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { data += 2; } - sm61716_colour[0] = candidate[0]; - sm61716_colour[1] = candidate[1]; - sm61716_colour[2] = candidate[2]; + sm16716_color[0] = candidate[0]; + sm16716_color[1] = candidate[1]; + sm16716_color[2] = candidate[2]; return true; } -boolean SM16716_Parse_Colour(char *data, int data_len) { - /* NOTE: Very similar to 'LightColorEntry', but it's not reusable, because - * 'light_type' must be PWM, but then it won't parse the colour components. - * It's indeed more effective to not do the parsing when the current light - * type couldn't handle it, but enum LightTypes is not to be changed, so - * I can't implement new light types. - * - * If the parsing/handling of light attributes were separated from the - * technical details of actually sending it to the device, then only the - * device-specific parts should've been adapted, but unfortunately this is - * not the case here, so, here we go */ - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_Colour; data='%s', data_len=%d"), data, data_len); + +/*********************************************************************************************/ +boolean SM16716_Parse_Color(char *data, int data_len) { + /* NOTE: Very similar to 'LightColorEntry', but can't reuse it here, because + * 'light_type' must be PWM, and then it won't parse the color components. */ + +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Parse_Color; data='%s', data_len=%d"), + data, data_len); AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 - if (data_len < 3) { // Colour preset + if (data_len < 3) { // a color preset switch (data[0]) { case '+': - ++sm61716_colour_preset; - if (sm61716_colour_preset >= MAX_FIXED_COLOR) - sm61716_colour_preset = 0; + ++sm16716_color_preset; + if (sm16716_color_preset >= MAX_FIXED_COLOR) + sm16716_color_preset = 0; break; case '-': - --sm61716_colour_preset; - if (sm61716_colour_preset < 0) - sm61716_colour_preset = MAX_FIXED_COLOR - 1; + --sm16716_color_preset; + if (sm16716_color_preset < 0) + sm16716_color_preset = MAX_FIXED_COLOR - 1; break; default: @@ -209,13 +230,17 @@ boolean SM16716_Parse_Colour(char *data, int data_len) { uint8_t candidate = (uint8_t)strtoul(data, &endptr, 10); if (!endptr || *endptr || (candidate < 0) || (MAX_FIXED_COLOR <= candidate)) return false; - sm61716_colour_preset = candidate; + sm16716_color_preset = candidate; } break; } - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_Colour; preset=%d"), sm61716_colour_preset); +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Parse_Color; preset=%d"), + sm16716_color_preset); AddLog(LOG_LEVEL_DEBUG); - memcpy_P(sm61716_colour, &kFixedColor[sm61716_colour_preset], 3); +#endif // D_LOG_SM16716 + memcpy_P(sm16716_color, &kFixedColor[sm16716_color_preset], 3); } else if (data[0] == '#') { // #RRGGBB if (!SM16716_Parse_RRGGBB(data + 1, data_len - 1)) @@ -240,36 +265,32 @@ boolean SM16716_Parse_Colour(char *data, int data_len) { tok = strtok_r(NULL, ",", &last); if (tok) return false; // junk at the end - sm61716_colour[0] = candidate[0]; - sm61716_colour[1] = candidate[1]; - sm61716_colour[2] = candidate[2]; + sm16716_color[0] = candidate[0]; + sm16716_color[1] = candidate[1]; + sm16716_color[2] = candidate[2]; } return true; } + /*********************************************************************************************/ bool SM16716_Command(void) { char command [CMDSZ]; int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, k_SM16716_Commands); - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Command; topic='%s', data_len=%d, data='%s', code=%d"), +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Command; topic='%s', data_len=%d, data='%s', code=%d"), XdrvMailbox.topic, XdrvMailbox.data_len, XdrvMailbox.data, command_code); AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 switch (command_code) { - case CMND_SM16716_POWER: - SM16716_Update(); - return false; // Don't catch the event, only handle the change - - case CMND_SM16716_DIMMER: - SM16716_Update(); - return false; // Don't catch the event, only handle the change - case CMND_SM16716_COLOR: if (XdrvMailbox.data_len == 0) return SM16716_Show_State(); - if (!SM16716_Parse_Colour(XdrvMailbox.data, XdrvMailbox.data_len)) + if (!SM16716_Parse_Color(XdrvMailbox.data, XdrvMailbox.data_len)) return false; SM16716_Update(); return true; @@ -277,43 +298,54 @@ bool SM16716_Command(void) return false; // Unknown command } + /*********************************************************************************************\ * Interface \*********************************************************************************************/ boolean Xdrv20(byte function) { - //snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Xdrv20; function=%d, index=%d"), function, XdrvMailbox.index); - //AddLog(LOG_LEVEL_DEBUG); - - switch (function) { - case FUNC_MODULE_INIT: - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_MODULE_INIT")); - AddLog(LOG_LEVEL_DEBUG); + if (function == FUNC_MODULE_INIT) { return SM16716_ModuleSelected(); + } + + if (!sm16716_is_selected) + return false; + switch (function) { case FUNC_INIT: - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_INIT")); +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Entry; function=FUNC_INIT")); AddLog(LOG_LEVEL_DEBUG); +#endif return SM16716_Init(); case FUNC_COMMAND: - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_COMMAND")); +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Entry; function=FUNC_COMMAND")); AddLog(LOG_LEVEL_DEBUG); return SM16716_Command(); +#endif - case FUNC_SET_POWER: - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_SET_POWER, index=%02x, payload=%02x"), XdrvMailbox.index, XdrvMailbox.payload); - AddLog(LOG_LEVEL_DEBUG); - return false; - + //case FUNC_SET_POWER: case FUNC_SET_DEVICE_POWER: - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_SET_DEVICE_POWER, index=%02x, payload=%02x"), XdrvMailbox.index, XdrvMailbox.payload); +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Entry; function=FUNC_SET_DEVICE_POWER, index=%02x, payload=%02x"), + XdrvMailbox.index, XdrvMailbox.payload); AddLog(LOG_LEVEL_DEBUG); - return false; +#endif + sm16716_is_on = (XdrvMailbox.index != 0); + SM16716_Update(); + return false; // don't catch the event case FUNC_JSON_APPEND: - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_JSON_APPEND")); +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Entry; function=FUNC_JSON_APPEND")); AddLog(LOG_LEVEL_DEBUG); +#endif SM16716_Append_JSON(); break; } @@ -321,5 +353,4 @@ boolean Xdrv20(byte function) } #endif // USE_SM16716 - // vim: set ft=c sw=2 ts=2 et: From d9e0e9f89e0d913e5a158cad569485b0d4af796c Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Sun, 20 Jan 2019 21:18:28 +0000 Subject: [PATCH 03/24] Added missing definitions to Greek localisation header --- sonoff/language/el-GR.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 8a440253830c..81a017a0bcd6 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -544,6 +544,8 @@ #define D_SENSOR_MAX31855_CS "MAX31855 CS" #define D_SENSOR_MAX31855_CLK "MAX31855 CLK" #define D_SENSOR_MAX31855_DO "MAX31855 DO" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" // Units #define D_UNIT_AMPERE "A" From f833dd07ad02b2fd2c39d37cb95b864f0337c672 Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Mon, 21 Jan 2019 06:44:07 +0000 Subject: [PATCH 04/24] Enabled 'warm white' pwm in the module config, code comments added, coding style improved --- sonoff/sonoff_template.h | 4 +- sonoff/xdrv_20_sm16717.ino | 86 ++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 250bd9f46271..ceca9685efb0 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -1800,10 +1800,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, // GPIO09 0, // GPIO10 // GPIO11 - GPIO_USER, // GPIO12 Warm White, not used on the LED panel + GPIO_PWM2, // GPIO12 Warm White GPIO_USER, // GPIO13 N.C. (used as LED if you add it) GPIO_SM16716_DAT, // GPIO14 - 0, // GPIO15 + 0, // GPIO15 wired to GND GPIO_USER, // GPIO16 N.C. GPIO_FLAG_ADC0 // ADC0 A0 Analog input // + GPIO_FLAG_PULLUP // Allow input pull-up control diff --git a/sonoff/xdrv_20_sm16717.ino b/sonoff/xdrv_20_sm16717.ino index 1779d1e7484b..7b367fc2f3bf 100644 --- a/sonoff/xdrv_20_sm16717.ino +++ b/sonoff/xdrv_20_sm16717.ino @@ -147,8 +147,9 @@ boolean SM16716_Init(void) { uint8_t t_init; - if (!SM16716_ModuleSelected()) + if (!SM16716_ModuleSelected()) { return false; + } pinMode(sm16716_pin_clk, OUTPUT); digitalWrite(sm16716_pin_clk, LOW); @@ -156,14 +157,18 @@ boolean SM16716_Init(void) pinMode(sm16716_pin_dat, OUTPUT); digitalWrite(sm16716_pin_dat, LOW); - for (t_init = 0; t_init < 50; ++t_init) + for (t_init = 0; t_init < 50; ++t_init) { SM16716_SendBit(0); + } return true; } /*********************************************************************************************/ +/* Try to parse a string as 'RRGGBB' hex-encoded color value + * Accept only exact match (i.e. there can be no leftover chars) + */ boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { char component[3]; char *endptr = NULL; @@ -177,20 +182,30 @@ boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { AddLog(LOG_LEVEL_DEBUG); #endif // D_LOG_SM16716 - if (data_len != 6) + if (data_len != 6) { + // too long or too short return false; + } + // a component is exactly 3 chars, so terminate the string now component[2] = '\0'; + // try to parse 3 components for (i = 0; i < 3; ++i) { + // copy the value to the temp string component[0] = data[0]; component[1] = data[1]; + // try to interpret it as a hex number candidate[i] = (uint8_t)strtoul(component, &endptr, 16); - if (!endptr || *endptr) + if (!endptr || *endptr) { + // not a valid hex number return false; + } + // advance to the next 2 characters data += 2; } + // now that we have all 3, we may change sm16716_color[] sm16716_color[0] = candidate[0]; sm16716_color[1] = candidate[1]; sm16716_color[2] = candidate[2]; @@ -210,61 +225,87 @@ boolean SM16716_Parse_Color(char *data, int data_len) { AddLog(LOG_LEVEL_DEBUG); #endif // D_LOG_SM16716 - if (data_len < 3) { // a color preset + if (data_len < 3) { // too short for color literal: try to interpret as a color preset + // check for '+' and '-' commands first switch (data[0]) { - case '+': + case '+': // advance to the next preset, handle wrap-around ++sm16716_color_preset; - if (sm16716_color_preset >= MAX_FIXED_COLOR) + if (sm16716_color_preset >= MAX_FIXED_COLOR) { sm16716_color_preset = 0; + } break; - case '-': + case '-': // return to the previous preset, handle wrap-around --sm16716_color_preset; - if (sm16716_color_preset < 0) + if (sm16716_color_preset < 0) { sm16716_color_preset = MAX_FIXED_COLOR - 1; + } break; default: + // try to interpret it as a decimal integer { char *endptr = NULL; uint8_t candidate = (uint8_t)strtoul(data, &endptr, 10); - if (!endptr || *endptr || (candidate < 0) || (MAX_FIXED_COLOR <= candidate)) + if (!endptr || *endptr || (candidate < 0) || (MAX_FIXED_COLOR <= candidate)) { + // it's not a valid integer (and nothing else), or the number is not a valid preset index return false; + } + // we have the requested preset index sm16716_color_preset = candidate; } break; } + #ifdef D_LOG_SM16716 snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Parse_Color; preset=%d"), sm16716_color_preset); AddLog(LOG_LEVEL_DEBUG); #endif // D_LOG_SM16716 + + // copy the requested preset values memcpy_P(sm16716_color, &kFixedColor[sm16716_color_preset], 3); } - else if (data[0] == '#') { // #RRGGBB - if (!SM16716_Parse_RRGGBB(data + 1, data_len - 1)) + else if (data[0] == '#') { // starts with #, so try to interpret as #RRGGBB + if (!SM16716_Parse_RRGGBB(data + 1, data_len - 1)) { + // not a valid RRGGBB after the # return false; + } } - else if (SM16716_Parse_RRGGBB(data, data_len)) { // RRGGBB + // two more formats left: RRGGBB (without #) and comma separated color components + else if (SM16716_Parse_RRGGBB(data, data_len)) { // try to interpret as RRGGBB + // parsed successfully as RRGGBB, nothing more to do } - else { // rrr,g,bb + else { // try to interpret as rrr,g,bb uint8_t candidate[3]; char *tok, *last, *endptr = NULL; int i; + // try to parse the first 3 comma-separated tokens for (i = 0; i < 3; ++i) { + // try to isolate the next token tok = strtok_r(data, ",", &last); - if (!tok) + if (!tok) { + // we're beyond the end of string: there were too few tokens return false; + } + // try to interpret the token as integer candidate[i] = (uint8_t)strtoul(tok, &endptr, 0); - if (!endptr || *endptr) + if (!endptr || *endptr) { + // not a valid integer return false; + } + // in the next cycle just continue this token-processing session data = NULL; } + // there shouldn't be any leftover characters (i.e. we need exactly 3 components) tok = strtok_r(NULL, ",", &last); - if (tok) - return false; // junk at the end + if (tok) { + // too many components + return false; + } + // now that we have all 3 components, we may change sm16716_color sm16716_color[0] = candidate[0]; sm16716_color[1] = candidate[1]; sm16716_color[2] = candidate[2]; @@ -288,10 +329,12 @@ bool SM16716_Command(void) switch (command_code) { case CMND_SM16716_COLOR: - if (XdrvMailbox.data_len == 0) + if (XdrvMailbox.data_len == 0) { return SM16716_Show_State(); - if (!SM16716_Parse_Color(XdrvMailbox.data, XdrvMailbox.data_len)) + } + if (!SM16716_Parse_Color(XdrvMailbox.data, XdrvMailbox.data_len)) { return false; + } SM16716_Update(); return true; } @@ -308,8 +351,9 @@ boolean Xdrv20(byte function) return SM16716_ModuleSelected(); } - if (!sm16716_is_selected) + if (!sm16716_is_selected) { return false; + } switch (function) { case FUNC_INIT: From a770f54e9022a45b6a3b538f375ed4a23b293550 Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Tue, 29 Jan 2019 06:58:52 +0000 Subject: [PATCH 05/24] misplaced #endif fixed --- sonoff/xdrv_20_sm16717.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xdrv_20_sm16717.ino b/sonoff/xdrv_20_sm16717.ino index 7b367fc2f3bf..0016efc2ef05 100644 --- a/sonoff/xdrv_20_sm16717.ino +++ b/sonoff/xdrv_20_sm16717.ino @@ -369,8 +369,8 @@ boolean Xdrv20(byte function) snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Entry; function=FUNC_COMMAND")); AddLog(LOG_LEVEL_DEBUG); - return SM16716_Command(); #endif + return SM16716_Command(); //case FUNC_SET_POWER: case FUNC_SET_DEVICE_POWER: From e2d80403382c08d6ff06e104ddc7512dd8f9781a Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Wed, 30 Jan 2019 07:05:38 +0000 Subject: [PATCH 06/24] Type changed from boolean to bool applied to xdrv_20_sm16716.ino as well The upstream commit that changed the types in the interface: commit 304ac6fe44c9ba9aca4478036555e9eaa442dc9b Author: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon Jan 28 14:08:33 2019 +0100 6.4.1.12 code changes (byte/boolean) --- sonoff/xdrv_20_sm16717.ino | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sonoff/xdrv_20_sm16717.ino b/sonoff/xdrv_20_sm16717.ino index 0016efc2ef05..1dada4c9ca89 100644 --- a/sonoff/xdrv_20_sm16717.ino +++ b/sonoff/xdrv_20_sm16717.ino @@ -40,8 +40,8 @@ const char k_SM16716_Commands[] PROGMEM = uint8_t sm16716_pin_clk = 100; uint8_t sm16716_pin_dat = 100; -boolean sm16716_is_selected = false; -boolean sm16716_is_on = false; +bool sm16716_is_selected = false; +bool sm16716_is_on = false; uint8_t sm16716_color[3] = {0, 0, 0}; int8_t sm16716_color_preset = 0; @@ -83,7 +83,7 @@ void SM16716_Append_JSON(void) /*********************************************************************************************/ -boolean SM16716_Show_State(void) +bool SM16716_Show_State(void) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COLOR "\":\"%02x%02x%02x\"}"), @@ -127,7 +127,7 @@ void SM16716_Update() /*********************************************************************************************/ -boolean SM16716_ModuleSelected(void) +bool SM16716_ModuleSelected(void) { sm16716_pin_clk = pin[GPIO_SM16716_CLK]; sm16716_pin_dat = pin[GPIO_SM16716_DAT]; @@ -143,7 +143,7 @@ boolean SM16716_ModuleSelected(void) /*********************************************************************************************/ -boolean SM16716_Init(void) +bool SM16716_Init(void) { uint8_t t_init; @@ -169,7 +169,7 @@ boolean SM16716_Init(void) /* Try to parse a string as 'RRGGBB' hex-encoded color value * Accept only exact match (i.e. there can be no leftover chars) */ -boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { +bool SM16716_Parse_RRGGBB(const char *data, int data_len) { char component[3]; char *endptr = NULL; uint8_t candidate[3]; @@ -214,7 +214,7 @@ boolean SM16716_Parse_RRGGBB(const char *data, int data_len) { /*********************************************************************************************/ -boolean SM16716_Parse_Color(char *data, int data_len) { +bool SM16716_Parse_Color(char *data, int data_len) { /* NOTE: Very similar to 'LightColorEntry', but can't reuse it here, because * 'light_type' must be PWM, and then it won't parse the color components. */ @@ -345,7 +345,7 @@ bool SM16716_Command(void) /*********************************************************************************************\ * Interface \*********************************************************************************************/ -boolean Xdrv20(byte function) +bool Xdrv20(uint8_t function) { if (function == FUNC_MODULE_INIT) { return SM16716_ModuleSelected(); From 3a43050d93fdf1afce468cd7f0c3c8bb15d374a0 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 30 Jan 2019 17:19:40 -0500 Subject: [PATCH 07/24] Integrated Gabor's SM16716 code into the light driver code Removed redundant processing and variables Added new light type to distinguish SM16716 devices --- sonoff/sonoff.ino | 6 + sonoff/xdrv_04_light.ino | 106 ++++++++++ sonoff/xdrv_20_sm16717.ino | 400 ------------------------------------- 3 files changed, 112 insertions(+), 400 deletions(-) delete mode 100644 sonoff/xdrv_20_sm16717.ino diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 936f7930e78a..fbf256134d76 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2422,6 +2422,12 @@ void GpioInit(void) light_type = LT_WS2812; } #endif // USE_WS2812 +#ifdef USE_SM16716 + if (SM16716_ModuleSelected()) { + light_type += 3; + light_type |= 16; + } +#endif // ifdef USE_SM16716 if (!light_type) { for (uint8_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only if (pin[GPIO_PWM1 +i] < 99) { diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 9d8740ccb089..2dc098c80f5b 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -32,6 +32,9 @@ * 11 +WS2812 RGB(W) no (One WS2812 RGB or RGBW ledstrip) * 12 AiLight RGBW no * 13 Sonoff B1 RGBCW yes + * 19 SM16716 RGB no + * 20 SM16716+W RGBW no + * 21 SM16716+CW RGBCW yes * * light_scheme WS2812 3+ Colors 1+2 Colors Effect * ------------ ------ --------- ---------- ----------------- @@ -354,6 +357,99 @@ void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t dut os_delay_us(12); // TStop > 12us. } +#ifdef USE_SM16716 +/*********************************************************************************************\ + * SM16716 - Controlling RGB over a synchronous serial line + * Copyright (C) 2019 Gabor Simon + * + * Source: https://community.home-assistant.io/t/cheap-uk-wifi-bulbs-with-tasmota-teardown-help-tywe3s/40508/27 + * +\*********************************************************************************************/ + +// Enable this for debug logging +//#define D_LOG_SM16716 "SM16716: " + +uint8_t sm16716_pin_clk = 100; +uint8_t sm16716_pin_dat = 100; + +void SM16716_SendBit(uint8_t v) +{ + /* NOTE: + * According to the spec sheet, max freq is 30 MHz, that is 16.6 ns per high/low half of the + * clk square wave. That is less than the overhead of 'digitalWrite' at this clock rate, + * so no additional delays are needed yet. */ + + digitalWrite(sm16716_pin_dat, (v != 0) ? HIGH : LOW); + //delayMicroseconds(1); + digitalWrite(sm16716_pin_clk, HIGH); + //delayMicroseconds(1); + digitalWrite(sm16716_pin_clk, LOW); +} + +void SM16716_SendByte(uint8_t v) +{ + uint8_t mask; + + for (mask = 0x80; mask; mask >>= 1) { + SM16716_SendBit(v & mask); + } +} + +void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) +{ +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Update; rgb=%02x%02x%02x"), + duty_r, duty_g, duty_b); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + + // send start bit + SM16716_SendBit(1); + // send 24-bit rgb data + SM16716_SendByte(duty_r); + SM16716_SendByte(duty_g); + SM16716_SendByte(duty_g); + // send a 'do it' pulse + // (if multiple chips are chained, each one processes the 1st '1rgb' 25-bit block and + // passes on the rest, right until the one starting with 0) + SM16716_SendBit(0); + SM16716_SendByte(0); + SM16716_SendByte(0); + SM16716_SendByte(0); + SM16716_Show_State(); +} + +bool SM16716_ModuleSelected(void) +{ + sm16716_pin_clk = pin[GPIO_SM16716_CLK]; + sm16716_pin_dat = pin[GPIO_SM16716_DAT]; +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), + sm16716_pin_clk, sm16716_pin_dat); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + return (sm16716_pin_clk < 99) && (sm16716_pin_dat < 99); +} + +bool SM16716_Init(void) +{ + uint8_t t_init; + + pinMode(sm16716_pin_clk, OUTPUT); + digitalWrite(sm16716_pin_clk, LOW); + + pinMode(sm16716_pin_dat, OUTPUT); + digitalWrite(sm16716_pin_dat, LOW); + + for (t_init = 0; t_init < 50; ++t_init) { + SM16716_SendBit(0); + } + + return true; +} + /********************************************************************************************/ void LightInit(void) @@ -402,6 +498,11 @@ void LightInit(void) max_scheme = LS_MAX + WS2812_SCHEMES; } #endif // USE_WS2812 ************************************************************************ +#ifdef USE_SM16716 + else if (16 & light_type) { + SM16716_Init(); + } +#endif // ifdef USE_SM16716 else { light_pdi_pin = pin[GPIO_DI]; light_pdcki_pin = pin[GPIO_DCKI]; @@ -844,6 +945,11 @@ void LightAnimate(void) Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2], cur_col[3]); } #endif // USE_ES2812 ************************************************************************ +#ifdef USE_SM16716 + else if (16 & light_type) { + SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); + } +#endif // ifdef USE_SM16716 else if (light_type > LT_WS2812) { LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); } diff --git a/sonoff/xdrv_20_sm16717.ino b/sonoff/xdrv_20_sm16717.ino deleted file mode 100644 index 1dada4c9ca89..000000000000 --- a/sonoff/xdrv_20_sm16717.ino +++ /dev/null @@ -1,400 +0,0 @@ -/* - xdrv_20_sm16716.ino - SM16716 RGB led controller support for Sonoff-Tasmota - - Copyright (C) 2019 Gabor Simon - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_SM16716 - -/*********************************************************************************************\ - * SM16716 - Controlling RGB over a synchronous serial line - * - * Source: https://community.home-assistant.io/t/cheap-uk-wifi-bulbs-with-tasmota-teardown-help-tywe3s/40508/27 - * -\*********************************************************************************************/ - -#define XDRV_20 20 - -// Enable this for debug logging -//#define D_LOG_SM16716 "SM16716: " - -enum SM16716_Commands { - CMND_SM16716_COLOR }; - -const char k_SM16716_Commands[] PROGMEM = - D_CMND_COLOR ; - -uint8_t sm16716_pin_clk = 100; -uint8_t sm16716_pin_dat = 100; - -bool sm16716_is_selected = false; -bool sm16716_is_on = false; -uint8_t sm16716_color[3] = {0, 0, 0}; -int8_t sm16716_color_preset = 0; - - -/*********************************************************************************************/ -void SM16716_SendBit(uint8_t v) -{ - /* NOTE: - * According to the spec sheet, max freq is 30 MHz, that is 16.6 ns per high/low half of the - * clk square wave. That is less than the overhead of 'digitalWrite' at this clock rate, - * so no additional delays are needed yet. */ - - digitalWrite(sm16716_pin_dat, (v != 0) ? HIGH : LOW); - //delayMicroseconds(1); - digitalWrite(sm16716_pin_clk, HIGH); - //delayMicroseconds(1); - digitalWrite(sm16716_pin_clk, LOW); -} - - -/*********************************************************************************************/ -void SM16716_SendByte(uint8_t v) -{ - uint8_t mask; - - for (mask = 0x80; mask; mask >>= 1) { - SM16716_SendBit(v & mask); - } -} - - -/*********************************************************************************************/ -void SM16716_Append_JSON(void) -{ - snprintf_P(mqtt_data, sizeof(mqtt_data), - PSTR("%s,\"SM16716\":{\"Red\":%d,\"Green\":%d,\"Blue\":%d}"), - mqtt_data, sm16716_color[0], sm16716_color[1], sm16716_color[2]); -} - - -/*********************************************************************************************/ -bool SM16716_Show_State(void) -{ - snprintf_P(mqtt_data, sizeof(mqtt_data), - PSTR("{\"" D_CMND_COLOR "\":\"%02x%02x%02x\"}"), - sm16716_color[0], sm16716_color[1], sm16716_color[2]); - return true; -} - - -/*********************************************************************************************/ -void SM16716_Update() -{ -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Update; pwr=%02x, rgb=%02x%02x%02x"), - sm16716_is_on, sm16716_color[0], sm16716_color[1], sm16716_color[2]); - AddLog(LOG_LEVEL_DEBUG); -#endif // D_LOG_SM16716 - - // send start bit - SM16716_SendBit(1); - // send 24-bit rgb data - if (sm16716_is_on) { - SM16716_SendByte(sm16716_color[0]); - SM16716_SendByte(sm16716_color[1]); - SM16716_SendByte(sm16716_color[2]); - } - else { - SM16716_SendByte(0); - SM16716_SendByte(0); - SM16716_SendByte(0); - } - // send a 'do it' pulse - // (if multiple chips are chained, each one processes the 1st '1rgb' 25-bit block and - // passes on the rest, right until the one starting with 0) - SM16716_SendBit(0); - SM16716_SendByte(0); - SM16716_SendByte(0); - SM16716_SendByte(0); - SM16716_Show_State(); -} - - -/*********************************************************************************************/ -bool SM16716_ModuleSelected(void) -{ - sm16716_pin_clk = pin[GPIO_SM16716_CLK]; - sm16716_pin_dat = pin[GPIO_SM16716_DAT]; -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), - sm16716_pin_clk, sm16716_pin_dat); - AddLog(LOG_LEVEL_DEBUG); -#endif // D_LOG_SM16716 - sm16716_is_selected = (sm16716_pin_clk < 99) && (sm16716_pin_dat < 99); - return sm16716_is_selected; -} - - -/*********************************************************************************************/ -bool SM16716_Init(void) -{ - uint8_t t_init; - - if (!SM16716_ModuleSelected()) { - return false; - } - - pinMode(sm16716_pin_clk, OUTPUT); - digitalWrite(sm16716_pin_clk, LOW); - - pinMode(sm16716_pin_dat, OUTPUT); - digitalWrite(sm16716_pin_dat, LOW); - - for (t_init = 0; t_init < 50; ++t_init) { - SM16716_SendBit(0); - } - - return true; -} - - -/*********************************************************************************************/ -/* Try to parse a string as 'RRGGBB' hex-encoded color value - * Accept only exact match (i.e. there can be no leftover chars) - */ -bool SM16716_Parse_RRGGBB(const char *data, int data_len) { - char component[3]; - char *endptr = NULL; - uint8_t candidate[3]; - int i; - -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Parse_RRGGBB; data='%s', data_len=%d"), - data, data_len); - AddLog(LOG_LEVEL_DEBUG); -#endif // D_LOG_SM16716 - - if (data_len != 6) { - // too long or too short - return false; - } - - // a component is exactly 3 chars, so terminate the string now - component[2] = '\0'; - - // try to parse 3 components - for (i = 0; i < 3; ++i) { - // copy the value to the temp string - component[0] = data[0]; - component[1] = data[1]; - // try to interpret it as a hex number - candidate[i] = (uint8_t)strtoul(component, &endptr, 16); - if (!endptr || *endptr) { - // not a valid hex number - return false; - } - // advance to the next 2 characters - data += 2; - } - - // now that we have all 3, we may change sm16716_color[] - sm16716_color[0] = candidate[0]; - sm16716_color[1] = candidate[1]; - sm16716_color[2] = candidate[2]; - return true; -} - - -/*********************************************************************************************/ -bool SM16716_Parse_Color(char *data, int data_len) { - /* NOTE: Very similar to 'LightColorEntry', but can't reuse it here, because - * 'light_type' must be PWM, and then it won't parse the color components. */ - -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Parse_Color; data='%s', data_len=%d"), - data, data_len); - AddLog(LOG_LEVEL_DEBUG); -#endif // D_LOG_SM16716 - - if (data_len < 3) { // too short for color literal: try to interpret as a color preset - // check for '+' and '-' commands first - switch (data[0]) { - case '+': // advance to the next preset, handle wrap-around - ++sm16716_color_preset; - if (sm16716_color_preset >= MAX_FIXED_COLOR) { - sm16716_color_preset = 0; - } - break; - - case '-': // return to the previous preset, handle wrap-around - --sm16716_color_preset; - if (sm16716_color_preset < 0) { - sm16716_color_preset = MAX_FIXED_COLOR - 1; - } - break; - - default: - // try to interpret it as a decimal integer - { - char *endptr = NULL; - uint8_t candidate = (uint8_t)strtoul(data, &endptr, 10); - if (!endptr || *endptr || (candidate < 0) || (MAX_FIXED_COLOR <= candidate)) { - // it's not a valid integer (and nothing else), or the number is not a valid preset index - return false; - } - // we have the requested preset index - sm16716_color_preset = candidate; - } - break; - } - -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Parse_Color; preset=%d"), - sm16716_color_preset); - AddLog(LOG_LEVEL_DEBUG); -#endif // D_LOG_SM16716 - - // copy the requested preset values - memcpy_P(sm16716_color, &kFixedColor[sm16716_color_preset], 3); - } - else if (data[0] == '#') { // starts with #, so try to interpret as #RRGGBB - if (!SM16716_Parse_RRGGBB(data + 1, data_len - 1)) { - // not a valid RRGGBB after the # - return false; - } - } - // two more formats left: RRGGBB (without #) and comma separated color components - else if (SM16716_Parse_RRGGBB(data, data_len)) { // try to interpret as RRGGBB - // parsed successfully as RRGGBB, nothing more to do - } - else { // try to interpret as rrr,g,bb - uint8_t candidate[3]; - char *tok, *last, *endptr = NULL; - int i; - - // try to parse the first 3 comma-separated tokens - for (i = 0; i < 3; ++i) { - // try to isolate the next token - tok = strtok_r(data, ",", &last); - if (!tok) { - // we're beyond the end of string: there were too few tokens - return false; - } - // try to interpret the token as integer - candidate[i] = (uint8_t)strtoul(tok, &endptr, 0); - if (!endptr || *endptr) { - // not a valid integer - return false; - } - // in the next cycle just continue this token-processing session - data = NULL; - } - // there shouldn't be any leftover characters (i.e. we need exactly 3 components) - tok = strtok_r(NULL, ",", &last); - if (tok) { - // too many components - return false; - } - // now that we have all 3 components, we may change sm16716_color - sm16716_color[0] = candidate[0]; - sm16716_color[1] = candidate[1]; - sm16716_color[2] = candidate[2]; - } - return true; -} - - -/*********************************************************************************************/ -bool SM16716_Command(void) -{ - char command [CMDSZ]; - int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, k_SM16716_Commands); - -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Command; topic='%s', data_len=%d, data='%s', code=%d"), - XdrvMailbox.topic, XdrvMailbox.data_len, XdrvMailbox.data, command_code); - AddLog(LOG_LEVEL_DEBUG); -#endif // D_LOG_SM16716 - - switch (command_code) { - case CMND_SM16716_COLOR: - if (XdrvMailbox.data_len == 0) { - return SM16716_Show_State(); - } - if (!SM16716_Parse_Color(XdrvMailbox.data, XdrvMailbox.data_len)) { - return false; - } - SM16716_Update(); - return true; - } - return false; // Unknown command -} - - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ -bool Xdrv20(uint8_t function) -{ - if (function == FUNC_MODULE_INIT) { - return SM16716_ModuleSelected(); - } - - if (!sm16716_is_selected) { - return false; - } - - switch (function) { - case FUNC_INIT: -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Entry; function=FUNC_INIT")); - AddLog(LOG_LEVEL_DEBUG); -#endif - return SM16716_Init(); - - case FUNC_COMMAND: -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Entry; function=FUNC_COMMAND")); - AddLog(LOG_LEVEL_DEBUG); -#endif - return SM16716_Command(); - - //case FUNC_SET_POWER: - case FUNC_SET_DEVICE_POWER: -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Entry; function=FUNC_SET_DEVICE_POWER, index=%02x, payload=%02x"), - XdrvMailbox.index, XdrvMailbox.payload); - AddLog(LOG_LEVEL_DEBUG); -#endif - sm16716_is_on = (XdrvMailbox.index != 0); - SM16716_Update(); - return false; // don't catch the event - - case FUNC_JSON_APPEND: -#ifdef D_LOG_SM16716 - snprintf_P(log_data, sizeof(log_data), - PSTR(D_LOG_SM16716 "Entry; function=FUNC_JSON_APPEND")); - AddLog(LOG_LEVEL_DEBUG); -#endif - SM16716_Append_JSON(); - break; - } - return false; -} - -#endif // USE_SM16716 -// vim: set ft=c sw=2 ts=2 et: From fa7440fb9afca4baa2db8fb6d83d622e8ebc90ef Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 30 Jan 2019 17:28:25 -0500 Subject: [PATCH 08/24] Allow PWM while SM16716 is enabled, for mixed control devices --- sonoff/xdrv_04_light.ino | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 2dc098c80f5b..90ef446ae16e 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -500,6 +500,13 @@ void LightInit(void) #endif // USE_WS2812 ************************************************************************ #ifdef USE_SM16716 else if (16 & light_type) { + // init PWM + for (uint8_t i = 0; i < light_subtype; i++) { + Settings.pwm_value[i] = 0; // Disable direct PWM control + if (pin[GPIO_PWM1 +i] < 99) { + pinMode(pin[GPIO_PWM1 +i], OUTPUT); + } + } SM16716_Init(); } #endif // ifdef USE_SM16716 @@ -919,7 +926,7 @@ void LightAnimate(void) light_last_color[i] = light_new_color[i]; cur_col[i] = light_last_color[i]*Settings.rgbwwTable[i]/255; cur_col[i] = (Settings.light_correction) ? ledTable[cur_col[i]] : cur_col[i]; - if (light_type < LT_PWM6) { + if (light_type < LT_PWM6 || light_type & 16) { if (pin[GPIO_PWM1 +i] < 99) { if (cur_col[i] > 0xFC) { cur_col[i] = 0xFC; // Fix unwanted blinking and PWM watchdog errors for values close to pwm_range (H801, Arilux and BN-SZ01) From ec984ab841d605225d33c723682da5de6f715d53 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 30 Jan 2019 17:32:17 -0500 Subject: [PATCH 09/24] Fixed compiler errors Missing #endif oops Vestigial function call --- sonoff/xdrv_04_light.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 90ef446ae16e..b60d0e64bb3a 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -417,7 +417,6 @@ void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) SM16716_SendByte(0); SM16716_SendByte(0); SM16716_SendByte(0); - SM16716_Show_State(); } bool SM16716_ModuleSelected(void) @@ -450,6 +449,8 @@ bool SM16716_Init(void) return true; } +#endif // ifdef USE_SM16716 + /********************************************************************************************/ void LightInit(void) From adcfeeaed5923307c857a5d7b87f5df9a1d6f0b1 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 30 Jan 2019 17:57:47 -0500 Subject: [PATCH 10/24] Fixed bug in web config page caused by merge from dev --- sonoff/sonoff_template.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index e050dc882354..809b0e390682 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -221,7 +221,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|" D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" D_SENSOR_BUTTON "1i|" D_SENSOR_BUTTON "2i|" D_SENSOR_BUTTON "3i|" D_SENSOR_BUTTON "4i|" - D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in" + D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in|" D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT ; From 4b6ddfb76f3a188a12618ecf95e0a95a66bfa939 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 30 Jan 2019 18:15:25 -0500 Subject: [PATCH 11/24] Moved PWM control to its own block while using SM16716 to skip RGB values --- sonoff/xdrv_04_light.ino | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index b60d0e64bb3a..d58207331c85 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -367,7 +367,7 @@ void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t dut \*********************************************************************************************/ // Enable this for debug logging -//#define D_LOG_SM16716 "SM16716: " +#define D_LOG_SM16716 "SM16716: " uint8_t sm16716_pin_clk = 100; uint8_t sm16716_pin_dat = 100; @@ -927,7 +927,7 @@ void LightAnimate(void) light_last_color[i] = light_new_color[i]; cur_col[i] = light_last_color[i]*Settings.rgbwwTable[i]/255; cur_col[i] = (Settings.light_correction) ? ledTable[cur_col[i]] : cur_col[i]; - if (light_type < LT_PWM6 || light_type & 16) { + if (light_type < LT_PWM6) { if (pin[GPIO_PWM1 +i] < 99) { if (cur_col[i] > 0xFC) { cur_col[i] = 0xFC; // Fix unwanted blinking and PWM watchdog errors for values close to pwm_range (H801, Arilux and BN-SZ01) @@ -956,6 +956,17 @@ void LightAnimate(void) #ifdef USE_SM16716 else if (16 & light_type) { SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); + for (uint8_t i = 3; i < light_subtype; i++) { + if (pin[GPIO_PWM1 +i-3] < 99) { + if (cur_col[i] > 0xFC) { + cur_col[i] = 0xFC; // Fix unwanted blinking and PWM watchdog errors for values close to pwm_range (H801, Arilux and BN-SZ01) + } + uint16_t curcol = cur_col[i] * (Settings.pwm_range / 255); +// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "Cur_Col%d %d, CurCol %d"), i, cur_col[i], curcol); +// AddLog(LOG_LEVEL_DEBUG); + analogWrite(pin[GPIO_PWM1 +i-3], bitRead(pwm_inverted, i-3) ? Settings.pwm_range - curcol : curcol); + } + } } #endif // ifdef USE_SM16716 else if (light_type > LT_WS2812) { From f60dd3c06aff4612f0fd663e4717d5af77ddcf0a Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 30 Jan 2019 18:32:37 -0500 Subject: [PATCH 12/24] Moved pin mode selection for sm16716 out of init function Made void Call SM16716_Init before setting the color --- sonoff/xdrv_04_light.ino | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index d58207331c85..0591da5bbb81 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -432,21 +432,11 @@ bool SM16716_ModuleSelected(void) return (sm16716_pin_clk < 99) && (sm16716_pin_dat < 99); } -bool SM16716_Init(void) +void SM16716_Init(void) { - uint8_t t_init; - - pinMode(sm16716_pin_clk, OUTPUT); - digitalWrite(sm16716_pin_clk, LOW); - - pinMode(sm16716_pin_dat, OUTPUT); - digitalWrite(sm16716_pin_dat, LOW); - - for (t_init = 0; t_init < 50; ++t_init) { + for (uint8_t t_init = 0; t_init < 50; ++t_init) { SM16716_SendBit(0); } - - return true; } #endif // ifdef USE_SM16716 @@ -508,6 +498,13 @@ void LightInit(void) pinMode(pin[GPIO_PWM1 +i], OUTPUT); } } + // init sm16716 + pinMode(sm16716_pin_clk, OUTPUT); + digitalWrite(sm16716_pin_clk, LOW); + + pinMode(sm16716_pin_dat, OUTPUT); + digitalWrite(sm16716_pin_dat, LOW); + SM16716_Init(); } #endif // ifdef USE_SM16716 @@ -955,7 +952,6 @@ void LightAnimate(void) #endif // USE_ES2812 ************************************************************************ #ifdef USE_SM16716 else if (16 & light_type) { - SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); for (uint8_t i = 3; i < light_subtype; i++) { if (pin[GPIO_PWM1 +i-3] < 99) { if (cur_col[i] > 0xFC) { @@ -967,6 +963,10 @@ void LightAnimate(void) analogWrite(pin[GPIO_PWM1 +i-3], bitRead(pwm_inverted, i-3) ? Settings.pwm_range - curcol : curcol); } } + if(cur_col[0] | cur_col[1] | cur_col[2]){ + SM16716_Init(); + } + SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); } #endif // ifdef USE_SM16716 else if (light_type > LT_WS2812) { From 1c76991c7fb3c89d7ca5b1dd4349bd47a0e54e68 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Thu, 31 Jan 2019 13:28:38 -0500 Subject: [PATCH 13/24] Added sm16716 select to the pin definitions --- sonoff/language/bg-BG.h | 1 + sonoff/language/cs-CZ.h | 1 + sonoff/language/de-DE.h | 1 + sonoff/language/el-GR.h | 1 + sonoff/language/en-GB.h | 1 + sonoff/language/es-AR.h | 1 + sonoff/language/fr-FR.h | 1 + sonoff/language/he-HE.h | 1 + sonoff/language/hu-HU.h | 1 + sonoff/language/it-IT.h | 1 + sonoff/language/nl-NL.h | 1 + sonoff/language/pl-PL.h | 1 + sonoff/language/pt-BR.h | 1 + sonoff/language/pt-PT.h | 1 + sonoff/language/ru-RU.h | 1 + sonoff/language/sk-SK.h | 1 + sonoff/language/sv-SE.h | 1 + sonoff/language/tr-TR.h | 1 + sonoff/language/uk-UK.h | 1 + sonoff/language/zh-CN.h | 1 + sonoff/language/zh-TW.h | 1 + sonoff/sonoff_template.h | 12 +++++++----- 22 files changed, 28 insertions(+), 5 deletions(-) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 03c1b9f32737..6c3f4556a768 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index c87260f7105a..38c80d158b64 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 692c74e1761e..607c781da581 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 81a017a0bcd6..0a385a96664d 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 9644e8b4d29f..34dc71c4a4e6 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index a2f8bcf8aaf9..597be23dbd77 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index b9fa0d423461..41da8c8956af 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index 22f9677b5fe2..96c14b0e50ad 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index b6dd5b55ab2e..628a1277025e 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index fa3c0b533ebf..90a9670571fb 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 684545acf5f6..cb3c9913cc2e 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 8e677b5546d8..1e50d2f6b101 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 1d708f0726e0..f86addf8eb6e 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index baa0e28a5f7e..8d8f1bb8d54a 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index 19c09a7fc48d..9064b14074c3 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sk-SK.h b/sonoff/language/sk-SK.h index e2551f9bc72f..b778d45a5066 100644 --- a/sonoff/language/sk-SK.h +++ b/sonoff/language/sk-SK.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index 2b7b672a45dd..4955640514a0 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index bdab28afbcdb..d55b02899689 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 4e3c255d5163..8c6d82a10aba 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index d4ff8eba8041..0d8a4012dde9 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 186c5bae3126..cd1e503ec942 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -546,6 +546,7 @@ #define D_SENSOR_MAX31855_DO "MAX31855 DO" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_SEL "SM16716 SEL" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 809b0e390682..0ad920b27227 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -154,8 +154,9 @@ enum UserSelectablePins { GPIO_KEY2_INV_NP, GPIO_KEY3_INV_NP, GPIO_KEY4_INV_NP, - GPIO_SM16716_CLK, // SM16716 CLK - GPIO_SM16716_DAT, // SM16716 DAT + GPIO_SM16716_CLK, // SM16716 CLOCK + GPIO_SM16716_DAT, // SM16716 DATA + GPIO_SM16716_SEL, // SM16716 SELECT GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -222,7 +223,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" D_SENSOR_BUTTON "1i|" D_SENSOR_BUTTON "2i|" D_SENSOR_BUTTON "3i|" D_SENSOR_BUTTON "4i|" D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in|" - D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT + D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_SEL ; /********************************************************************************************/ @@ -530,8 +531,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_MAX31855DO, // MAX31855 Serial interface #endif #ifdef USE_SM16716 - GPIO_SM16716_CLK, // SM16716 CLK - GPIO_SM16716_DAT, // SM16716 DAT + GPIO_SM16716_CLK, // SM16716 CLOCK + GPIO_SM16716_DAT, // SM16716 DATA + GPIO_SM16716_SEL, // SM16716 SELECT #endif // USE_SM16716 }; From 04f1ed1659240092e1cfc987d0f5e811c5310884 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Thu, 31 Jan 2019 17:17:01 -0500 Subject: [PATCH 14/24] Implemented sm16716 select If SM16716_SEL is specified, it will toggle it on/off depending on whether or not there is color data --- sonoff/xdrv_04_light.ino | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 0591da5bbb81..9cb22d698fcf 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -371,6 +371,7 @@ void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t dut uint8_t sm16716_pin_clk = 100; uint8_t sm16716_pin_dat = 100; +uint8_t sm16716_pin_sel = 100; void SM16716_SendBit(uint8_t v) { @@ -397,6 +398,23 @@ void SM16716_SendByte(uint8_t v) void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) { + if (sm16716_pin_sel < 99) { + if (duty_r | duty_g | duty_b) { +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "turning color on")); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + digitalWrite(sm16716_pin_sel, HIGH); + delayMicroseconds(20); + SM16716_Init(); + } else { +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "turning color off")); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + digitalWrite(sm16716_pin_sel, LOW); + } + } #ifdef D_LOG_SM16716 snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "Update; rgb=%02x%02x%02x"), @@ -409,10 +427,11 @@ void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) // send 24-bit rgb data SM16716_SendByte(duty_r); SM16716_SendByte(duty_g); - SM16716_SendByte(duty_g); + SM16716_SendByte(duty_b); // send a 'do it' pulse // (if multiple chips are chained, each one processes the 1st '1rgb' 25-bit block and // passes on the rest, right until the one starting with 0) + //SM16716_Init(); SM16716_SendBit(0); SM16716_SendByte(0); SM16716_SendByte(0); @@ -423,6 +442,7 @@ bool SM16716_ModuleSelected(void) { sm16716_pin_clk = pin[GPIO_SM16716_CLK]; sm16716_pin_dat = pin[GPIO_SM16716_DAT]; + sm16716_pin_sel = pin[GPIO_SM16716_SEL]; #ifdef D_LOG_SM16716 snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), @@ -505,6 +525,11 @@ void LightInit(void) pinMode(sm16716_pin_dat, OUTPUT); digitalWrite(sm16716_pin_dat, LOW); + if (sm16716_pin_sel < 99) { + pinMode(sm16716_pin_sel, OUTPUT); + digitalWrite(sm16716_pin_sel, LOW); + } + SM16716_Init(); } #endif // ifdef USE_SM16716 @@ -963,9 +988,6 @@ void LightAnimate(void) analogWrite(pin[GPIO_PWM1 +i-3], bitRead(pwm_inverted, i-3) ? Settings.pwm_range - curcol : curcol); } } - if(cur_col[0] | cur_col[1] | cur_col[2]){ - SM16716_Init(); - } SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); } #endif // ifdef USE_SM16716 From ef40aff62a25f86a32888abe485743b6ba1779e9 Mon Sep 17 00:00:00 2001 From: Gabor Simon Date: Fri, 1 Feb 2019 04:37:22 +0000 Subject: [PATCH 15/24] Added SM16716_SEL pin to SYF05 template, enabled SM16716 support --- sonoff/my_user_config.h | 2 ++ sonoff/sonoff_template.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 83bbb7b6514b..92f2a6d86987 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -416,6 +416,8 @@ // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) // #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 weather stations using 868MHz RF sensor receiver (+1k7 code) +#define USE_SM16716 // Add support for SM16716 RGB LED controller + /*********************************************************************************************\ * Debug features are only supported in development branch \*********************************************************************************************/ diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 0ad920b27227..115e999cf588 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -1822,7 +1822,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, // GPIO10 // GPIO11 GPIO_PWM2, // GPIO12 Warm White - GPIO_USER, // GPIO13 N.C. (used as LED if you add it) + GPIO_SM16716_SEL, // GPIO13 GPIO_SM16716_DAT, // GPIO14 0, // GPIO15 wired to GND GPIO_USER, // GPIO16 N.C. From 25856c323a834cead4d412402ed77563adfc236f Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 1 Feb 2019 00:59:53 -0500 Subject: [PATCH 16/24] Track sm16716 select pin state so we don't waste cycles continuously enabling/disabling color Added some comments; disabled sm16716 debug messages by default Removed delay after setting select pin; didn't seem to help anyway --- sonoff/xdrv_04_light.ino | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 9cb22d698fcf..4a6c21389222 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -367,11 +367,12 @@ void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t dut \*********************************************************************************************/ // Enable this for debug logging -#define D_LOG_SM16716 "SM16716: " +//#define D_LOG_SM16716 "SM16716: " uint8_t sm16716_pin_clk = 100; uint8_t sm16716_pin_dat = 100; uint8_t sm16716_pin_sel = 100; +uint8_t sm16716_enabled = 0; void SM16716_SendBit(uint8_t v) { @@ -399,19 +400,23 @@ void SM16716_SendByte(uint8_t v) void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) { if (sm16716_pin_sel < 99) { - if (duty_r | duty_g | duty_b) { + uint8_t sm16716_should_enable = (duty_r | duty_g | duty_b); + if (!sm16716_enabled && sm16716_should_enable) { #ifdef D_LOG_SM16716 snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "turning color on")); AddLog(LOG_LEVEL_DEBUG); #endif // D_LOG_SM16716 + sm16716_enabled = 1; digitalWrite(sm16716_pin_sel, HIGH); - delayMicroseconds(20); + //delayMicroseconds(20); SM16716_Init(); - } else { + } + else if (sm16716_enabled && !sm16716_should_enable) { #ifdef D_LOG_SM16716 snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "turning color off")); AddLog(LOG_LEVEL_DEBUG); #endif // D_LOG_SM16716 + sm16716_enabled = 0; digitalWrite(sm16716_pin_sel, LOW); } } @@ -977,6 +982,7 @@ void LightAnimate(void) #endif // USE_ES2812 ************************************************************************ #ifdef USE_SM16716 else if (16 & light_type) { + // handle any PWM pins, skipping the first 3 values for sm16716 for (uint8_t i = 3; i < light_subtype; i++) { if (pin[GPIO_PWM1 +i-3] < 99) { if (cur_col[i] > 0xFC) { @@ -988,6 +994,7 @@ void LightAnimate(void) analogWrite(pin[GPIO_PWM1 +i-3], bitRead(pwm_inverted, i-3) ? Settings.pwm_range - curcol : curcol); } } + // handle sm16716 update SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); } #endif // ifdef USE_SM16716 From 99b027852b145e27b93a7f7fdd3f933d95d01c22 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 1 Feb 2019 17:33:21 -0500 Subject: [PATCH 17/24] Fixed first color command failing; need to wait for chip to power up --- sonoff/xdrv_04_light.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 4a6c21389222..ba12ac3db64d 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -408,7 +408,9 @@ void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) #endif // D_LOG_SM16716 sm16716_enabled = 1; digitalWrite(sm16716_pin_sel, HIGH); - //delayMicroseconds(20); + // in testing I found it takes a minimum of ~380us to wake up the chip + // tested on a Merkury RGBW with an SM726EB + delayMicroseconds(400); SM16716_Init(); } else if (sm16716_enabled && !sm16716_should_enable) { From 817d0af598d887c7105e7d023f840d4f23762d87 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 1 Feb 2019 17:37:37 -0500 Subject: [PATCH 18/24] No need (and pointless) to call SM16716_Init until color updates, iff using sel pin --- sonoff/xdrv_04_light.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index ba12ac3db64d..f65dd43da82b 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -535,9 +535,11 @@ void LightInit(void) if (sm16716_pin_sel < 99) { pinMode(sm16716_pin_sel, OUTPUT); digitalWrite(sm16716_pin_sel, LOW); + // no need to call SM16716_Init here, it will be called after sel goes HIGH + } else { + // no sel pin means you have an 'always on' chip, so init right away + SM16716_Init(); } - - SM16716_Init(); } #endif // ifdef USE_SM16716 else { From 6d19a9c998eb6a4da0692836d420628b96d6ccfc Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 1 Feb 2019 19:28:16 -0500 Subject: [PATCH 19/24] Generalize the SYF05 a tiny bit so it can be easily adapted to similar bulbs --- sonoff/sonoff_template.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 80155a7c125d..e57cd54cfd68 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -1827,6 +1827,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, 0, 0 }, { "SYF05", // Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726 + // Also works with Merkury 904 RGBW Bulbs with 13 set to GPIO_SM16716_SEL // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771 @@ -1834,17 +1835,17 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, GPIO_USER, // GPIO02 N.C. 0, - GPIO_SM16716_CLK, // GPIO04 - GPIO_PWM1, // GPIO05 Cold White + GPIO_SM16716_CLK, // GPIO04 SM16716 Clock + GPIO_PWM1, // GPIO05 White // GPIO06 // GPIO07 // GPIO08 0, // GPIO09 0, // GPIO10 // GPIO11 - GPIO_PWM2, // GPIO12 Warm White - GPIO_SM16716_SEL, // GPIO13 - GPIO_SM16716_DAT, // GPIO14 + GPIO_USER, // GPIO12 Alt. White on some devices + GPIO_USER, // GPIO13 SM16716 Select on some devices + GPIO_SM16716_DAT, // GPIO14 SM16716 Data 0, // GPIO15 wired to GND GPIO_USER, // GPIO16 N.C. GPIO_FLAG_ADC0 // ADC0 A0 Analog input From d7b8a6453dbea52a6006d1e2c62593365dd39376 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 1 Feb 2019 19:41:12 -0500 Subject: [PATCH 20/24] Added preprocessor constant for LT_SM16716 for improved code readability Note that this differs from other LT_* in that it's not an enum Ensure the SM16716 codepath is only taken when the top half of light_type is LT_SM16716 --- sonoff/sonoff.h | 2 ++ sonoff/sonoff.ino | 2 +- sonoff/xdrv_04_light.ino | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 9ba91f09185c..b54a32f3c0b8 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -168,6 +168,8 @@ typedef unsigned long power_t; // Power (Relay) type #define NEO_RGBW 5 // Neopixel RGBW leds #define NEO_GRBW 6 // Neopixel GRBW leds +#define LT_SM16716 16 // Lights that use SM16716 will have this bit set in light_type + #define MQTT_PUBSUBCLIENT 1 // Mqtt PubSubClient library #define MQTT_TASMOTAMQTT 2 // Mqtt TasmotaMqtt library based on esp-mqtt-arduino - soon obsolete #define MQTT_ESPMQTTARDUINO 3 // Mqtt esp-mqtt-arduino library by Ingo Randolf - obsolete but define is present for debugging purposes diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 694f7d4c9eac..7be59f746e9b 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2425,7 +2425,7 @@ void GpioInit(void) #ifdef USE_SM16716 if (SM16716_ModuleSelected()) { light_type += 3; - light_type |= 16; + light_type |= LT_SM16716; } #endif // ifdef USE_SM16716 if (!light_type) { diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index f65dd43da82b..bc4a9b91cb26 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -517,7 +517,7 @@ void LightInit(void) } #endif // USE_WS2812 ************************************************************************ #ifdef USE_SM16716 - else if (16 & light_type) { + else if (LT_SM16716 == light_type - light_subtype) { // init PWM for (uint8_t i = 0; i < light_subtype; i++) { Settings.pwm_value[i] = 0; // Disable direct PWM control @@ -985,7 +985,7 @@ void LightAnimate(void) } #endif // USE_ES2812 ************************************************************************ #ifdef USE_SM16716 - else if (16 & light_type) { + else if (LT_SM16716 == light_type - light_subtype) { // handle any PWM pins, skipping the first 3 values for sm16716 for (uint8_t i = 3; i < light_subtype; i++) { if (pin[GPIO_PWM1 +i-3] < 99) { From 35060dfa45cb84c248c1930f522dc51f0f23b41e Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 1 Feb 2019 20:12:13 -0500 Subject: [PATCH 21/24] Measured impact of USE_SM16716 on binary filesize --- sonoff/my_user_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index c914e55679f9..d06b0c85454f 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -417,7 +417,7 @@ // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) // #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 weather stations using 868MHz RF sensor receiver (+1k7 code) -#define USE_SM16716 // Add support for SM16716 RGB LED controller +#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code) /*********************************************************************************************\ * Debug features are only supported in development branch From 1bf7d32544884fea76a509de219bc60cc34cad41 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Wed, 6 Feb 2019 18:51:54 -0500 Subject: [PATCH 22/24] Renamed SM16716 Select to SM16716 Enable to avoid confusion with a SM16726 feature also called select --- sonoff/language/bg-BG.h | 2 +- sonoff/language/cs-CZ.h | 2 +- sonoff/language/de-DE.h | 2 +- sonoff/language/el-GR.h | 2 +- sonoff/language/en-GB.h | 2 +- sonoff/language/es-AR.h | 2 +- sonoff/language/fr-FR.h | 2 +- sonoff/language/he-HE.h | 2 +- sonoff/language/hu-HU.h | 2 +- sonoff/language/it-IT.h | 2 +- sonoff/language/nl-NL.h | 2 +- sonoff/language/pl-PL.h | 2 +- sonoff/language/pt-BR.h | 2 +- sonoff/language/pt-PT.h | 2 +- sonoff/language/ru-RU.h | 2 +- sonoff/language/sk-SK.h | 2 +- sonoff/language/sv-SE.h | 2 +- sonoff/language/tr-TR.h | 2 +- sonoff/language/uk-UK.h | 2 +- sonoff/language/zh-CN.h | 2 +- sonoff/language/zh-TW.h | 2 +- sonoff/sonoff_template.h | 4 ++-- 22 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 3b0aa8a20fa9..b04271a7f5ff 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Активиране на SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index c7cfcd99f3d6..caf213296ab3 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Povol SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 74be66eac453..2c2b48d5e319 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "SM16716 aktivieren" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 03bc7dc4e5a9..faa5f0ec2a58 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Ενεργοποίηση SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 249bb66c553b..a4acbf38d367 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Enable SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 19988b248e0b..075c8bbf587e 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Habilitar SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 27623806d0c2..a75205c26c81 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Activer SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index a4cee77c53ff..031635c15fc4 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Enable SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 89adb73e60ae..3d8cc88504db 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "SM16716 engedélyezése" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 7b0801056a5a..c2b3a60c37af 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Abilita SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 6aa5ee7c3fa6..c9a0e4715476 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -556,7 +556,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "SM16716 inschakelen" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index fa38c7887c59..1ad8e5546bd3 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -556,7 +556,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Włącz SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index af3d109745bf..e3f61775a3d0 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Habilitar SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index e868601cb570..e9b3c470ead4 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Enable SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index b7e079a76172..a0a0953e919c 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Enable SM16716" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sk-SK.h b/sonoff/language/sk-SK.h index 4b14e8c3d0cc..f1e6495c9761 100644 --- a/sonoff/language/sk-SK.h +++ b/sonoff/language/sk-SK.h @@ -556,7 +556,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Povoľ SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index fe8f4231bb59..961637b357d1 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Aktivera SM16716" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index a307f84f1b56..1302595cf15e 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "SM16716 Aktif" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 1ddea2efd168..5a2aad11b70c 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Увімкнений SM16716" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index c362fd86a8a0..3f24ab2ae3d5 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "启用 SM16716" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 105ca749feab..be91648d2f3e 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -555,7 +555,7 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_SEL "SM16716 SEL" +#define D_SENSOR_SM16716_POWER "Enable SM16716" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 561750a716ca..12f9a924194c 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -230,7 +230,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in|" D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" - D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_SEL + D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER ; /********************************************************************************************/ @@ -1892,7 +1892,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, // GPIO10 // GPIO11 GPIO_USER, // GPIO12 Alt. White on some devices - GPIO_USER, // GPIO13 SM16716 Select on some devices + GPIO_USER, // GPIO13 SM16716 Enable on some devices GPIO_SM16716_DAT, // GPIO14 SM16716 Data 0, // GPIO15 wired to GND GPIO_USER, // GPIO16 N.C. From 4dc4f3832391ee35e312d64e00f3d0605a6298f6 Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Mon, 4 Feb 2019 01:08:29 -0500 Subject: [PATCH 23/24] Added USE_SM16716 to the feature list --- sonoff/support_features.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sonoff/support_features.ino b/sonoff/support_features.ino index 6c1abf97ac8f..1dc19e17292c 100644 --- a/sonoff/support_features.ino +++ b/sonoff/support_features.ino @@ -177,8 +177,10 @@ void GetFeatures(void) #ifdef USE_ARMTRONIX_DIMMERS feature_drv2 |= 0x00020000; // xdrv_18_armtronixdimmer.ino #endif +#ifdef USE_SM16716 + feature_drv2 |= 0x00040000; // xdrv_04_light.ino +#endif -// feature_drv2 |= 0x00040000; // feature_drv2 |= 0x00080000; // feature_drv2 |= 0x00100000; // feature_drv2 |= 0x00200000; From f1247a61e5872c13be19ef9968e0e1f2a44c133d Mon Sep 17 00:00:00 2001 From: Colin Kuebler Date: Fri, 8 Feb 2019 12:10:01 -0500 Subject: [PATCH 24/24] Renamed SM16716 PWR as per https://github.com/arendst/Sonoff-Tasmota/pull/4991#pullrequestreview-201622697 --- sonoff/language/bg-BG.h | 2 +- sonoff/language/cs-CZ.h | 2 +- sonoff/language/de-DE.h | 2 +- sonoff/language/el-GR.h | 2 +- sonoff/language/en-GB.h | 2 +- sonoff/language/es-AR.h | 2 +- sonoff/language/fr-FR.h | 2 +- sonoff/language/he-HE.h | 2 +- sonoff/language/hu-HU.h | 2 +- sonoff/language/it-IT.h | 2 +- sonoff/language/nl-NL.h | 2 +- sonoff/language/pl-PL.h | 2 +- sonoff/language/pt-BR.h | 2 +- sonoff/language/pt-PT.h | 2 +- sonoff/language/ru-RU.h | 2 +- sonoff/language/sk-SK.h | 2 +- sonoff/language/sv-SE.h | 2 +- sonoff/language/tr-TR.h | 2 +- sonoff/language/uk-UK.h | 2 +- sonoff/language/zh-CN.h | 2 +- sonoff/language/zh-TW.h | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index c0195039b594..292a61b1853b 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Активиране на SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 48c78ed96e48..48e34a4c386a 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Povol SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index c82602d0c4ef..98d3cf16f7d1 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "SM16716 aktivieren" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 4a711959ee39..8acf24fa7b72 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Ενεργοποίηση SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 6b4ebcbd2136..2d07be421342 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Enable SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 2e8bf6fbce24..b8b2f5950acb 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Habilitar SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 59292bd445c6..2b71e0066e08 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Activer SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index 62c23386a6bc..eb4feb449e5d 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Enable SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 6a96b2501bd4..cf924b2ac8ca 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "SM16716 engedélyezése" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 94aac6e22d33..3698bc57d35a 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Abilita SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index eb4ed10f778c..e33a5cf90243 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -558,7 +558,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "SM16716 inschakelen" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index ee8de573919f..b2847923be8e 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -558,7 +558,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Włącz SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index c88fdd0c4dab..d66ed8589e49 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Habilitar SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 94b5923cfe34..a9d22221fbff 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Enable SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index d88f9e6e419a..762bfe1f59dd 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Enable SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sk-SK.h b/sonoff/language/sk-SK.h index 31d9a021eacc..0c8d0f428c47 100644 --- a/sonoff/language/sk-SK.h +++ b/sonoff/language/sk-SK.h @@ -558,7 +558,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Povoľ SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index ea0b507b6c40..2c36c1d8bc29 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Aktivera SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index 557b057c94f8..b41e57f10732 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "SM16716 Aktif" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index e227203a7731..47b62987ba2e 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Увімкнений SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 3a882e424b5f..5a581d0da16a 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "启用 SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index b5154a03e3d7..602ecbe4dc40 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -557,7 +557,7 @@ #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" #define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "Enable SM16716" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "安"