Merge pull request #3 from arendst/development

update local repo
This commit is contained in:
Vic 2020-12-22 16:58:47 +00:00 committed by GitHub
commit 64ba2514b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 274 additions and 50 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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
\*-------------------------------------------------------------------------------------------*/

View File

@ -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;

View File

@ -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

View File

@ -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=\"}"));
}

View File

@ -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;

View File

@ -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;
}

174
tasmota/xdrv_47_ftc532.ino Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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))