From 244611f12f6e9cbfbcf8ff15996bdedfd8829bc9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 22 Dec 2020 15:26:07 +0100 Subject: [PATCH 1/2] Add logging buffer management --- tasmota/support.ino | 16 +++++++++++++- tasmota/support_tasmota.ino | 8 +++++-- tasmota/tasmota.ino | 2 +- tasmota/xdrv_01_webserver.ino | 40 +++++++++++++++++------------------ tasmota/xdrv_02_mqtt.ino | 3 ++- tasmota/xdrv_40_telegram.ino | 40 +++++++++++++++++------------------ 6 files changed, 62 insertions(+), 47 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index b54a15f28..85840fb8a 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1924,9 +1924,11 @@ void Syslog(void) } } -void SyslogAsync(void) { +void SyslogAsync(bool refresh) { static uint32_t index = 1; + if (refresh && !NeedLogRefresh(TasmotaGlobal.syslog_level, index)) { return; } + char* line; size_t len; while (GetLog(TasmotaGlobal.syslog_level, &index, &line, &len)) { @@ -1940,6 +1942,16 @@ void SyslogAsync(void) { } } +bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) { + // Skip initial buffer fill + if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - LOGSZ) { return false; } + + char* line; + size_t len; + if (!GetLog(req_loglevel, &index, &line, &len)) { return false; } + return ((line - TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE / 4); +} + bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* len_p) { uint32_t index = *index_p; @@ -1996,6 +2008,8 @@ void AddLog(uint32_t loglevel) { uint32_t highest_loglevel = Settings.weblog_level; if (Settings.mqttlog_level > highest_loglevel) { highest_loglevel = Settings.mqttlog_level; } if (TasmotaGlobal.syslog_level > highest_loglevel) { highest_loglevel = TasmotaGlobal.syslog_level; } + if (TasmotaGlobal.templog_level > highest_loglevel) { highest_loglevel = TasmotaGlobal.templog_level; } + if ((loglevel <= highest_loglevel) && // Log only when needed (TasmotaGlobal.masterlog_level <= highest_loglevel)) { // Delimited, zero-terminated buffer of log lines. diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index f9a501b39..98da69ee2 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -845,8 +845,8 @@ void PerformEverySecond(void) } } - MqttPublishLoggingAsync(); - SyslogAsync(); + MqttPublishLoggingAsync(false); + SyslogAsync(false); ResetGlobalValues(); @@ -984,6 +984,10 @@ void Every250mSeconds(void) SetLedPower(tstate); } + // Check if log refresh needed in case of fast buffer fill + MqttPublishLoggingAsync(true); + SyslogAsync(true); + /*-------------------------------------------------------------------------------------------*\ * Every second at 0.25 second interval \*-------------------------------------------------------------------------------------------*/ diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 300c09b68..5befb1a68 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -151,6 +151,7 @@ struct { uint8_t masterlog_level; // Master log level used to override set log level uint8_t seriallog_level; // Current copy of Settings.seriallog_level uint8_t syslog_level; // Current copy of Settings.syslog_level + uint8_t templog_level; // Temporary log level to be used by HTTP cm and Telegram uint8_t module_type; // Current copy of Settings.module or user template type uint8_t last_source; // Last command source uint8_t shutters_present; // Number of actual define shutters @@ -197,7 +198,6 @@ void setup(void) { memset(&TasmotaGlobal, 0, sizeof(TasmotaGlobal)); TasmotaGlobal.baudrate = APP_BAUDRATE; TasmotaGlobal.seriallog_timer = SERIALLOG_TIMER; - TasmotaGlobal.gpio_optiona.data = 0; TasmotaGlobal.temperature_celsius = NAN; TasmotaGlobal.blinks = 201; TasmotaGlobal.wifi_state_flag = WIFI_RESTART; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e2de549fa..f0f65e77b 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -3017,32 +3017,30 @@ void HandleHttpCommand(void) } WSContentBegin(200, CT_JSON); - uint32_t curridx = TasmotaGlobal.log_buffer_pointer; String svalue = Webserver->arg("cmnd"); if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { + uint32_t curridx = TasmotaGlobal.log_buffer_pointer; + TasmotaGlobal.templog_level = LOG_LEVEL_INFO; ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND); - if (TasmotaGlobal.log_buffer_pointer != curridx) { - WSContentSend_P(PSTR("{")); - bool cflg = false; - uint32_t index = curridx; - char* line; - size_t len; - while (GetLog(Settings.weblog_level, &index, &line, &len)) { - // [14:49:36.123 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] - char* JSON = (char*)memchr(line, '{', len); - if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) - size_t JSONlen = len - (JSON - line); - if (JSONlen > sizeof(TasmotaGlobal.mqtt_data)) { JSONlen = sizeof(TasmotaGlobal.mqtt_data); } - char stemp[JSONlen]; - strlcpy(stemp, JSON +1, JSONlen -2); - WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp); - cflg = true; - } + WSContentSend_P(PSTR("{")); + bool cflg = false; + uint32_t index = curridx; + char* line; + size_t len; + while (GetLog(TasmotaGlobal.templog_level, &index, &line, &len)) { + // [14:49:36.123 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] + char* JSON = (char*)memchr(line, '{', len); + if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) + size_t JSONlen = len - (JSON - line); + if (JSONlen > sizeof(TasmotaGlobal.mqtt_data)) { JSONlen = sizeof(TasmotaGlobal.mqtt_data); } + char stemp[JSONlen]; + strlcpy(stemp, JSON +1, JSONlen -2); + WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp); + cflg = true; } - WSContentSend_P(PSTR("}")); - } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}")); } + WSContentSend_P(PSTR("}")); + TasmotaGlobal.templog_level = 0; } else { WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}")); } diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 87d1cf4a5..a91e801e2 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -291,10 +291,11 @@ void MqttUnsubscribe(const char *topic) MqttUnsubscribeLib(topic); } -void MqttPublishLoggingAsync(void) { +void MqttPublishLoggingAsync(bool refresh) { static uint32_t index = 1; if (!Settings.flag.mqtt_enabled) { return; } // SetOption3 - Enable MQTT + if (refresh && !NeedLogRefresh(Settings.mqttlog_level, index)) { return; } char* line; size_t len; diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index cf4ab4baa..628ae0782 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -290,30 +290,28 @@ String TelegramExecuteCommand(const char *svalue) { String response = ""; uint32_t curridx = TasmotaGlobal.log_buffer_pointer; + TasmotaGlobal.templog_level = LOG_LEVEL_INFO; ExecuteCommand(svalue, SRC_CHAT); - if (TasmotaGlobal.log_buffer_pointer != curridx) { - response = F("{"); - bool cflg = false; - uint32_t index = curridx; - char* line; - size_t len; - while (GetLog(Settings.weblog_level, &index, &line, &len)) { - // [14:49:36.123 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] - char* JSON = (char*)memchr(line, '{', len); - if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) - size_t JSONlen = len - (JSON - line); - if (JSONlen > sizeof(TasmotaGlobal.mqtt_data)) { JSONlen = sizeof(TasmotaGlobal.mqtt_data); } - char stemp[JSONlen]; - strlcpy(stemp, JSON +1, JSONlen -2); - if (cflg) { response += F(","); } - response += stemp; - cflg = true; - } + response = F("{"); + bool cflg = false; + uint32_t index = curridx; + char* line; + size_t len; + while (GetLog(TasmotaGlobal.templog_level, &index, &line, &len)) { + // [14:49:36.123 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] + char* JSON = (char*)memchr(line, '{', len); + if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) + size_t JSONlen = len - (JSON - line); + if (JSONlen > sizeof(TasmotaGlobal.mqtt_data)) { JSONlen = sizeof(TasmotaGlobal.mqtt_data); } + char stemp[JSONlen]; + strlcpy(stemp, JSON +1, JSONlen -2); + if (cflg) { response += F(","); } + response += stemp; + cflg = true; } - response += F("}"); - } else { - response = F("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}"); } + response += F("}"); + TasmotaGlobal.templog_level = 0; return response; } From 59992d195463cc79cb39c667fdb9cb1f6106467a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 22 Dec 2020 16:47:24 +0100 Subject: [PATCH 2/2] Add support for FTC532 8-button touch controller Add support for FTC532 8-button touch controller by Peter Franck (#10222) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/language/bg_BG.h | 1 + tasmota/language/cs_CZ.h | 1 + tasmota/language/de_DE.h | 1 + tasmota/language/el_GR.h | 1 + tasmota/language/en_GB.h | 1 + tasmota/language/es_ES.h | 1 + tasmota/language/fr_FR.h | 1 + tasmota/language/he_HE.h | 1 + tasmota/language/hu_HU.h | 1 + tasmota/language/it_IT.h | 1 + tasmota/language/ko_KO.h | 1 + tasmota/language/nl_NL.h | 1 + tasmota/language/pl_PL.h | 1 + tasmota/language/pt_BR.h | 1 + tasmota/language/pt_PT.h | 1 + tasmota/language/ro_RO.h | 1 + tasmota/language/ru_RU.h | 1 + tasmota/language/sk_SK.h | 1 + tasmota/language/sv_SE.h | 1 + tasmota/language/tr_TR.h | 1 + tasmota/language/uk_UA.h | 1 + tasmota/language/vi_VN.h | 1 + tasmota/language/zh_CN.h | 1 + tasmota/language/zh_TW.h | 1 + tasmota/my_user_config.h | 2 + tasmota/support_features.ino | 4 +- tasmota/tasmota_template.h | 5 + tasmota/xdrv_47_ftc532.ino | 174 +++++++++++++++++++++++++++++++++++ tools/decode-status.py | 4 +- 31 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 tasmota/xdrv_47_ftc532.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3bf2f44..855e17018 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Support for P9813 RGB Led MOSFET controller (#10104) - Support for GPIO option selection - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs (#10196) +- Support for FTC532 8-button touch controller by Peter Franck (#10222) ### Fixed - Redesign syslog and mqttlog using log buffer (#10164) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ef5cfa9ed..1d606f988 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -62,6 +62,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for P9813 RGB Led MOSFET controller [#10104](https://github.com/arendst/Tasmota/issues/10104) - Support for GPIO option selection - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) +- Support for FTC532 8-button touch controller by Peter Franck [#10222](https://github.com/arendst/Tasmota/issues/10222) ### Fixed - Redesign syslog and mqttlog using log buffer [#10164](https://github.com/arendst/Tasmota/issues/10152) diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index b5a2e80b2..8a670dc5e 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -639,6 +639,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 86d6ea8a2..9f33d6b8b 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index fb8c9068c..dca3a03f2 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 6d069fab4..dc1212c8d 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index ea657251f..a2e32ec75 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 162803eda..d66fd557d 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 9e6ef3dfa..59175ce32 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -636,6 +636,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RF TX" #define D_SENSOR_RFRECV "RF RX" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 003d553e2..f6fb550ce 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index f4c40c182..24f5b535a 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 07fa5342a..06d753117 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 - STB" #define D_SENSOR_HX711_SCK "HX711 - SCK" #define D_SENSOR_HX711_DAT "HX711 - DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RF - TX" #define D_SENSOR_RFRECV "RF - RX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 2b4a62989..e11302fdb 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index cfe550e3d..6fb94bf76 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 2c4c96549..f2c811047 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 5427e5a93..0ba51aa7a 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 4e036a3ef..da55dc83c 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 64cd876bd..274bec4ca 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index eba040d20..76b17e9fa 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 33b63795a..7d566e561 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index a30bbf9ec..562d8ad3c 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 44f1ad715..9c66d591c 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 78ceca919..784262d36 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFRecv" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index d31207bca..c45de11cf 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index f06f21ea8..86bac3ed8 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index d759dd63e..1839950df 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -640,6 +640,7 @@ #define D_SENSOR_TM1638_STB "TM16 STB" #define D_SENSOR_HX711_SCK "HX711 SCK" #define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532"" #define D_SENSOR_TX2X_TX "TX2x" #define D_SENSOR_RFSEND "RFSend" #define D_SENSOR_RFRECV "RFrecv" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 7e101b144..2cd7f6229 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -752,6 +752,8 @@ //#define USE_WINDMETER // Add support for analog anemometer (+2k2 code) +//#define USE_FTC532 // Add support for FTC532 8-button touch controller (+0k6 code) + //#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) //#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index f6995f0ee..7a5d6cbcb 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -668,7 +668,9 @@ void ResponseAppendFeatures(void) #ifdef USE_RC522 feature7 |= 0x00002000; // xsns_80_mfrc522.ino #endif -// feature7 |= 0x00004000; +#ifdef USE_FTC532 + feature7 |= 0x00004000; // xdrv_47_ftc532.ino +#endif // feature7 |= 0x00008000; // feature7 |= 0x00010000; diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 2eefcf4a7..48dd7a30f 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -131,6 +131,7 @@ enum UserSelectablePins { GPIO_RC522_RST, // RC522 reset GPIO_P9813_CLK, GPIO_P9813_DAT, // P9813 Clock and Data GPIO_OPTION_A, // Specific device options to be served in code + GPIO_FTC532, // FTC532 touch ctrlr serial input GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -282,6 +283,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_RC522_RST "|" D_SENSOR_P9813_CLK "|" D_SENSOR_P9813_DAT "|" D_SENSOR_OPTION "_a|" + D_SENSOR_FTC532 ; const char kSensorNamesFixed[] PROGMEM = @@ -325,6 +327,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LEDLNK_INV), // Inverted link led AGPIO(GPIO_OUTPUT_HI), // Fixed output high AGPIO(GPIO_OUTPUT_LO), // Fixed output low +#ifdef USE_FTC532 + AGPIO(GPIO_FTC532), // FTC532 touch input +#endif /*-------------------------------------------------------------------------------------------*\ * Protocol specifics diff --git a/tasmota/xdrv_47_ftc532.ino b/tasmota/xdrv_47_ftc532.ino new file mode 100644 index 000000000..4c978cf43 --- /dev/null +++ b/tasmota/xdrv_47_ftc532.ino @@ -0,0 +1,174 @@ +/* + xdrv_47_ftc532.ino - FTC532 touch buttons support for Tasmota + + Copyright (C) 2020 Peter Franck and Theo Arends + + 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_FTC532 +/*********************************************************************************************\ + THE PLAN [tm]: OUTCOME: + ============== ======== + appear in a dropdown (D_SENSOR_FTC532 "FTC532") + select pin (GPIO_FTC532) + attach interrupt to pin DONE + ISR updating all 8 inputs DONE + de-bouncing for 50 ms NOT REQUIRED + change report every 250 ms REPORTS EVERY 50MS + Webserver display "00001001" DONE & REMOVED + MQTT message DONE + Rules hook DONE + detach interrupt before restart POINTLESS + + THE PROTOCOL [tm]: + ================== + LEAD-IN = 3015 µs HIGH, 755 µs LOW + S = 377 µs HIGH, 377 µs LOW + L = 377 µs HIGH, 1130 µs LOW + + GROUP1 GROUP2 + --------------------------- + ALL OFF: SSSSLLLL SSSSLLLL + 1 ON : LSSSSLLL SSSSLLLL + 2 ON : SLSSLSLL SSSSLLLL + 3 ON : SSLSLLSL SSSSLLLL + 8 ON : SSSSLLLL SSSLLLLS + 123 ON : LLLSSSSL SSSSLLLL + + Timing of an ALL OFF frame in clock cycles T=377µs, triggering on rising edge: + IDLE-2222444422224444-IDLE +\*********************************************************************************************/ + +#define XDRV_47 47 + +#define FTC532_KEYS_MAX 8 + +#define FTC532_STATE_WAITING 0x01 +#define FTC532_STATE_READING 0x02 + +// Rising edge timing in microseconds +#define FTC532_BIT 377 +#define FTC532_SHORT (FTC532_BIT * 2) +#define FTC532_LONG (FTC532_BIT * 4) +#define FTC532_IDLE (FTC532_BIT * 10) +#define FTC532_MAX (FTC532_BIT * 58) + +struct FTC532 { + volatile uint32_t rxtime; // ISR timer memory + volatile uint16_t errors; // error counter + volatile uint16_t sample = 0xF0F0; // buffer for bit-coded time samples + volatile uint16_t rxbit; // ISR bit counter + uint16_t keys = 0; // bitmap of active keys + uint16_t old_keys = 0; // previously active keys + volatile uint8_t state; // ISR state + volatile uint8_t valid; // did we ever receive valid data? + bool present = false; +} Ftc532; + +const char ftc532_json[] PROGMEM = "\"FTC532\":{\"KEYS\":\""; + +void ICACHE_RAM_ATTR ftc532_ISR(void) { // Hardware interrupt routine, triggers on rising edge + uint32_t time = micros(); + uint32_t time_diff = time - Ftc532.rxtime; + Ftc532.rxtime = time; + + if (Ftc532.state == FTC532_STATE_WAITING) { + if (time_diff > FTC532_LONG + FTC532_SHORT) { // new frame + Ftc532.rxbit = 0; + Ftc532.state = FTC532_STATE_READING; + } + return; + } // FTC532_STATE_READING starts here + if (time_diff > FTC532_LONG + FTC532_BIT) { + ++Ftc532.errors; // frame error + Ftc532.state = FTC532_STATE_WAITING; + return; + } + if (time_diff > FTC532_SHORT + FTC532_BIT) { + Ftc532.sample |= (1 << Ftc532.rxbit); // LONG + } else { + Ftc532.sample &= ~(1 << Ftc532.rxbit); // SHORT + } + ++Ftc532.rxbit; + if (Ftc532.rxbit == FTC532_KEYS_MAX * 2) { // frame complete + Ftc532.rxbit = 0; + Ftc532.valid = 1; + Ftc532.state = FTC532_STATE_WAITING; + } +} + +void ftc532_init(void) { // Initialize + if (!PinUsed(GPIO_FTC532)) { return; } + + Ftc532.errors = 0; + Ftc532.valid = 0; + Ftc532.state = FTC532_STATE_WAITING; + Ftc532.rxtime = micros(); + pinMode(Pin(GPIO_FTC532), INPUT_PULLUP); + attachInterrupt(Pin(GPIO_FTC532), ftc532_ISR, RISING); + Ftc532.present = true; +} + +void ftc532_update(void) { // Usually called every 50 ms +// // WARNING: Reduce callback frequency if this code is enabled +// if ((Ftc532.sample & 0xF) != ((~Ftc532.sample >> 4) & 0xF) || ((Ftc532.sample >> 8) & 0xF) != ((~Ftc532.sample >> 12) & 0xF)) { +// AddLog_P(LOG_LEVEL_ERROR, PSTR("FTC: inverted sample does not match %x %x %x %x"), +// Ftc532.sample & 0xF, (~Ftc532.sample >> 4) & 0xF, (Ftc532.sample >> 8) & 0xF, (~Ftc532.sample >> 12) & 0xF); +// } + Ftc532.keys = (Ftc532.sample & 0xF) | ((Ftc532.sample >> 4) & 0xF0); + if (Ftc532.keys != Ftc532.old_keys) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR("FTC: SAM=%04X KEY=%02X OLD=%02X ERR=%u OK=%u TIME=%lu Pin=%u"), +// Ftc532.sample, Ftc532.keys, Ftc532.old_keys, Ftc532.errors, Ftc532.valid, Ftc532.rxtime, Pin(GPIO_FTC532)); + ftc532_publish(); + Ftc532.old_keys = Ftc532.keys; + } +} + +void ftc532_show() { + ResponseAppend_P(PSTR(",%s%02X\"}"), ftc532_json, Ftc532.keys); // Hex keys need JSON quotes +} + +void ftc532_publish(void) { + Response_P(PSTR("{%s%02X\"}}"), ftc532_json, Ftc532.keys); // Hex keys need JSON quotes + MqttPublishTeleSensor(); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv47(uint8_t function) { + bool result = false; + + if (FUNC_INIT == function) { + // Initialize driver + ftc532_init(); + } else if (Ftc532.present) { + switch (function) { + // timed callback functions + case FUNC_EVERY_50_MSECOND: + ftc532_update(); + break; + // Generate JSON telemetry string + case FUNC_JSON_APPEND: + ftc532_show(); + break; + } + } + // Return bool result + return result; +} + +#endif // USE_FTC532 \ No newline at end of file diff --git a/tools/decode-status.py b/tools/decode-status.py index 829e84e32..678cf5a73 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -239,7 +239,7 @@ a_features = [[ "USE_EZOORP","USE_EZORTD","USE_EZOHUM","USE_EZOEC", "USE_EZOCO2","USE_EZOO2","USE_EZOPRS","USE_EZOFLO", "USE_EZODO","USE_EZORGB","USE_EZOPMP","USE_AS608", - "USE_SHELLY_DIMMER","USE_RC522","","", + "USE_SHELLY_DIMMER","USE_RC522","USE_FTC532","", "","","","", "","","","", "","","","", @@ -271,7 +271,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20201130 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20201222 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj))