From e7600ac83a0f05643dfa1df3343d7dd17af1812e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 20:16:23 +0300
Subject: [PATCH 01/71] Add support NTAG21x and NTAG20x cards. NTAG21x support
password authentication
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 270 ++++++++++++++++--
1 file changed, 247 insertions(+), 23 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 03eba20c7..62615c9bc 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -16,6 +16,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
+ #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
+// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
#ifdef USE_PN532_HSU
/*********************************************************************************************\
@@ -47,24 +50,48 @@ TasmotaSerial *PN532_Serial;
#define PN532_COMMAND_SAMCONFIGURATION 0x14
#define PN532_COMMAND_RFCONFIGURATION 0x32
#define PN532_COMMAND_INDATAEXCHANGE 0x40
+#define PN532_COMMAND_INCOMMUNICATETHRU 0x42
#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A
-
+#define PN532_COMMAND_INRELEASE 0x52
+#define PN532_COMMAND_INSELECT 0x54
#define PN532_MIFARE_ISO14443A 0x00
#define MIFARE_CMD_READ 0x30
#define MIFARE_CMD_AUTH_A 0x60
#define MIFARE_CMD_AUTH_B 0x61
#define MIFARE_CMD_WRITE 0xA0
+#define NTAG21X_CMD_GET_VERSION 0x60
+#define NTAG21X_CMD_READ 0x30
+#define NTAG21X_CMD_FAST_READ 0x3A
+#define NTAG21X_CMD_PWD_AUTH 0x1B
+
+const struct {
+ uint8_t version[6];
+ uint8_t confPage;
+} NTAG[] PROGMEM ={
+ {.version={0x04, 0x02, 0x01, 0x00, 0x0f, 0x03},.confPage=0x29}, /* NTAG213 */
+ {.version={0x04, 0x02, 0x01, 0x00, 0x11, 0x03},.confPage=0x83}, /* NTAG215 */
+ {.version={0x04, 0x02, 0x01, 0x00, 0x13, 0x03},.confPage=0xe3}, /* NTAG216 */
+ {.version={0x04, 0x05, 0x02, 0x02, 0x13, 0x03},.confPage=0xe3}, /* NT3H2111 */
+ {.version={0x04, 0x05, 0x02, 0x02, 0x15, 0x03},.confPage=0xe3}, /* NT3H2211 */
+};
+#define NTAG_CNT (sizeof(NTAG)/7) // num records in NTAG array
+
struct PN532 {
char uids[21]; // Number of bytes in the UID. 4, 7 or 10
uint8_t packetbuffer[64]; // Global buffer used to store packet
uint8_t command = 0; // Carry command code between functions
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
bool present = false; // Maintain detection flag
+ uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[16];
+ uint8_t newdata[33];
uint8_t function = 0;
- uint8_t newdata_len = 0;
+// uint8_t newdata_len = 0;
+ uint32_t pwd_auth=0x64636261;
+ uint16_t pwd_pack=0x6665;
+ uint32_t pwd_auth_new;
+ uint16_t pwd_pack_new;
#endif // USE_PN532_DATA_FUNCTION
} Pn532;
@@ -273,9 +300,9 @@ bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidL
return 0;
}
- uint16_t sens_res = Pn532.packetbuffer[2];
- sens_res <<= 8;
- sens_res |= Pn532.packetbuffer[3];
+ Pn532.atqa = Pn532.packetbuffer[2];
+ Pn532.atqa <<= 8;
+ Pn532.atqa |= Pn532.packetbuffer[3];
/* Card appears to be Mifare Classic */
*uidLength = Pn532.packetbuffer[5];
@@ -310,6 +337,25 @@ bool PN532_SAMConfig(void) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
+void PN532_inRelease(void) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
+ Pn532.packetbuffer[1] = 1;
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return;
+ }
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+}
+
+void PN532_inSelect(void) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
+ Pn532.packetbuffer[1] = 1;
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return ;
+ }
+ int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: Select %d %x"), res, Pn532.packetbuffer[0]);
+}
+
#ifdef USE_PN532_DATA_FUNCTION
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
@@ -393,19 +439,151 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
+uint8_t ntag21x_probe (void) {
+ uint8_t result=0;
+
+ Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
+ Pn532.packetbuffer[1] = NTAG21X_CMD_GET_VERSION;
+
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return result;
+ }
+
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))<9){
+ return result;
+ }
+
+/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: NTAG Version %02x %02x %02x %02x %02x %02x %02x %02x %02x"),
+ Pn532.packetbuffer[0],Pn532.packetbuffer[1],Pn532.packetbuffer[2],Pn532.packetbuffer[3],
+ Pn532.packetbuffer[4],Pn532.packetbuffer[5],Pn532.packetbuffer[6],Pn532.packetbuffer[7],
+ Pn532.packetbuffer[8]);
+ */
+ if (Pn532.packetbuffer[3] != 4) { // not NTAG type
+ return result;
+ }
+
+ for (uint8_t i=0; i0) {
+ /* NTAG EV1 found*/
+ str_pwd=PWD_NONE;
+ if (!ntag21x_read32(card_datas, sizeof(card_datas))) {
+ if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
+ if (memcmp(uid, nuid, sizeof(uid))==0) {
+ if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
+ if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ }
+ }
+ }
+
+ } else {
+ if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
+ if (memcmp(uid, nuid, sizeof(uid))==0) {
+ if (!ntag20x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ }
+ }
+ }
+ } else
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
@@ -415,7 +593,7 @@ void PN532_ScanForTag(void) {
memcpy(&card_datas,&card_data,sizeof(card_data));
#else
for (uint32_t i = 0;i < sizeof(card_data);i++) {
- if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) {
+ if (isprint(card_data[i])) {
card_datas[i] = char(card_data[i]);
} else {
card_datas[i] = '\0';
@@ -424,11 +602,12 @@ void PN532_ScanForTag(void) {
#endif // USE_PN532_DATA_RAW
}
if (Pn532.function == 1) { // erase block 1 of card
+//TODO : Test
for (uint32_t i = 0;i<16;i++) {
card_data[i] = 0x00;
}
if (mifareclassic_WriteDataBlock(1, card_data)) {
- erase_success = true;
+ success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
@@ -437,14 +616,14 @@ void PN532_ScanForTag(void) {
#ifdef USE_PN532_DATA_RAW
memcpy(&card_data,&Pn532.newdata,sizeof(card_data));
if (mifareclassic_WriteDataBlock(1, card_data)) {
- set_success = true;
+ success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
#else
bool IsAlphaNumeric = true;
for (uint32_t i = 0;i < Pn532.newdata_len;i++) {
- if ((!isalpha(Pn532.newdata[i])) && (!isdigit(Pn532.newdata[i]))) {
+ if (!isprint(Pn532.newdata[i])) {
IsAlphaNumeric = false;
}
}
@@ -452,7 +631,7 @@ void PN532_ScanForTag(void) {
memcpy(&card_data,&Pn532.newdata,Pn532.newdata_len);
card_data[Pn532.newdata_len] = '\0'; // Enforce null termination
if (mifareclassic_WriteDataBlock(1, card_data)) {
- set_success = true;
+ success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
@@ -467,24 +646,35 @@ void PN532_ScanForTag(void) {
}
switch (Pn532.function) {
case 0x01:
- if (!erase_success) {
+ if (!success) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
}
break;
case 0x02:
- if (!set_success) {
+ if (!success) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
}
default:
break;
}
Pn532.function = 0;
- ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), Pn532.uids, card_datas);
+ ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas);
+ if (str_pwd == PWD_NONE) {
+ ResponseAppend_P(PSTR(",\"Auth\":\"None\""));
+ } else
+ if (str_pwd == PWD_OK) {
+ ResponseAppend_P(PSTR(",\"Auth\":\"Ok\""));
+ } else
+ if (str_pwd == PWD_NOK) {
+ ResponseAppend_P(PSTR(",\"Auth\":\"NOk\""));
+ }
+ ResponseAppend_P(PSTR("}}"));
#else
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
#endif // USE_PN532_DATA_FUNCTION
MqttPublishTeleSensor();
+ PN532_inRelease();
Pn532.scantimer = 7; // Ignore tags found for two seconds
}
}
@@ -501,19 +691,23 @@ bool PN532_Command(void) {
return serviced;
}
char argument[XdrvMailbox.data_len];
+/*
for (uint32_t ca=0;ca 1) {
+ } else
+ if (!strcmp(argument,"S")) {
+ if (ArgC() > 1) {
if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
serviced = false;
return serviced;
@@ -528,6 +722,36 @@ bool PN532_Command(void) {
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
return serviced;
}
+ } else
+ if (!strncmp_P(argument,PSTR("AUTH"),4)) {
+ if (ArgC() > 1) {
+ Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_auth);
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"NTAG_PWD\"}}"));
+ }
+ if (ArgC() > 2) {
+ Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_pack);
+ }
+ return true;
+ } else
+ if (!strncmp_P(argument,PSTR("SET_PWD"),7)) {
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}"));
+ Pn532.pwd_auth_new=Pn532.pwd_auth;
+ Pn532.pwd_pack_new=Pn532.pwd_pack;
+ if (ArgC() > 1) {
+ Pn532.pwd_auth_new=strtoul(ArgV(argument,2),nullptr,0);
+ }
+ if (ArgC() > 2) {
+ Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0);
+ }
+ Pn532.function = 3;
+ return true;
+ } else
+ if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) {
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
+ Pn532.function = 4;
+ return true;
}
return false;
}
From b419e69759de4c0ccb8017fcdac1c741c6346241 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 20:18:31 +0300
Subject: [PATCH 02/71] Defines
---
tasmota/my_user_config.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 51ea0d677..ddb3912a5 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -776,8 +776,8 @@
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
-//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
-// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
+#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
+ #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
From 5db8fcd0d051a44e62039956eec974c56f056ab5 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 22:38:12 +0300
Subject: [PATCH 03/71] refactoring mifare classic
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 68 ++++++-------------
1 file changed, 20 insertions(+), 48 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 62615c9bc..fe105f8ce 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -18,7 +18,6 @@
*/
#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
#define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
-// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
#ifdef USE_PN532_HSU
/*********************************************************************************************\
@@ -85,9 +84,9 @@ struct PN532 {
bool present = false; // Maintain detection flag
uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[33];
+ uint8_t newdata[16];
uint8_t function = 0;
-// uint8_t newdata_len = 0;
+ uint8_t newdata_len = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
uint32_t pwd_auth_new;
@@ -587,58 +586,29 @@ void PN532_ScanForTag(void) {
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- uint8_t card_data[16];
- if (mifareclassic_ReadDataBlock(1, card_data)) {
-#ifdef USE_PN532_DATA_RAW
- memcpy(&card_datas,&card_data,sizeof(card_data));
-#else
- for (uint32_t i = 0;i < sizeof(card_data);i++) {
- if (isprint(card_data[i])) {
- card_datas[i] = char(card_data[i]);
- } else {
- card_datas[i] = '\0';
+ if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
+ for (uint32_t i = 0;i < sizeof(card_datas);i++) {
+ if (!isprint(card_datas[i])) {
+ // do not output non-printable characters to the console
+ card_datas[i] = 0;
}
}
-#endif // USE_PN532_DATA_RAW
+ } else {
+ card_datas[0] = 0;
}
if (Pn532.function == 1) { // erase block 1 of card
-//TODO : Test
- for (uint32_t i = 0;i<16;i++) {
- card_data[i] = 0x00;
- }
- if (mifareclassic_WriteDataBlock(1, card_data)) {
+ memset(card_datas,0,sizeof(card_datas));
+ if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
- memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
- }
+ } else
if (Pn532.function == 2) {
-#ifdef USE_PN532_DATA_RAW
- memcpy(&card_data,&Pn532.newdata,sizeof(card_data));
- if (mifareclassic_WriteDataBlock(1, card_data)) {
+ memcpy(&card_datas,&Pn532.newdata,sizeof(card_datas));
+ if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
- memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
-#else
- bool IsAlphaNumeric = true;
- for (uint32_t i = 0;i < Pn532.newdata_len;i++) {
- if (!isprint(Pn532.newdata[i])) {
- IsAlphaNumeric = false;
- }
- }
- if (IsAlphaNumeric) {
- memcpy(&card_data,&Pn532.newdata,Pn532.newdata_len);
- card_data[Pn532.newdata_len] = '\0'; // Enforce null termination
- if (mifareclassic_WriteDataBlock(1, card_data)) {
- success = true;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
- memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
- }
- } else {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data must be alphanumeric"));
- }
-#endif // USE_PN532_DATA_RAW
}
} else {
sprintf_P(card_datas, PSTR("AUTHFAIL"));
@@ -713,10 +683,12 @@ bool PN532_Command(void) {
return serviced;
}
ArgV(argument, 2);
- Pn532.newdata_len = strlen(argument);
- if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; }
- memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
- Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
+// Pn532.newdata_len = strlen(argument);
+// if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; }
+// memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
+// Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
+ strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
+ Pn532.newdata[sizeof(Pn532.newdata)-1]=0;
Pn532.function = 2;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
From 3e3dfa35d33db379267102de737fb30cab0df5c7 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 23:14:27 +0300
Subject: [PATCH 04/71] refactoring mifare classic stage 2
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index fe105f8ce..fee1302f8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -86,7 +86,7 @@ struct PN532 {
#ifdef USE_PN532_DATA_FUNCTION
uint8_t newdata[16];
uint8_t function = 0;
- uint8_t newdata_len = 0;
+// uint8_t newdata_len = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
uint32_t pwd_auth_new;
@@ -586,16 +586,6 @@ void PN532_ScanForTag(void) {
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0;i < sizeof(card_datas);i++) {
- if (!isprint(card_datas[i])) {
- // do not output non-printable characters to the console
- card_datas[i] = 0;
- }
- }
- } else {
- card_datas[0] = 0;
- }
if (Pn532.function == 1) { // erase block 1 of card
memset(card_datas,0,sizeof(card_datas));
if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
@@ -610,6 +600,16 @@ void PN532_ScanForTag(void) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
}
}
+ if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
+ for (uint32_t i = 0;i < sizeof(card_datas);i++) {
+ if (!isprint(card_datas[i])) {
+ // do not output non-printable characters to the console
+ card_datas[i] = 0;
+ }
+ }
+ } else {
+ card_datas[0] = 0;
+ }
} else {
sprintf_P(card_datas, PSTR("AUTHFAIL"));
}
From b35479559db49acb94014bbcf3c55151561a1b5b Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 23:15:58 +0300
Subject: [PATCH 05/71] Delete #define USE_PN532_DATA_RAW
---
tasmota/my_user_config.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index ddb3912a5..1838b9096 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -778,7 +778,6 @@
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
#define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
-// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
From 0eebdf86208e04297c70c1f3a15e1ee040bf8c79 Mon Sep 17 00:00:00 2001
From: cybermaus
Date: Tue, 25 Oct 2022 22:34:08 +0200
Subject: [PATCH 06/71] Deduplicate code from xdrv_10_rules.ino
Turns out this code was already done in xdrv_09_timers.ino
---
tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
index 6686b8770..49342df27 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
@@ -1458,19 +1458,7 @@ bool findNextVariableValue(char * &pVarname, float &value)
} else if (sVarName.startsWith(F("TIMER"))) {
uint32_t index = sVarName.substring(5).toInt();
if (index > 0 && index <= MAX_TIMERS) {
- value = Settings->timer[index -1].time;
-#if defined(USE_SUNRISE)
- // Correct %timerN% values for sunrise/sunset timers
- if ((1 == Settings->timer[index -1].mode) || (2 == Settings->timer[index -1].mode)) {
- // in this context, time variable itself is merely an offset, with <720 being negative
- value += -720 + SunMinutes(Settings->timer[index -1].mode -1);
- if (2 == Settings->timer[index -1].mode) {
- // To aid rule comparative statements, sunset past midnight (high lattitudes) is expressed past 24h00
- // So sunset at 00h45 is at 24h45
- if (value < 360) { value += 1440; }
- }
- }
-#endif // USE_SUNRISE
+ value = TimerGetTimeOfDay(index -1);
}
#if defined(USE_SUNRISE)
} else if (sVarName.equals(F("SUNRISE"))) {
From a47f6baf2fc36ba903392a27263587c2d125caa4 Mon Sep 17 00:00:00 2001
From: cybermaus
Date: Tue, 25 Oct 2022 22:39:30 +0200
Subject: [PATCH 07/71] Deduplicate xdrv_09_timers.ino also
Turns out even TimerGetTimeOfDay was duplicate code from ApplyTimerOffsets
Did add a fix for the permanent day/night situation
---
tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino b/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
index 438ade4d5..8c1fd530e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
@@ -253,10 +253,10 @@ uint16_t TimerGetTimeOfDay(uint8_t index)
int16_t xtime = xtimer.time;
#ifdef USE_SUNRISE
if (xtimer.mode) {
- if (xtime >= 12*60) xtime = 12*60 - xtime;
- xtime += (int16_t)SunMinutes(xtimer.mode-1);
- if (xtime < 0) xtime += 24*60;
- if (xtime >= 24*60) xtime -= 24*60;
+ ApplyTimerOffsets(&xtimer);
+ xtime = xtimer.time;
+ if (xtime==2047 && xtimer.mode==1) xtime *= -1; // Sun always has already rises
+ if (xtime==2046 && xtimer.mode==2) xtime *= -1; // Sun always has already set
}
#endif
return xtime;
From 37df680a80720d6b6a2de45870cac171c91b2fc1 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 00:15:04 +0300
Subject: [PATCH 08/71] Refactoring mifare classic, stage 3
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 23 +++++--------------
1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index fee1302f8..50bb6e02a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -82,11 +82,10 @@ struct PN532 {
uint8_t command = 0; // Carry command code between functions
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
bool present = false; // Maintain detection flag
- uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[16];
+ uint16_t atqa;
+ uint8_t newdata[32];
uint8_t function = 0;
-// uint8_t newdata_len = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
uint32_t pwd_auth_new;
@@ -601,12 +600,13 @@ void PN532_ScanForTag(void) {
}
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0;i < sizeof(card_datas);i++) {
+ for (uint32_t i = 0; i < 16;i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
card_datas[i] = 0;
}
}
+ card_datas[16] = 0;
} else {
card_datas[0] = 0;
}
@@ -661,13 +661,6 @@ bool PN532_Command(void) {
return serviced;
}
char argument[XdrvMailbox.data_len];
-/*
- for (uint32_t ca=0;ca 15) { Pn532.newdata_len = 15; }
-// memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
-// Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
- Pn532.newdata[sizeof(Pn532.newdata)-1]=0;
+ if (strlen(argument)>16) argument[16]=0;
Pn532.function = 2;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata);
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
return serviced;
}
From 0487cf9eaa5ea074c194078ca416c023a62356d7 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 00:50:07 +0300
Subject: [PATCH 09/71] renamed the commands Sensor40, increased recording to
32
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 75 ++++++++++---------
1 file changed, 40 insertions(+), 35 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 50bb6e02a..7e40e58d3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -395,46 +395,51 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the command */
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ for (uint8_t i = 0; i < 2; i++) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
+ Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- /* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
- return 0;
+ /* Send the command */
+ if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
+ return 0;
+ }
+
+ /* Read the response packet */
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+
+ /* If byte 8 isn't 0x00 we probably have an error */
+ if (Pn532.packetbuffer[0] != 0x00) {
+ return 0;
+ }
+
+ /* Copy the 16 data bytes to the output buffer */
+ /* Block content starts at byte 9 of a valid response */
+ memcpy (&data[i<<4], &Pn532.packetbuffer[1], 16);
}
-
- /* Read the response packet */
- PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
-
- /* If byte 8 isn't 0x00 we probably have an error */
- if (Pn532.packetbuffer[0] != 0x00) {
- return 0;
- }
-
- /* Copy the 16 data bytes to the output buffer */
- /* Block content starts at byte 9 of a valid response */
- memcpy (data, &Pn532.packetbuffer[1], 16);
-
return 1;
}
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
+ for (uint8_t i = 0; i < 2; i++) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
+ Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ memcpy(&Pn532.packetbuffer[4], &data[i<<4], 16); /* Data Payload */
/* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return 0;
- }
-
+ if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
+ return 0;
+ }
/* Read the response packet */
- return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
+ if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) {
+ return 0;
+ }
+ }
+ return 1;
}
uint8_t ntag21x_probe (void) {
@@ -600,13 +605,13 @@ void PN532_ScanForTag(void) {
}
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0; i < 16;i++) {
+ for (uint32_t i = 0; i < 32;i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
card_datas[i] = 0;
}
}
- card_datas[16] = 0;
+ card_datas[32] = 0;
} else {
card_datas[0] = 0;
}
@@ -663,13 +668,13 @@ bool PN532_Command(void) {
char argument[XdrvMailbox.data_len];
ArgV(argument, 1);
UpperCase(argument,argument);
- if (!strcmp(argument,"E")) {
+ if (!strncmp_P(argument,PSTR("ERASE"),5)) {
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}"));
return serviced;
} else
- if (!strcmp(argument,"S")) {
+ if (!strncmp_P(argument,PSTR("WRITE"),5)) {
if (ArgC() > 1) {
if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
serviced = false;
@@ -677,7 +682,7 @@ bool PN532_Command(void) {
}
ArgV(argument, 2);
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
- if (strlen(argument)>16) argument[16]=0;
+ if (strlen(argument)>32) argument[32]=0;
Pn532.function = 2;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
From 9534838c19cb93f2ea6926058c5d431301088598 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 00:56:44 +0300
Subject: [PATCH 10/71] renamed the commands Sensor40, increased recording to
32, stage 2
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 7e40e58d3..35bbfd5e6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -671,7 +671,7 @@ bool PN532_Command(void) {
if (!strncmp_P(argument,PSTR("ERASE"),5)) {
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
return serviced;
} else
if (!strncmp_P(argument,PSTR("WRITE"),5)) {
@@ -685,7 +685,7 @@ bool PN532_Command(void) {
if (strlen(argument)>32) argument[32]=0;
Pn532.function = 2;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}"));
return serviced;
}
} else
From 0887ec31f54e4ebc738cefd110d133f567c2996c Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 01:29:10 +0300
Subject: [PATCH 11/71] Reduced 16 bytes
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 25 +++++++++++--------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 35bbfd5e6..c6823d259 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -421,7 +421,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
return 1;
}
-uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
+bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
for (uint8_t i = 0; i < 2; i++) {
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
@@ -432,14 +432,14 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Send the command */
if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return 0;
+ return false;
}
/* Read the response packet */
if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) {
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
uint8_t ntag21x_probe (void) {
@@ -575,6 +575,12 @@ void PN532_ScanForTag(void) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (Pn532.command == 1) {
+ /* Erase */
+ } else
+ if (Pn532.command == 2) {
+ /* Write */
+ }
}
}
}
@@ -587,20 +593,17 @@ void PN532_ScanForTag(void) {
}
}
} else
- if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
+ if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- if (Pn532.function == 1) { // erase block 1 of card
+ if (Pn532.function == 1) { // erase blocks 1 & 2 of card
memset(card_datas,0,sizeof(card_datas));
- if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
- success = true;
+ if ((success=mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas))) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
}
} else
if (Pn532.function == 2) {
- memcpy(&card_datas,&Pn532.newdata,sizeof(card_datas));
- if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
- success = true;
+ if ((success=mifareclassic_WriteDataBlock(1, Pn532.newdata))) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
}
}
From 97230fe456ec1328cdca325b0e36c05a64a59118 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 19:21:50 +0300
Subject: [PATCH 12/71] Removed the duplicated functionality
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 74 +++++--------------
1 file changed, 18 insertions(+), 56 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index c6823d259..3e8224d7a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -472,29 +472,6 @@ uint8_t ntag21x_probe (void) {
return result; //Return configuration page address
}
-bool ntag21x_read32(char *out, uint8_t out_len) {
-
- if (out_len<33) return false;
-
- Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
- Pn532.packetbuffer[1] = NTAG21X_CMD_FAST_READ;
- Pn532.packetbuffer[2] = 0x04; // first page
- Pn532.packetbuffer[3] = 0x0b; // last page
- if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
- return false;
- }
- if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<33){
- return false;
- }
-
- if (Pn532.packetbuffer[0]!=0) {
- return false;
- }
- memcpy(out,&Pn532.packetbuffer[1],out_len);
- out[32]=0;
- return true;
-}
-
bool ntag21x_auth(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH;
@@ -512,41 +489,26 @@ bool ntag21x_auth(void) {
return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0;
}
-bool ntag20x_read32(char *out, uint8_t out_len) {
+bool ntag2xx_read32(char *out, uint8_t out_len) {
if (out_len<33) return false;
+ for (uint8_t i = 0; i < 2; i++) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
+ Pn532.packetbuffer[1] = NTAG21X_CMD_READ;
+ Pn532.packetbuffer[2] = 0x04 << i; // first page
- Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
- Pn532.packetbuffer[1] = NTAG21X_CMD_READ;
- Pn532.packetbuffer[2] = 0x04; // first page
-
- if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
- return false;
+ if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
+ return false;
+ }
+ if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
+ return false;
+ }
+ if (Pn532.packetbuffer[0]!=0) {
+ return false;
+ }
+ memcpy(&out[i<<4],&Pn532.packetbuffer[1],16);
}
- if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
- return false;
- }
- if (Pn532.packetbuffer[0]!=0) {
- return false;
- }
- memcpy(out,&Pn532.packetbuffer[1],16);
-
- Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
- Pn532.packetbuffer[1] = NTAG21X_CMD_READ;
- Pn532.packetbuffer[2] = 0x08; // first page
-
- if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
- return false;
- }
- if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
- return false;
- }
- if (Pn532.packetbuffer[0]!=0) {
- return false;
- }
- memcpy(&out[16],&Pn532.packetbuffer[1],16);
out[32]=0;
-
return true;
}
@@ -570,11 +532,11 @@ void PN532_ScanForTag(void) {
if ((confPage=ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag21x_read32(card_datas, sizeof(card_datas))) {
+ if (!ntag2xx_read32(card_datas, sizeof(card_datas))) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
- if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
if (Pn532.command == 1) {
/* Erase */
} else
@@ -588,7 +550,7 @@ void PN532_ScanForTag(void) {
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag20x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
}
}
}
From cc7936bd7e90b0df19013fae1963baedb03f726c Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Thu, 27 Oct 2022 00:48:22 +0300
Subject: [PATCH 13/71] Add password operations
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 197 ++++++++++++------
1 file changed, 134 insertions(+), 63 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 3e8224d7a..639a3a8c8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -60,9 +60,10 @@ TasmotaSerial *PN532_Serial;
#define MIFARE_CMD_WRITE 0xA0
#define NTAG21X_CMD_GET_VERSION 0x60
-#define NTAG21X_CMD_READ 0x30
+#define NTAG2XX_CMD_READ 0x30
#define NTAG21X_CMD_FAST_READ 0x3A
#define NTAG21X_CMD_PWD_AUTH 0x1B
+#define NTAG2XX_CMD_WRITE 0xA2
const struct {
uint8_t version[6];
@@ -344,15 +345,14 @@ void PN532_inRelease(void) {
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
}
-void PN532_inSelect(void) {
+/* void PN532_inSelect(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
Pn532.packetbuffer[1] = 1;
if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
return ;
}
int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: Select %d %x"), res, Pn532.packetbuffer[0]);
-}
+} */
#ifdef USE_PN532_DATA_FUNCTION
@@ -435,7 +435,7 @@ bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
return false;
}
/* Read the response packet */
- if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) {
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
return false;
}
}
@@ -456,23 +456,20 @@ uint8_t ntag21x_probe (void) {
return result;
}
-/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: NTAG Version %02x %02x %02x %02x %02x %02x %02x %02x %02x"),
- Pn532.packetbuffer[0],Pn532.packetbuffer[1],Pn532.packetbuffer[2],Pn532.packetbuffer[3],
- Pn532.packetbuffer[4],Pn532.packetbuffer[5],Pn532.packetbuffer[6],Pn532.packetbuffer[7],
- Pn532.packetbuffer[8]);
- */
if (Pn532.packetbuffer[3] != 4) { // not NTAG type
return result;
}
for (uint8_t i=0; i= 33 */
+
+ if (!ntag2xx_read16(page, out)) {
+ return false;
+ }
+ if (!ntag2xx_read16(page + 4, &out[16])) {
+ return false;
}
out[32]=0;
return true;
}
+bool ntag2xx_write4(uint8_t page, char *in) {
+
+ Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
+ Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE;
+ Pn532.packetbuffer[2] = page; // first page
+ memcpy(&Pn532.packetbuffer[3],in,4);
+
+ if (PN532_writeCommand(Pn532.packetbuffer, 7)) {
+ return false;
+ }
+
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
+ return false;
+ }
+ return true;
+}
+
+bool ntag2xx_writeN(uint8_t page, uint8_t numPages, char *in) {
+
+ for (uint8_t i = 0; i < numPages; i++) {
+ if (!ntag2xx_write4(page +i, &in[i << 2])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
+ char card_datas[16];
+
+ if (ntag2xx_read16(confPage, card_datas)) {
+ if (unsetPasswd) {
+ card_datas[3]=0xFF;
+ return ntag2xx_writeN(confPage,1,card_datas);
+ }
+ card_datas[3]=0; // Set AUTH0 for protect all pages
+ card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
+ memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
+ memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
+ return ntag2xx_writeN(confPage,4,card_datas);
+ }
+ return false;
+}
+
#endif // USE_PN532_DATA_FUNCTION
void PN532_ScanForTag(void) {
@@ -532,42 +580,45 @@ void PN532_ScanForTag(void) {
if ((confPage=ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag2xx_read32(card_datas, sizeof(card_datas))) {
+ if (!ntag2xx_read32(4, card_datas)) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
- if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
- if (Pn532.command == 1) {
- /* Erase */
- } else
- if (Pn532.command == 2) {
- /* Write */
+ if (ntag21x_auth()) {
+ str_pwd=PWD_OK;
+ if (Pn532.function == 3) { /* new password */
+ success = ntag21x_set_password(confPage, false);
+ }
+ if (Pn532.function == 4) { /* clear password */
+ success = ntag21x_set_password(confPage, true);
+ }
+ } else {
+ str_pwd=PWD_NOK;
}
+ if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
}
}
- }
-
+ } else {
+ if (Pn532.function == 3) { /* new password */
+ success = ntag21x_set_password(confPage, false);
+ }
+ }
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
}
}
}
- } else
- if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
+ if ((Pn532.function == 1) || (Pn532.function == 2)) {
+ success = ntag2xx_writeN(4, 8, (char *)Pn532.newdata);
+ if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ }
+ }
+ else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- if (Pn532.function == 1) { // erase blocks 1 & 2 of card
- memset(card_datas,0,sizeof(card_datas));
- if ((success=mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas))) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
- }
- } else
- if (Pn532.function == 2) {
- if ((success=mifareclassic_WriteDataBlock(1, Pn532.newdata))) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
- }
+ if ((Pn532.function == 1) || (Pn532.function == 2)) {
+ success=mifareclassic_WriteDataBlock(1, Pn532.newdata);
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
for (uint32_t i = 0; i < 32;i++) {
@@ -586,14 +637,33 @@ void PN532_ScanForTag(void) {
}
switch (Pn532.function) {
case 0x01:
- if (!success) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase success"));
+ } else {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase fail - exiting erase mode"));
}
break;
case 0x02:
- if (!success) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Data write successful"));
+ } else{
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Write failed - exiting set mode"));
}
+ break;
+ case 0x03:
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password successful"));
+ } else{
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password failed - exiting set mode"));
+ }
+ break;
+ case 0x04:
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password successful"));
+ } else{
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password failed - exiting set mode"));
+ }
+ break;
default:
break;
}
@@ -634,8 +704,9 @@ bool PN532_Command(void) {
ArgV(argument, 1);
UpperCase(argument,argument);
if (!strncmp_P(argument,PSTR("ERASE"),5)) {
+ memset(Pn532.newdata,0,sizeof(Pn532.newdata));
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be erased"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
return serviced;
} else
@@ -649,7 +720,7 @@ bool PN532_Command(void) {
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
if (strlen(argument)>32) argument[32]=0;
Pn532.function = 2;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be set to '%s'"), argument);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}"));
return serviced;
}
@@ -657,16 +728,15 @@ bool PN532_Command(void) {
if (!strncmp_P(argument,PSTR("AUTH"),4)) {
if (ArgC() > 1) {
Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
- AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_auth);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"NTAG_PWD\"}}"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"AUTH\"}}"));
}
if (ArgC() > 2) {
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
- AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_pack);
}
return true;
} else
if (!strncmp_P(argument,PSTR("SET_PWD"),7)) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will set password"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}"));
Pn532.pwd_auth_new=Pn532.pwd_auth;
Pn532.pwd_pack_new=Pn532.pwd_pack;
@@ -680,8 +750,9 @@ bool PN532_Command(void) {
return true;
} else
if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) {
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
- Pn532.function = 4;
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will unset password"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
+ Pn532.function = 4;
return true;
}
return false;
From 09b02b3325a00f7a3b49153a48423f8051cafe87 Mon Sep 17 00:00:00 2001
From: Charles
Date: Thu, 27 Oct 2022 14:16:37 +0200
Subject: [PATCH 14/71] standard mode bug fixes
Increase serial buffer size for standard mode
trimmed values for standard mode
fix (hopefully) negative total kWh counter
save energy on reset
update energy total every hour
fixed contract label display for Standard mode
---
.../tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 80 ++++++++++++++-----
1 file changed, 60 insertions(+), 20 deletions(-)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
index 04afe6af4..a17361047 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
@@ -152,7 +152,7 @@ PROGMEM
"|"
;
-#define TELEINFO_SERIAL_BUFFER_STANDARD 512 // Receive buffer size for Standard mode
+#define TELEINFO_SERIAL_BUFFER_STANDARD 1536 // Receive buffer size for Standard mode
#define TELEINFO_SERIAL_BUFFER_HISTORIQUE 512 // Receive buffer size for Legacy mode
#define TELEINFO_PROCESS_BUFFER 32 // Local processing buffer
@@ -163,6 +163,7 @@ uint8_t tic_rx_pin = NOT_A_PIN;
char serialNumber[13] = ""; // Serial number is 12 char long
bool tinfo_found = false;
int serial_buffer_size;
+uint32_t total_wh;
int contrat;
int tarif;
int isousc;
@@ -183,7 +184,12 @@ char * getValueFromLabelIndex(int labelIndex, char * value)
// Get the label name
GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel);
// Get value of label name
- return tinfo.valueGet(labelName, value) ;
+ tinfo.valueGet(labelName, value) ;
+ // Standard mode has values with space before/after
+ if (tinfo_mode==TINFO_MODE_STANDARD) {
+ Trim(value);
+ }
+ return value;
}
/* ======================================================================
@@ -329,12 +335,11 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
char value[32];
uint32_t hc = 0;
uint32_t hp = 0;
- uint32_t total = 0;
// Base, un seul index
if (ilabel == LABEL_BASE) {
- total = atol(me->value);
- AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Base:%ld"), total);
+ total_wh = atol(me->value);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Base:%ld"), total_wh);
// Heures creuses/pleines calculer total
} else {
// Heures creuses get heures pleines
@@ -352,15 +357,17 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
}
}
if (hc>0 && hp>0) {
- total = hc + hp;
+ total_wh = hc + hp;
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total_wh);
}
- AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %ld Wh"), total);
- if (total>0) {
- Energy.import_active[0] = (float)total/1000.0f;
- EnergyUpdateTotal();
+ AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %ld Wh"), total_wh);
+ if (total_wh>0) {
+ Energy.total[0] = (float) total_wh / 1000.0f;
+ Energy.import_active[0] = Energy.total[0];
+ //Energy.import_active[0] = (float)total/1000.0f;
+ //EnergyUpdateTotal();
AddLog (LOG_LEVEL_DEBUG_MORE, PSTR ("TIC: import_active[0]=%.3fKWh"), Energy.import_active[0] );
}
}
@@ -368,10 +375,10 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
// Wh total index (all contract)
else if ( ilabel == LABEL_EAST)
{
- uint32_t total = atol(me->value);
- Energy.import_active[0] = (float)total/1000.0f;
- EnergyUpdateTotal();
- AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%ldWh"), total);
+ total_wh = atol(me->value);
+ Energy.total[0] = (float) total_wh / 1000.0f;
+ Energy.import_active[0] = Energy.total[0];
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%ldWh"), total_wh);
}
// Wh indexes (standard)
@@ -538,7 +545,7 @@ void NewFrameCallback(struct _ValueList * me)
Energy.data_valid[0] = 0;
// Deprecated see setOption108
- // send teleinfo raw data only if setup like that
+ // send teleinfo MQTT raw data only if setup like that
if (Settings->teleinfo.raw_send) {
// Do we need to skip this frame
if (raw_skip == 0 ) {
@@ -578,6 +585,7 @@ void TInfoDrvInit(void) {
Energy.voltage_available = false;
Energy.phase_count = 1;
// init hardware energy counters
+ total_wh = 0;
Settings->flag3.hardware_energy_total = true;
}
}
@@ -673,6 +681,25 @@ void TInfoInit(void)
}
}
+//
+/* ======================================================================
+Function: TInfoSaveBeforeRestart
+Purpose : Save data before ESP restart
+Input : -
+Output : -
+Comments: -
+====================================================================== */
+void TInfoSaveBeforeRestart()
+{
+ // if teleinfo enabled, set it low
+ if (PinUsed (GPIO_TELEINFO_ENABLE)) {
+ digitalWrite( Pin(GPIO_TELEINFO_ENABLE), LOW);
+ }
+
+ // update energy total (in kwh)
+ EnergyUpdateTotal();
+
+}
/* ======================================================================
Function: TInfoCmd
@@ -842,6 +869,7 @@ Comments: -
void TInfoProcess(void)
{
static char buff[TELEINFO_PROCESS_BUFFER];
+ static uint32_t tick_update = 0;
#ifdef MEASURE_PERF
static unsigned long max_time = 0;
unsigned long duration = millis();
@@ -872,6 +900,14 @@ void TInfoProcess(void)
if (duration > max_time) { max_time = duration; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_time=%lu"), max_time); }
if (tmp_size > max_size) { max_size = tmp_size; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_size=%d"), max_size); }
#endif
+
+ // if needed, update energy total every hour
+ if (tick_update++ > 3600 * 4) {
+ EnergyUpdateTotal();
+ AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %lu Wh"), total_wh);
+ tick_update = 0;
+ }
+
}
/* ======================================================================
@@ -886,7 +922,8 @@ const char HTTP_ENERGY_ID_TELEINFO[] PROGMEM = "{s}ID{m}%s{e}" ;
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
//const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "%s{m}%d " D_UNIT_AMPERE "{e}" ;
-const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s%s{e}" ;
+const char HTTP_ENERGY_TARIF_TELEINFO_STD[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s{e}" ;
+const char HTTP_ENERGY_TARIF_TELEINFO_HISTO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}Heures %s{e}" ;
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}" D_CONTRACT "{m}%s %d" D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}" D_POWER_LOAD "{m}%d" D_UNIT_PERCENT "{e}" ;
const char HTTP_ENERGY_IMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d" D_UNIT_AMPERE "{e}" ;
@@ -977,9 +1014,9 @@ void TInfoShow(bool json)
if (tarif) {
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
if (tinfo_mode==TINFO_MODE_STANDARD ) {
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "", name);
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, name);
} else {
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "Heures ", name);
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_HISTO, name);
}
}
if (contrat && isousc) {
@@ -1006,7 +1043,7 @@ void TInfoShow(bool json)
WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value));
}
if (getValueFromLabelIndex(LABEL_LTARF, value) ) {
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, value);
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, value);
}
if (getValueFromLabelIndex(LABEL_NGTF, value) ) {
if (isousc) {
@@ -1035,6 +1072,9 @@ bool Xnrg15(uint8_t function)
case FUNC_INIT:
TInfoInit();
break;
+ case FUNC_SAVE_BEFORE_RESTART:
+ if (tinfo_found) { TInfoSaveBeforeRestart(); }
+ break;
case FUNC_PRE_INIT:
TInfoDrvInit();
break;
From b877c174b1fd5923041663ab91c9c87e55c1805a Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Thu, 27 Oct 2022 19:23:11 +0300
Subject: [PATCH 15/71] Ready fo test (32 bytes)
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 639a3a8c8..e55a9d94d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -83,8 +83,8 @@ struct PN532 {
uint8_t command = 0; // Carry command code between functions
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
bool present = false; // Maintain detection flag
-#ifdef USE_PN532_DATA_FUNCTION
uint16_t atqa;
+#ifdef USE_PN532_DATA_FUNCTION
uint8_t newdata[32];
uint8_t function = 0;
uint32_t pwd_auth=0x64636261;
@@ -336,15 +336,6 @@ bool PN532_SAMConfig(void) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
-void PN532_inRelease(void) {
- Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
- Pn532.packetbuffer[1] = 1;
- if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
- return;
- }
- PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
-}
-
/* void PN532_inSelect(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
Pn532.packetbuffer[1] = 1;
@@ -356,6 +347,15 @@ void PN532_inRelease(void) {
#ifdef USE_PN532_DATA_FUNCTION
+void PN532_inRelease(void) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
+ Pn532.packetbuffer[1] = 1;
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return;
+ }
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+}
+
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
uint8_t i;
uint8_t _key[6];
@@ -679,12 +679,12 @@ void PN532_ScanForTag(void) {
ResponseAppend_P(PSTR(",\"Auth\":\"NOk\""));
}
ResponseAppend_P(PSTR("}}"));
+ PN532_inRelease();
#else
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
#endif // USE_PN532_DATA_FUNCTION
MqttPublishTeleSensor();
- PN532_inRelease();
Pn532.scantimer = 7; // Ignore tags found for two seconds
}
}
@@ -706,7 +706,7 @@ bool PN532_Command(void) {
if (!strncmp_P(argument,PSTR("ERASE"),5)) {
memset(Pn532.newdata,0,sizeof(Pn532.newdata));
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be erased"));
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block will be erased"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
return serviced;
} else
From 3cccdd9c4f73ebdedd18bf28f0669147d78a87a3 Mon Sep 17 00:00:00 2001
From: barkow
Date: Thu, 27 Oct 2022 21:46:07 +0200
Subject: [PATCH 16/71] Change modbus rx message length check
Start evaluating messages already after message length information byte is received. Necessary to support read coil status messages.
---
tasmota/tasmota_xsns_sensor/xsns_53_sml.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
index 62e06f3ac..451044a8e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
@@ -1683,7 +1683,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
meter_spos[meters] = 0;
}
// modbus
- if (meter_spos[meters] >= 8) {
+ if (meter_spos[meters] >= 3) {
uint32_t mlen = smltbuf[meters][2] + 5;
if (mlen > SML_BSIZ) mlen = SML_BSIZ;
if (meter_spos[meters] >= mlen) {
From 116affb2fa8dd2cf928eb1a3069a40fe50843901 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:12:33 +0300
Subject: [PATCH 17/71] 16 bytes operational
---
tasmota/my_user_config.h | 4 +-
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 177 ++++++++----------
2 files changed, 82 insertions(+), 99 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 1838b9096..6bafe2c6a 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -776,8 +776,8 @@
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
-#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
- #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
+#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
+ #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index e55a9d94d..0819e2d4c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -16,8 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
- #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
#ifdef USE_PN532_HSU
/*********************************************************************************************\
@@ -85,7 +83,7 @@ struct PN532 {
bool present = false; // Maintain detection flag
uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[32];
+ uint8_t newdata[16];
uint8_t function = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
@@ -395,50 +393,47 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the command */
- for (uint8_t i = 0; i < 2; i++) {
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
- Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
/* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
- return 0;
- }
-
- /* Read the response packet */
- PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
-
- /* If byte 8 isn't 0x00 we probably have an error */
- if (Pn532.packetbuffer[0] != 0x00) {
- return 0;
- }
-
- /* Copy the 16 data bytes to the output buffer */
- /* Block content starts at byte 9 of a valid response */
- memcpy (&data[i<<4], &Pn532.packetbuffer[1], 16);
+ if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
+ return 0;
}
+
+ /* Read the response packet */
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+
+ /* If byte 8 isn't 0x00 we probably have an error */
+ if (Pn532.packetbuffer[0] != 0x00) {
+ return 0;
+ }
+
+ /* Copy the 16 data bytes to the output buffer */
+ /* Block content starts at byte 9 of a valid response */
+ memcpy (data, &Pn532.packetbuffer[1], 16);
return 1;
}
bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
- for (uint8_t i = 0; i < 2; i++) {
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
- Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- memcpy(&Pn532.packetbuffer[4], &data[i<<4], 16); /* Data Payload */
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
/* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return false;
- }
- /* Read the response packet */
- if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
- return false;
- }
+ if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
+ return false;
}
+ /* Read the response packet */
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
+ return false;
+ }
+
return true;
}
@@ -504,18 +499,6 @@ bool ntag2xx_read16 (const uint8_t page, char *out) {
return true;
}
-bool ntag2xx_read32 (const uint8_t page, char *out) { /* Size of oun must be >= 33 */
-
- if (!ntag2xx_read16(page, out)) {
- return false;
- }
- if (!ntag2xx_read16(page + 4, &out[16])) {
- return false;
- }
- out[32]=0;
- return true;
-}
-
bool ntag2xx_write4(uint8_t page, char *in) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
@@ -533,9 +516,9 @@ bool ntag2xx_write4(uint8_t page, char *in) {
return true;
}
-bool ntag2xx_writeN(uint8_t page, uint8_t numPages, char *in) {
+bool ntag2xx_write16(uint8_t page, char *in) {
- for (uint8_t i = 0; i < numPages; i++) {
+ for (uint8_t i = 0; i < 4; i++) {
if (!ntag2xx_write4(page +i, &in[i << 2])) {
return false;
}
@@ -549,13 +532,13 @@ bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
if (ntag2xx_read16(confPage, card_datas)) {
if (unsetPasswd) {
card_datas[3]=0xFF;
- return ntag2xx_writeN(confPage,1,card_datas);
+ return ntag2xx_write4(confPage, card_datas);
}
card_datas[3]=0; // Set AUTH0 for protect all pages
card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
- return ntag2xx_writeN(confPage,4,card_datas);
+ return ntag2xx_write16(confPage, card_datas);
}
return false;
}
@@ -570,7 +553,7 @@ void PN532_ScanForTag(void) {
#ifdef USE_PN532_DATA_FUNCTION
bool success = false;
- char card_datas[34]={0};
+ char card_datas[17]={0};
enum {NOPWD, PWD_NONE, PWD_OK, PWD_NOK} str_pwd=NOPWD;
if (Pn532.atqa == 0x44) {
@@ -580,7 +563,7 @@ void PN532_ScanForTag(void) {
if ((confPage=ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag2xx_read32(4, card_datas)) {
+ if (!ntag2xx_read16(4, card_datas)) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
if (ntag21x_auth()) {
@@ -594,7 +577,7 @@ void PN532_ScanForTag(void) {
} else {
str_pwd=PWD_NOK;
}
- if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
} else {
@@ -605,13 +588,13 @@ void PN532_ScanForTag(void) {
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
}
if ((Pn532.function == 1) || (Pn532.function == 2)) {
- success = ntag2xx_writeN(4, 8, (char *)Pn532.newdata);
- if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ success = ntag2xx_write16(4, (char *)Pn532.newdata);
+ if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
@@ -621,13 +604,12 @@ void PN532_ScanForTag(void) {
success=mifareclassic_WriteDataBlock(1, Pn532.newdata);
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0; i < 32;i++) {
+ for (uint32_t i = 0; i < 16; i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
card_datas[i] = 0;
}
}
- card_datas[32] = 0;
} else {
card_datas[0] = 0;
}
@@ -668,6 +650,7 @@ void PN532_ScanForTag(void) {
break;
}
Pn532.function = 0;
+ card_datas[16] = 0;
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas);
if (str_pwd == PWD_NONE) {
ResponseAppend_P(PSTR(",\"Auth\":\"None\""));
@@ -692,52 +675,45 @@ void PN532_ScanForTag(void) {
#ifdef USE_PN532_DATA_FUNCTION
bool PN532_Command(void) {
- bool serviced = true;
- uint8_t paramcount = 0;
- if (XdrvMailbox.data_len > 0) {
- paramcount=1;
- } else {
- serviced = false;
+ bool serviced = false;
+ char command[10];
+ char log[70];
+ if (ArgC() < 1) {
return serviced;
}
+
char argument[XdrvMailbox.data_len];
ArgV(argument, 1);
- UpperCase(argument,argument);
- if (!strncmp_P(argument,PSTR("ERASE"),5)) {
+ strncpy(command,UpperCase(argument,argument),sizeof(command));
+
+ if (!strcmp_P(argument,PSTR("ERASE"))) {
memset(Pn532.newdata,0,sizeof(Pn532.newdata));
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block will be erased"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
- return serviced;
- } else
- if (!strncmp_P(argument,PSTR("WRITE"),5)) {
+ snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be erased"));
+ serviced = true;
+ }
+ if (!strcmp_P(argument,PSTR("WRITE"))) {
if (ArgC() > 1) {
- if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
- serviced = false;
- return serviced;
- }
ArgV(argument, 2);
+ memset(Pn532.newdata,0,sizeof(Pn532.newdata));
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
- if (strlen(argument)>32) argument[32]=0;
+ if (strlen(argument)>16) argument[16]=0;
Pn532.function = 2;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be set to '%s'"), argument);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}"));
- return serviced;
+ snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be set to '%s'"), argument);
+ serviced = true;
}
- } else
- if (!strncmp_P(argument,PSTR("AUTH"),4)) {
+ }
+ if (!strcmp_P(argument,PSTR("AUTH"))) {
if (ArgC() > 1) {
Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"AUTH\"}}"));
}
if (ArgC() > 2) {
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
}
- return true;
- } else
- if (!strncmp_P(argument,PSTR("SET_PWD"),7)) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will set password"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}"));
+ serviced = true;
+ }
+ if (!strcmp_P(argument,PSTR("SET_PWD"))) {
+ snprintf_P(log, sizeof(log), PSTR("will be protected"));
Pn532.pwd_auth_new=Pn532.pwd_auth;
Pn532.pwd_pack_new=Pn532.pwd_pack;
if (ArgC() > 1) {
@@ -747,15 +723,22 @@ bool PN532_Command(void) {
Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0);
}
Pn532.function = 3;
- return true;
- } else
- if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will unset password"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
- Pn532.function = 4;
- return true;
+ serviced = true;
}
- return false;
+ if (!strcmp_P(argument,PSTR("UNSET_PWD"))) {
+ snprintf_P(log, sizeof(log), PSTR("will be unprotected"));
+ Pn532.function = 4;
+ serviced = true;
+ }
+ if (!strcmp_P(argument,PSTR("CANCEL"))) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Job canceled"));
+ Pn532.function = 0;
+ serviced = true;
+ } else {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag %s"), log);
+ }
+ if (serviced) ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"%s\"}}"),command);
+ return serviced;
}
#endif // USE_PN532_DATA_FUNCTION
From 0d22a162401a4c5bef51d11474844ea9dee1856e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:13:27 +0300
Subject: [PATCH 18/71] Disable in default config
---
tasmota/my_user_config.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 6bafe2c6a..858a3725e 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -776,8 +776,8 @@
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
-#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
- #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
+//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
+// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
From d152199aee6a181305faffaefe483b5a9218fe6e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:24:22 +0300
Subject: [PATCH 19/71] Edit formats
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 0819e2d4c..def685769 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -396,9 +396,9 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- /* Send the command */
+ /* Send the command */
if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
return 0;
}
@@ -414,27 +414,25 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Copy the 16 data bytes to the output buffer */
/* Block content starts at byte 9 of a valid response */
memcpy (data, &Pn532.packetbuffer[1], 16);
+
return 1;
}
-bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
+uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
/* Send the command */
if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return false;
- }
- /* Read the response packet */
- if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
- return false;
+ return 0;
}
- return true;
+ /* Read the response packet */
+return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
uint8_t ntag21x_probe (void) {
From 25079bb86b1fc57525be30af79e245f5c1c5a130 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:26:24 +0300
Subject: [PATCH 20/71] Ready for PR
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index def685769..c5afefa9f 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -432,7 +432,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
}
/* Read the response packet */
-return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
+ return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
uint8_t ntag21x_probe (void) {
From 1bf69fd3108a0ca10d4271375d759c78c191b14f Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 17:08:02 +0300
Subject: [PATCH 21/71] dali
---
tasmota/include/tasmota_template.h | 11 +
tasmota/language/af_AF.h | 7 +
tasmota/language/bg_BG.h | 7 +
tasmota/language/ca_AD.h | 7 +
tasmota/language/cs_CZ.h | 7 +
tasmota/language/de_DE.h | 7 +
tasmota/language/el_GR.h | 7 +
tasmota/language/en_GB.h | 7 +
tasmota/language/es_ES.h | 7 +
tasmota/language/fr_FR.h | 7 +
tasmota/language/fy_NL.h | 7 +
tasmota/language/he_HE.h | 7 +
tasmota/language/hu_HU.h | 7 +
tasmota/language/it_IT.h | 7 +
tasmota/language/ko_KO.h | 7 +
tasmota/language/nl_NL.h | 7 +
tasmota/language/pl_PL.h | 7 +
tasmota/language/pt_BR.h | 7 +
tasmota/language/pt_PT.h | 7 +
tasmota/language/ro_RO.h | 7 +
tasmota/language/ru_RU.h | 7 +
tasmota/language/sk_SK.h | 7 +
tasmota/language/sv_SE.h | 7 +
tasmota/language/tr_TR.h | 7 +
tasmota/language/uk_UA.h | 7 +
tasmota/language/vi_VN.h | 7 +
tasmota/language/zh_CN.h | 7 +
tasmota/language/zh_TW.h | 7 +
.../xdrv_89_esp32_dali.ino | 643 ++++++++++++++++++
29 files changed, 843 insertions(+)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 869e92a8c..76977bde0 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -198,6 +198,9 @@ enum UserSelectablePins {
GPIO_ADE7953_RST, // ADE7953 Reset
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
+#ifdef ESP32
+ GPIO_DALI_RX, GPIO_DALI_TX, // Dali
+#endif
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -443,6 +446,9 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ADE7953_RST "|"
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
+#ifdef ESP32
+ D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
+#endif
;
const char kSensorNamesFixed[] PROGMEM =
@@ -527,6 +533,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
* Protocol specifics
\*-------------------------------------------------------------------------------------------*/
+#if defined(USE_DALI) && defined(ESP32)
+ AGPIO(GPIO_DALI_RX), // DALI RX
+ AGPIO(GPIO_DALI_TX), // DALI TX
+#endif // USE_DALI
+
#ifdef USE_I2C
AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL
AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 58b48a17a..39dc3126b 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie Vandag"
#define D_ENERGY_YESTERDAY "Energie Gister"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 968746cd4..21ecbce73 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Консумация за днес"
#define D_ENERGY_YESTERDAY "Консумация за вчера"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 26bafafd8..01cf177b1 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
#define D_ENERGY_YESTERDAY "Energy Yesterday"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 2d32dcc9a..f1fea69ec 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotřeba Dnes"
#define D_ENERGY_YESTERDAY "Spotřeba Včera"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 05f940706..df8a827b1 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gefunden an Adresse"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zufällige Zigbee Parameter erstellt, Überprüfung mit 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie heute"
#define D_ENERGY_YESTERDAY "Energie gestern"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index d7cdbfe65..0d7500450 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
#define D_ENERGY_YESTERDAY "Ενέργεια χθες"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index ea85e0861..d59a97f01 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
#define D_ENERGY_YESTERDAY "Energy Yesterday"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index fa8dd2b67..b75beec9a 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Encontrada EEPROM de ZBBridge en"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Configurando parámetros Zigbee de forma aleatoria. Usar 'ZbConfig' para revisarlos."
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energía Hoy"
#define D_ENERGY_YESTERDAY "Energía Ayer"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 3364ff482..5f3eac5a3 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge trouvée à l'adresse"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomisation des paramètres ZigBee, veuillez vérifier avec 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xsns_03_energy.ino
#define D_ENERGY_TODAY "Énergie aujourd'hui"
#define D_ENERGY_YESTERDAY "Énergie hier"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 1e1a25927..a5f22689a 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM fûn op adres"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, kontrolearje asjebleaft mei 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Konsumpsje hjoed"
#define D_ENERGY_YESTERDAY "Konsumpsje juster"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 4db4cc9ff..31d969f78 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "צריכה יומית"
#define D_ENERGY_YESTERDAY "צריכה בעבר"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index d90312b00..c2204ea65 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM található a címen"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zigbee paramétereknek véletlennek kell lenniük, ellenőrizd a 'ZbConfig'-gal"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Mai energia"
#define D_ENERGY_YESTERDAY "Tegnapi energia"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 99301cc0e..5db1e1220 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Trovata EEPROM ZBBridge all'indirizzo"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizzazione parametri Zigbee, controlla con \"ZbConfig\""
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia - oggi"
#define D_ENERGY_YESTERDAY "Energia - ieri"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 5554f07a0..7e85879cc 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "금일 전력 사용량"
#define D_ENERGY_YESTERDAY "어제 전력 사용량"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 960a8fcf2..f2355a709 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM aanwezig op adres"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Willekeurige Zigbee parameters gemaakt, controleer met 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Verbruik vandaag"
#define D_ENERGY_YESTERDAY "Verbruik gisteren"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 1157da535..c523cec6f 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Znaleziono ZBBridge EEPROM na adresie"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Losowanie parametrów Zigbee, proszę sprawdzić 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia dzisiaj"
#define D_ENERGY_YESTERDAY "Energia wczoraj"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index fe96b16b8..b87b1a618 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge encontrada no endereço" // "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizando parametros Zigbee, por favor congira em 'ZbConfig'" // "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 3607f8252..c050785fa 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM encontrada no edereço"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomização de parâmetros Zigbee, por-favor verifique a 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index f51f0d07a..77ca813dc 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia de Azi"
#define D_ENERGY_YESTERDAY "Energia de Ieri"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index d45530605..fd9c3a7ee 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Конфигурация DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Энергия Сегодня"
#define D_ENERGY_YESTERDAY "Энергия Вчера"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 945bd72c1..8b1f107df 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotreba dnes"
#define D_ENERGY_YESTERDAY "Spotreba včera"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index ffc3e2764..a603635c3 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energi idag"
#define D_ENERGY_YESTERDAY "Energi igår"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index a19995a43..4c6d46b49 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
#define D_ENERGY_YESTERDAY "Energy Yesterday"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 8e832b9d8..1a6f34161 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Енергія Сьогодні"
#define D_ENERGY_YESTERDAY "Енергія Вчора"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index f87ba1029..7416d1dae 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Năng lượng tiêu thụ hôm nay"
#define D_ENERGY_YESTERDAY "Năng lượng tiêu thụ hôm qua"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 348718091..4f93019fc 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "找到 ZBBridge EEPROM, 地址:"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "正在随机化 Zigbee 参数, 请通过 'ZbConfig' 检查"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用电量"
#define D_ENERGY_YESTERDAY "昨日用电量"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 50c8c5dfb..641f8192c 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用電量"
#define D_ENERGY_YESTERDAY "昨日用電量"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
new file mode 100644
index 000000000..222f91bac
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -0,0 +1,643 @@
+/*
+ xdrv_89_esp32_dali.ino - DALI support for Tasmota
+
+ Copyright (C) 2022 Andrei Kazmirtsuk aka eeak
+
+ 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 .
+
+ --------------------------------------------------------------------------------------------
+ Version yyyymmdd Action Description
+ --------------------------------------------------------------------------------------------
+ 0.0.0.1 20221027 publish - initial version
+*/
+
+#ifdef ESP32
+#ifdef USE_DALI
+
+/*********************************************************************************************\
+ * DALI support for Tasmota
+\*********************************************************************************************/
+
+#define XDRV_89 89
+
+#define BROADCAST_DP 0b11111110 // 0xFE
+
+enum
+{
+ DALI_NO_ACTION,
+ DALI_SENDING_DATA,
+ DALI_RECEIVING_DATA,
+ DALI_ERROR
+};
+
+struct DALI {
+ bool present = false;
+} Dali;
+
+// http and json defines
+#define D_NAME_DALI "DALI"
+
+const char S_JSON_DALI_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_DALI "\":{\"%s\":%d}}";
+const char kDALI_Commands[] PROGMEM = D_CMND_DALI_POWER "|" D_CMND_DALI_DIMMER;
+
+enum DALI_Commands { // commands for Console
+ CMND_DALI_PWR,
+ CMND_DALI_DIM,
+};
+
+/* Private variables ---------------------------------------------------------*/
+// Communication ports and pins
+bool DALIOUT_invert = false;
+bool DALIIN_invert = false;
+// Data variables
+uint16_t send_dali_data; // data to send to DALI bus
+uint16_t received_dali_data; // data received from DALI bus
+// Processing variables
+uint8_t flag; // DALI status flag
+uint8_t bit_count; // nr of rec/send bits
+uint16_t tick_count; // nr of ticks of the timer
+
+bool bit_value; // value of actual bit
+bool actual_val; // bit value in this tick of timer
+bool former_val; // bit value in previous tick of timer
+
+hw_timer_t *DALI_timer = NULL;
+
+/*********************************************************************************************\
+ * DALI low level
+\*********************************************************************************************/
+
+/**
+* @brief This function handles hardware timer Handler.
+* @param None
+* @retval None
+*/
+void IRAM_ATTR DALI_Tick_Handler(void)
+{
+ if (get_flag() == DALI_RECEIVING_DATA)
+ {
+ receive_tick();
+ }
+ else if (get_flag() == DALI_SENDING_DATA)
+ {
+ send_tick();
+ }
+}
+
+/**
+* @brief This function enable data transfer start interrupt.
+* @param None
+* @retval None
+*/
+void enableDaliRxInterrupt() {
+ flag = DALI_NO_ACTION;
+ timerAlarmDisable(DALI_timer);
+ attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
+}
+
+/**
+* @brief This function disable data transfer start interrupt.
+* @param None
+* @retval None
+*/
+void disableRxInterrupt() {
+ timerAlarmEnable(DALI_timer);
+ detachInterrupt(Pin(GPIO_DALI_RX));
+}
+
+/**
+* @brief receiving flag status
+* @param None
+* @retval uint8_t flag
+*/
+uint8_t get_flag(void)
+{
+ return flag;
+}
+
+/**
+* @brief DALI data received callback
+* @param None
+* @retval uint8_t flag
+*/
+void DataReceivedCallback() {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), received_dali_data>>9, received_dali_data&0xff);
+}
+
+/*************** R E C E I V E * P R O C E D U R E S *******/
+
+/**
+* @brief receive data from DALI bus
+* @param None
+* @retval None
+*/
+void receiveDaliData()
+{
+ // null variables
+ received_dali_data = 0;
+ bit_count = 0;
+ tick_count = 0;
+ former_val = true;
+
+ flag = DALI_RECEIVING_DATA;
+
+ disableRxInterrupt();
+}
+
+/**
+* @brief Get state of DALIIN pin
+* @param None
+* @retval bool status
+*/
+bool get_DALIIN(void)
+{
+ bool dali_read = digitalRead(Pin(GPIO_DALI_RX));
+ return (false == DALIIN_invert) ? dali_read : !dali_read;
+}
+
+/**
+* @brief receiving data from DALI bus
+* @param None
+* @retval None
+*
+* |--------|----|---------------------------|----|
+* 0 24 32 160 176
+* wait start data stop
+*/
+void receive_tick(void)
+{
+ // four ticks per bit
+ actual_val = get_DALIIN();
+ tick_count++;
+
+ // edge detected
+ if(actual_val != former_val)
+ {
+ switch(bit_count)
+ {
+ case 0:
+ if (tick_count > 2)
+ {
+ tick_count = 0;
+ bit_count = 1; // start bit
+ }
+ break;
+ case 17: // 1st stop bit
+ if(tick_count > 6) { // stop bit error, no edge should exist
+ flag = DALI_ERROR;
+ }
+ break;
+ default: // other bits
+ if(tick_count > 6)
+ {
+ received_dali_data |= (actual_val << (16-bit_count));
+ bit_count++;
+ tick_count = 0;
+ }
+ break;
+ }
+ }else // voltage level stable
+ {
+ switch(bit_count)
+ {
+ case 0:
+ if(tick_count==8) { // too long start bit
+ flag = DALI_ERROR;
+ Serial.println("Too long start bit.");
+ }
+ break;
+ case 17:
+ // First stop bit
+ if (tick_count==8)
+ {
+ if (actual_val==0) // wrong level of stop bit
+ {
+ flag = DALI_ERROR;
+ }
+ else
+ {
+ bit_count++;
+ tick_count = 0;
+ }
+ }
+ break;
+ case 18:
+ // Second stop bit
+ if (tick_count==8)
+ {
+ enableDaliRxInterrupt();
+ DataReceivedCallback();
+
+ }
+ break;
+ default: // normal bits
+ if(tick_count==10)
+ { // too long delay before edge
+ flag = DALI_ERROR;
+ }
+ break;
+ }
+ }
+ former_val = actual_val;
+ if(flag==DALI_ERROR)
+ {
+ enableDaliRxInterrupt();
+ }
+}
+
+
+/*************** S E N D * P R O C E D U R E S *************/
+
+/**
+* @brief Set value to the DALIOUT pin
+* @param bool
+* @retval None
+*/
+void set_DALIOUT(bool pin_value)
+{
+ digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALIOUT_invert ? LOW : HIGH);
+}
+
+/**
+* @brief gets state of the DALIOUT pin
+* @param None
+* @retval bool state of the DALIOUT pin
+*/
+bool get_DALIOUT(void)
+{
+ bool dali_read = digitalRead(Pin(GPIO_DALI_TX));
+ return (false == DALIOUT_invert) ? dali_read : !dali_read;
+}
+
+/**
+* @brief Send data to DALI bus
+* @param byteToSend
+* @retval None
+*/
+void sendDaliData(uint8_t firstByte, uint8_t secondByte)
+{
+ send_dali_data = firstByte << 8;
+ send_dali_data += secondByte & 0xff;
+ bit_count = 0;
+ tick_count = 0;
+
+ flag = DALI_SENDING_DATA;
+
+ disableRxInterrupt();
+}
+
+/**
+* @brief DALI protocol physical layer for slave device
+* @param None
+* @retval None
+*
+* |--------|----|---------------------------|----|
+* 0 24 32 160 176
+* wait start data stop
+*/
+void send_tick(void)
+{
+ // access to the routine just every 4 ticks = every half bit
+ if ((tick_count & 0x03) == 0)
+ {
+ if (tick_count < 160)
+ {
+ // settling time between forward and backward frame
+ if (tick_count < 24)
+ {
+ tick_count++;
+ return;
+ }
+
+ // start of the start bit
+ if (tick_count == 24)
+ {
+ // GPIOB->ODR ^= GPIO_ODR_7;
+ set_DALIOUT(false);
+ tick_count++;
+ return;
+ }
+
+ // edge of the start bit
+ // 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
+ if (tick_count == 28)
+ {
+ set_DALIOUT(true);
+ tick_count++;
+ return;
+ }
+
+ // bit value (edge) selection
+ bit_value = (bool)((send_dali_data >> (15 - bit_count)) & 0x01);
+
+ // Every half bit -> Manchester coding
+ if (!((tick_count - 24) & 0x0007))
+ { // div by 8
+ if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
+ set_DALIOUT((bool)(1 - bit_value));
+ }
+
+ // Generate edge for actual bit
+ if (!((tick_count - 28) & 0x0007))
+ {
+ set_DALIOUT(bit_value);
+ bit_count++;
+ }
+ }
+ else
+ { // end of data byte, start of stop bits
+ if (tick_count == 160)
+ {
+ set_DALIOUT(true); // start of stop bit
+ }
+
+ // end of stop bits, no settling time
+ if (tick_count == 176)
+ {
+ enableDaliRxInterrupt();
+ }
+ }
+ }
+ tick_count++;
+
+ return;
+}
+
+/***********************************************************/
+
+void DaliPreInit() {
+ if (!PinUsed(GPIO_DALI_TX) || !PinUsed(GPIO_DALI_RX)) { return; }
+ AddLog(LOG_LEVEL_INFO, PSTR("DLI: Init - RX-pin: %d, TX-pin: %d"), Pin(GPIO_DALI_RX), Pin(GPIO_DALI_TX));
+ // pinMode(LED, OUTPUT);
+ pinMode(Pin(GPIO_DALI_TX), OUTPUT);
+ digitalWrite(Pin(GPIO_DALI_TX), HIGH);
+ pinMode(Pin(GPIO_DALI_RX), INPUT);
+
+ DALI_timer = timerBegin(0, 13, true);
+ timerAttachInterrupt(DALI_timer, &DALI_Tick_Handler, true);
+ timerAlarmWrite(DALI_timer, 641, true);
+
+ attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
+ enableDaliRxInterrupt();
+ Dali.present = true;
+}
+
+void DaliPwr(uint8_t val){
+ // AddLog(LOG_LEVEL_INFO, PSTR("DLI: Send to address %d value %d"), 0, val);
+ sendDaliData(BROADCAST_DP, val);
+}
+
+bool DaliCmd(void)
+{
+ char command[CMDSZ];
+ uint8_t name_len = strlen(D_NAME_DALI);
+ if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_DALI), name_len))
+ {
+ uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kDALI_Commands);
+ switch (command_code)
+ {
+ case CMND_DALI_PWR:
+ if (XdrvMailbox.data_len)
+ {
+ // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.data_len %d"), XdrvMailbox.data_len);
+ // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.payload %d"), XdrvMailbox.payload);
+ if (254 >= XdrvMailbox.payload)
+ {
+ DaliPwr(XdrvMailbox.payload);
+ }
+ }
+ // Response_P(S_JSON_DALI_COMMAND_NVALUE, command, DaliGetPwr());
+ Response_P(S_JSON_DALI_COMMAND_NVALUE, command, XdrvMailbox.payload);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/*********************************************************************************************\
+ * Presentation
+\*********************************************************************************************/
+
+#ifdef USE_WEBSERVER
+
+#define WEB_HANDLE_DALI "dali"
+
+const char HTTP_BTN_MENU_DALI[] PROGMEM =
+ "
";
+
+#endif // USE_WEBSERVER
+
+
+
+#define DALI_TOPIC "DALI"
+static char tmp[120];
+
+bool DaliMqtt()
+{
+ char stopic[TOPSZ];
+ strncpy(stopic, XdrvMailbox.topic, TOPSZ);
+ XdrvMailbox.topic[TOPSZ - 1] = 0;
+
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DALI mqtt: %s:%s"), stopic, XdrvMailbox.data);
+
+ // Разберем топик на слова по "/"
+ char *items[10];
+ char *p = stopic;
+ int cnt = 0;
+ do
+ {
+ items[cnt] = strtok(p, "/");
+ cnt++;
+ p = nullptr;
+ } while (items[cnt - 1]);
+ cnt--; // repreents the number of items
+
+ if (cnt < 3)
+ { // not for us?
+ AddLog(LOG_LEVEL_INFO,PSTR("cnt: %d < 3"), cnt);
+ return false;
+ }
+
+ // cnt-4 cnt -3 cnt-2 cnt-1
+ // cmnd/tasmota_078480/DALI/power :70
+ // cnt-5 cnt -4 cnt-3 cnt-2 cnt-1
+ // cmnd/tasmota_078480/DALI/power/0 :70
+ int DALIindex = 0;
+ int ADRindex = 0;
+ int CMDindex = 0;
+ uint8_t DALIaddr = BROADCAST_DP;
+ if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0)
+ {
+ // AddLog(LOG_LEVEL_INFO,PSTR("cnt-3 not %s"), PSTR(DALI_TOPIC));
+ if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0)
+ {
+ // AddLog(LOG_LEVEL_INFO,PSTR("cnt-2 not %s"), PSTR(DALI_TOPIC));
+ if (strcasecmp_P(items[cnt - 1], PSTR(DALI_TOPIC)) != 0)
+ {
+ return false; // not for us
+ }
+ else
+ {
+ // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle json"));
+ if (true == DaliJsonParse()) { return true; }
+ }
+ }
+ else
+ {
+ DALIindex = cnt - 2;
+ CMDindex = cnt - 1;
+ }
+ }
+ else
+ {
+ DALIindex = cnt - 3;
+ CMDindex = cnt - 2;
+ ADRindex = cnt - 1;
+ DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
+
+ }
+
+ // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle topic + data"));
+ uint8_t level;
+ uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data);
+ if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) {
+ float percent = (float)(254 * value * 0.01);
+ level = (uint8_t)percent;
+ }
+ else if (strcasecmp_P(items[CMDindex], PSTR("level")) == 0) {
+ level = value;
+ }
+ else {
+ AddLog(LOG_LEVEL_INFO,PSTR("command not recognized: %s"), items[CMDindex]);
+ return false; // not for us
+ }
+
+ AddLog(LOG_LEVEL_INFO,PSTR("Dali value %d on address %d"), value, DALIaddr);
+ sendDaliData(DALIaddr, level);
+
+ return true;
+}
+
+bool DaliJsonParse()
+{
+ bool served = false;
+
+ // if (strlen(XdrvMailbox.data) > 8) { // Workaround exception if empty JSON like {} - Needs checks
+ JsonParser parser((char *)XdrvMailbox.data);
+ JsonParserObject root = parser.getRootObject();
+ if (root)
+ {
+ int DALIindex = 0;
+ int ADRindex = 0;
+ int8_t DALIdim = -1;
+ uint8_t DALIaddr = BROADCAST_DP;
+
+ JsonParserToken val = root[PSTR("cmd")]; // Команда
+ if (val)
+ {
+ uint8_t cmd = val.getUInt();
+ val = root[PSTR("addr")];
+ if (val)
+ {
+ uint8_t addr = val.getUInt();
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
+ sendDaliData(addr, cmd);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ val = root[PSTR("addr")];
+ if (val)
+ {
+ uint8_t addr = val.getUInt();
+ if ((addr >= 0) && (addr < 64))
+ DALIaddr = addr << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json addr = %d"), val.getUInt());
+ }
+ val = root[PSTR("dim")];
+ if (val)
+ {
+ uint8_t dim = val.getUInt();
+ if ((dim >= 0) && (dim < 255))
+ DALIdim = dim;
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json dimmer = %d"), val.getUInt());
+ }
+ // val = root[PSTR("power")];
+ // if (val)
+ // {
+ // // FMqtt.file_type = val.getUInt();
+ // // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json power = %d"), val.getUInt());
+ // }
+ sendDaliData(DALIaddr, DALIdim);
+ served = true;
+ }
+ // else {
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json ERROR - not json"));
+ // }
+ // }
+
+ return served;
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xdrv89(uint8_t function)
+{
+ bool result = false;
+
+ if (FUNC_INIT == function)
+ {
+ DaliPreInit();
+ }
+ else if (Dali.present)
+ {
+ switch (function)
+ {
+ case FUNC_MQTT_DATA:
+ result = DaliMqtt();
+ break;
+ case FUNC_COMMAND:
+ result = DaliCmd();
+ break;
+#ifdef USE_WEBSERVER
+ // case FUNC_WEB_ADD_BUTTON:
+ // WSContentSend_P(HTTP_BTN_MENU_DALI);
+ // break;
+ // case FUNC_WEB_ADD_HANDLER:
+ // WebServer_on(PSTR("/" WEB_HANDLE_DALI), HandleDali);
+ // break;
+#ifdef USE_DALI_DISPLAYINPUT
+ // case FUNC_WEB_SENSOR:
+ // DaliShow(0);
+ // break;
+#endif // #ifdef USE_DALI_DISPLAYINPUT
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_DALI
+#endif // ESP32
\ No newline at end of file
From c1c0b25c174034adbb96578e228a77ed712fb7e0 Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 19:47:55 +0300
Subject: [PATCH 22/71] Clean up some comments and little refactor
---
tasmota/my_user_config.h | 4 +
.../xdrv_89_esp32_dali.ino | 138 +++++-------------
2 files changed, 43 insertions(+), 99 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 51ea0d677..8a4de54f0 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1034,6 +1034,10 @@
#define USE_ESP32_SENSORS // Add support for ESP32 temperature and optional hall effect sensor
+#define USE_DALI // Add support for DALI
+ #define DALI_IN_INVERT 0 // DALI RX inverted ?
+ #define DALI_OUT_INVERT 0 // DALI TX inverted ?
+
//#define USE_SONOFF_SPM // Add support for ESP32 based Sonoff Smart Stackable Power Meter (+11k code)
//#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 dsiplay driver used by Sonoff POWR3xxD and THR3xxD
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 222f91bac..844b71af6 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -32,6 +32,7 @@
#define XDRV_89 89
#define BROADCAST_DP 0b11111110 // 0xFE
+#define DALI_TOPIC "DALI"
enum
{
@@ -57,9 +58,6 @@ enum DALI_Commands { // commands for Console
};
/* Private variables ---------------------------------------------------------*/
-// Communication ports and pins
-bool DALIOUT_invert = false;
-bool DALIIN_invert = false;
// Data variables
uint16_t send_dali_data; // data to send to DALI bus
uint16_t received_dali_data; // data received from DALI bus
@@ -163,7 +161,7 @@ void receiveDaliData()
bool get_DALIIN(void)
{
bool dali_read = digitalRead(Pin(GPIO_DALI_RX));
- return (false == DALIIN_invert) ? dali_read : !dali_read;
+ return (false == DALI_IN_INVERT) ? dali_read : !dali_read;
}
/**
@@ -266,7 +264,7 @@ void receive_tick(void)
*/
void set_DALIOUT(bool pin_value)
{
- digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALIOUT_invert ? LOW : HIGH);
+ digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALI_OUT_INVERT ? LOW : HIGH);
}
/**
@@ -277,7 +275,7 @@ void set_DALIOUT(bool pin_value)
bool get_DALIOUT(void)
{
bool dali_read = digitalRead(Pin(GPIO_DALI_TX));
- return (false == DALIOUT_invert) ? dali_read : !dali_read;
+ return (false == DALI_OUT_INVERT) ? dali_read : !dali_read;
}
/**
@@ -394,7 +392,6 @@ void DaliPreInit() {
}
void DaliPwr(uint8_t val){
- // AddLog(LOG_LEVEL_INFO, PSTR("DLI: Send to address %d value %d"), 0, val);
sendDaliData(BROADCAST_DP, val);
}
@@ -410,14 +407,11 @@ bool DaliCmd(void)
case CMND_DALI_PWR:
if (XdrvMailbox.data_len)
{
- // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.data_len %d"), XdrvMailbox.data_len);
- // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.payload %d"), XdrvMailbox.payload);
if (254 >= XdrvMailbox.payload)
{
DaliPwr(XdrvMailbox.payload);
}
}
- // Response_P(S_JSON_DALI_COMMAND_NVALUE, command, DaliGetPwr());
Response_P(S_JSON_DALI_COMMAND_NVALUE, command, XdrvMailbox.payload);
break;
default:
@@ -431,23 +425,6 @@ bool DaliCmd(void)
}
}
-/*********************************************************************************************\
- * Presentation
-\*********************************************************************************************/
-
-#ifdef USE_WEBSERVER
-
-#define WEB_HANDLE_DALI "dali"
-
-const char HTTP_BTN_MENU_DALI[] PROGMEM =
- "";
-
-#endif // USE_WEBSERVER
-
-
-
-#define DALI_TOPIC "DALI"
-static char tmp[120];
bool DaliMqtt()
{
@@ -455,9 +432,6 @@ bool DaliMqtt()
strncpy(stopic, XdrvMailbox.topic, TOPSZ);
XdrvMailbox.topic[TOPSZ - 1] = 0;
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DALI mqtt: %s:%s"), stopic, XdrvMailbox.data);
-
- // Разберем топик на слова по "/"
char *items[10];
char *p = stopic;
int cnt = 0;
@@ -475,27 +449,20 @@ bool DaliMqtt()
return false;
}
- // cnt-4 cnt -3 cnt-2 cnt-1
- // cmnd/tasmota_078480/DALI/power :70
- // cnt-5 cnt -4 cnt-3 cnt-2 cnt-1
- // cmnd/tasmota_078480/DALI/power/0 :70
int DALIindex = 0;
int ADRindex = 0;
int CMDindex = 0;
uint8_t DALIaddr = BROADCAST_DP;
if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0)
{
- // AddLog(LOG_LEVEL_INFO,PSTR("cnt-3 not %s"), PSTR(DALI_TOPIC));
if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0)
{
- // AddLog(LOG_LEVEL_INFO,PSTR("cnt-2 not %s"), PSTR(DALI_TOPIC));
if (strcasecmp_P(items[cnt - 1], PSTR(DALI_TOPIC)) != 0)
{
return false; // not for us
}
else
{
- // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle json"));
if (true == DaliJsonParse()) { return true; }
}
}
@@ -510,11 +477,10 @@ bool DaliMqtt()
DALIindex = cnt - 3;
CMDindex = cnt - 2;
ADRindex = cnt - 1;
- DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
+ DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1;
}
- // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle topic + data"));
uint8_t level;
uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data);
if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) {
@@ -538,63 +504,50 @@ bool DaliMqtt()
bool DaliJsonParse()
{
bool served = false;
+ JsonParser parser((char *)XdrvMailbox.data);
+ JsonParserObject root = parser.getRootObject();
+ if (root)
+ {
+ int DALIindex = 0;
+ int ADRindex = 0;
+ int8_t DALIdim = -1;
+ uint8_t DALIaddr = BROADCAST_DP;
- // if (strlen(XdrvMailbox.data) > 8) { // Workaround exception if empty JSON like {} - Needs checks
- JsonParser parser((char *)XdrvMailbox.data);
- JsonParserObject root = parser.getRootObject();
- if (root)
+ JsonParserToken val = root[PSTR("cmd")];
+ if (val)
{
- int DALIindex = 0;
- int ADRindex = 0;
- int8_t DALIdim = -1;
- uint8_t DALIaddr = BROADCAST_DP;
-
- JsonParserToken val = root[PSTR("cmd")]; // Команда
- if (val)
- {
- uint8_t cmd = val.getUInt();
- val = root[PSTR("addr")];
- if (val)
- {
- uint8_t addr = val.getUInt();
- AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
- sendDaliData(addr, cmd);
- return true;
- }
- else
- {
- return false;
- }
- }
+ uint8_t cmd = val.getUInt();
val = root[PSTR("addr")];
if (val)
{
uint8_t addr = val.getUInt();
- if ((addr >= 0) && (addr < 64))
- DALIaddr = addr << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json addr = %d"), val.getUInt());
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
+ sendDaliData(addr, cmd);
+ return true;
}
- val = root[PSTR("dim")];
- if (val)
+ else
{
- uint8_t dim = val.getUInt();
- if ((dim >= 0) && (dim < 255))
- DALIdim = dim;
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json dimmer = %d"), val.getUInt());
+ return false;
}
- // val = root[PSTR("power")];
- // if (val)
- // {
- // // FMqtt.file_type = val.getUInt();
- // // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json power = %d"), val.getUInt());
- // }
- sendDaliData(DALIaddr, DALIdim);
- served = true;
}
- // else {
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json ERROR - not json"));
- // }
- // }
+ val = root[PSTR("addr")];
+ if (val)
+ {
+ uint8_t addr = val.getUInt();
+ if ((addr >= 0) && (addr < 64))
+ DALIaddr = addr << 1;
+ }
+ val = root[PSTR("dim")];
+ if (val)
+ {
+ uint8_t dim = val.getUInt();
+ if (dim < 255)
+ DALIdim = dim;
+ }
+
+ sendDaliData(DALIaddr, DALIdim);
+ served = true;
+ }
return served;
}
@@ -621,19 +574,6 @@ bool Xdrv89(uint8_t function)
case FUNC_COMMAND:
result = DaliCmd();
break;
-#ifdef USE_WEBSERVER
- // case FUNC_WEB_ADD_BUTTON:
- // WSContentSend_P(HTTP_BTN_MENU_DALI);
- // break;
- // case FUNC_WEB_ADD_HANDLER:
- // WebServer_on(PSTR("/" WEB_HANDLE_DALI), HandleDali);
- // break;
-#ifdef USE_DALI_DISPLAYINPUT
- // case FUNC_WEB_SENSOR:
- // DaliShow(0);
- // break;
-#endif // #ifdef USE_DALI_DISPLAYINPUT
-#endif // USE_WEBSERVER
}
}
return result;
From 76c5be76346ef1fb85918b6e91a10963cd30d263 Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 20:16:45 +0300
Subject: [PATCH 23/71] Packed global variables into a struct
---
.../xdrv_89_esp32_dali.ino | 146 +++++++++---------
1 file changed, 77 insertions(+), 69 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 844b71af6..39ac47a3f 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -42,10 +42,6 @@ enum
DALI_ERROR
};
-struct DALI {
- bool present = false;
-} Dali;
-
// http and json defines
#define D_NAME_DALI "DALI"
@@ -59,16 +55,29 @@ enum DALI_Commands { // commands for Console
/* Private variables ---------------------------------------------------------*/
// Data variables
-uint16_t send_dali_data; // data to send to DALI bus
-uint16_t received_dali_data; // data received from DALI bus
+// uint16_t send_dali_data; // data to send to DALI bus
+// uint16_t received_dali_data; // data received from DALI bus
// Processing variables
-uint8_t flag; // DALI status flag
-uint8_t bit_count; // nr of rec/send bits
-uint16_t tick_count; // nr of ticks of the timer
+// uint8_t flag; // DALI status flag
+// uint8_t bit_count; // nr of rec/send bits
+// uint16_t tick_count; // nr of ticks of the timer
-bool bit_value; // value of actual bit
-bool actual_val; // bit value in this tick of timer
-bool former_val; // bit value in previous tick of timer
+// bool bit_value; // value of actual bit
+// bool actual_val; // bit value in this tick of timer
+// bool former_val; // bit value in previous tick of timer
+
+struct DALI {
+ // Data variables
+ uint16_t send_dali_data; // data to send to DALI bus
+ uint16_t received_dali_data; // data received from DALI bus
+ // Processing variables
+ uint8_t flag; // DALI status flag
+ uint8_t bit_count; // nr of rec/send bits
+ uint16_t tick_count; // nr of ticks of the timer
+ bool former_val; // bit value in previous tick of timer
+
+ bool present = false;// DALI initialized
+} Dali;
hw_timer_t *DALI_timer = NULL;
@@ -83,11 +92,11 @@ hw_timer_t *DALI_timer = NULL;
*/
void IRAM_ATTR DALI_Tick_Handler(void)
{
- if (get_flag() == DALI_RECEIVING_DATA)
+ if (getDaliFlag() == DALI_RECEIVING_DATA)
{
receive_tick();
}
- else if (get_flag() == DALI_SENDING_DATA)
+ else if (getDaliFlag() == DALI_SENDING_DATA)
{
send_tick();
}
@@ -99,7 +108,7 @@ void IRAM_ATTR DALI_Tick_Handler(void)
* @retval None
*/
void enableDaliRxInterrupt() {
- flag = DALI_NO_ACTION;
+ Dali.flag = DALI_NO_ACTION;
timerAlarmDisable(DALI_timer);
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
}
@@ -119,9 +128,9 @@ void disableRxInterrupt() {
* @param None
* @retval uint8_t flag
*/
-uint8_t get_flag(void)
+uint8_t getDaliFlag(void)
{
- return flag;
+ return Dali.flag;
}
/**
@@ -130,7 +139,7 @@ uint8_t get_flag(void)
* @retval uint8_t flag
*/
void DataReceivedCallback() {
- AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), received_dali_data>>9, received_dali_data&0xff);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali.received_dali_data>>9, Dali.received_dali_data&0xff);
}
/*************** R E C E I V E * P R O C E D U R E S *******/
@@ -143,12 +152,12 @@ void DataReceivedCallback() {
void receiveDaliData()
{
// null variables
- received_dali_data = 0;
- bit_count = 0;
- tick_count = 0;
- former_val = true;
+ Dali.received_dali_data = 0;
+ Dali.bit_count = 0;
+ Dali.tick_count = 0;
+ Dali.former_val = true;
- flag = DALI_RECEIVING_DATA;
+ Dali.flag = DALI_RECEIVING_DATA;
disableRxInterrupt();
}
@@ -176,63 +185,62 @@ bool get_DALIIN(void)
void receive_tick(void)
{
// four ticks per bit
- actual_val = get_DALIIN();
- tick_count++;
+ bool actual_val = get_DALIIN();
+ Dali.tick_count++;
// edge detected
- if(actual_val != former_val)
+ if(actual_val != Dali.former_val)
{
- switch(bit_count)
+ switch(Dali.bit_count)
{
case 0:
- if (tick_count > 2)
+ if (Dali.tick_count > 2)
{
- tick_count = 0;
- bit_count = 1; // start bit
+ Dali.tick_count = 0;
+ Dali.bit_count = 1; // start bit
}
break;
case 17: // 1st stop bit
- if(tick_count > 6) { // stop bit error, no edge should exist
- flag = DALI_ERROR;
+ if(Dali.tick_count > 6) { // stop bit error, no edge should exist
+ Dali.flag = DALI_ERROR;
}
break;
default: // other bits
- if(tick_count > 6)
+ if(Dali.tick_count > 6)
{
- received_dali_data |= (actual_val << (16-bit_count));
- bit_count++;
- tick_count = 0;
+ Dali.received_dali_data |= (actual_val << (16-Dali.bit_count));
+ Dali.bit_count++;
+ Dali.tick_count = 0;
}
break;
}
}else // voltage level stable
{
- switch(bit_count)
+ switch(Dali.bit_count)
{
case 0:
- if(tick_count==8) { // too long start bit
- flag = DALI_ERROR;
- Serial.println("Too long start bit.");
+ if(Dali.tick_count==8) { // too long start bit
+ Dali.flag = DALI_ERROR;
}
break;
case 17:
// First stop bit
- if (tick_count==8)
+ if (Dali.tick_count==8)
{
if (actual_val==0) // wrong level of stop bit
{
- flag = DALI_ERROR;
+ Dali.flag = DALI_ERROR;
}
else
{
- bit_count++;
- tick_count = 0;
+ Dali.bit_count++;
+ Dali.tick_count = 0;
}
}
break;
case 18:
// Second stop bit
- if (tick_count==8)
+ if (Dali.tick_count==8)
{
enableDaliRxInterrupt();
DataReceivedCallback();
@@ -240,15 +248,15 @@ void receive_tick(void)
}
break;
default: // normal bits
- if(tick_count==10)
+ if(Dali.tick_count==10)
{ // too long delay before edge
- flag = DALI_ERROR;
+ Dali.flag = DALI_ERROR;
}
break;
}
}
- former_val = actual_val;
- if(flag==DALI_ERROR)
+ Dali.former_val = actual_val;
+ if(getDaliFlag() == DALI_ERROR)
{
enableDaliRxInterrupt();
}
@@ -285,12 +293,12 @@ bool get_DALIOUT(void)
*/
void sendDaliData(uint8_t firstByte, uint8_t secondByte)
{
- send_dali_data = firstByte << 8;
- send_dali_data += secondByte & 0xff;
- bit_count = 0;
- tick_count = 0;
+ Dali.send_dali_data = firstByte << 8;
+ Dali.send_dali_data += secondByte & 0xff;
+ Dali.bit_count = 0;
+ Dali.tick_count = 0;
- flag = DALI_SENDING_DATA;
+ Dali.flag = DALI_SENDING_DATA;
disableRxInterrupt();
}
@@ -307,67 +315,67 @@ void sendDaliData(uint8_t firstByte, uint8_t secondByte)
void send_tick(void)
{
// access to the routine just every 4 ticks = every half bit
- if ((tick_count & 0x03) == 0)
+ if ((Dali.tick_count & 0x03) == 0)
{
- if (tick_count < 160)
+ if (Dali.tick_count < 160)
{
// settling time between forward and backward frame
- if (tick_count < 24)
+ if (Dali.tick_count < 24)
{
- tick_count++;
+ Dali.tick_count++;
return;
}
// start of the start bit
- if (tick_count == 24)
+ if (Dali.tick_count == 24)
{
// GPIOB->ODR ^= GPIO_ODR_7;
set_DALIOUT(false);
- tick_count++;
+ Dali.tick_count++;
return;
}
// edge of the start bit
// 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
- if (tick_count == 28)
+ if (Dali.tick_count == 28)
{
set_DALIOUT(true);
- tick_count++;
+ Dali.tick_count++;
return;
}
// bit value (edge) selection
- bit_value = (bool)((send_dali_data >> (15 - bit_count)) & 0x01);
+ bool bit_value = (bool)((Dali.send_dali_data >> (15 - Dali.bit_count)) & 0x01);
// Every half bit -> Manchester coding
- if (!((tick_count - 24) & 0x0007))
+ if (!((Dali.tick_count - 24) & 0x0007))
{ // div by 8
if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
set_DALIOUT((bool)(1 - bit_value));
}
// Generate edge for actual bit
- if (!((tick_count - 28) & 0x0007))
+ if (!((Dali.tick_count - 28) & 0x0007))
{
set_DALIOUT(bit_value);
- bit_count++;
+ Dali.bit_count++;
}
}
else
{ // end of data byte, start of stop bits
- if (tick_count == 160)
+ if (Dali.tick_count == 160)
{
set_DALIOUT(true); // start of stop bit
}
// end of stop bits, no settling time
- if (tick_count == 176)
+ if (Dali.tick_count == 176)
{
enableDaliRxInterrupt();
}
}
}
- tick_count++;
+ Dali.tick_count++;
return;
}
From 404db7965e84421d6cb83e4b536fc2cd0142f49b Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 21:57:40 +0300
Subject: [PATCH 24/71] Timer number is now declared in my_user_config.h
---
tasmota/my_user_config.h | 1 +
.../xdrv_89_esp32_dali.ino | 19 +++++--------------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 8a4de54f0..3e2d83a5b 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1037,6 +1037,7 @@
#define USE_DALI // Add support for DALI
#define DALI_IN_INVERT 0 // DALI RX inverted ?
#define DALI_OUT_INVERT 0 // DALI TX inverted ?
+ #define DALI_TIMER 0 // ESP32 hardware timer number 0-3 !!! timer 3 used in xdrv_10_scripter.ino !!!
//#define USE_SONOFF_SPM // Add support for ESP32 based Sonoff Smart Stackable Power Meter (+11k code)
//#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 dsiplay driver used by Sonoff POWR3xxD and THR3xxD
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 39ac47a3f..87523b6e0 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -31,6 +31,10 @@
#define XDRV_89 89
+#ifndef DALI_TIMER
+ #define DALI_TIMER 0 // Default timer
+#endif
+
#define BROADCAST_DP 0b11111110 // 0xFE
#define DALI_TOPIC "DALI"
@@ -53,19 +57,6 @@ enum DALI_Commands { // commands for Console
CMND_DALI_DIM,
};
-/* Private variables ---------------------------------------------------------*/
-// Data variables
-// uint16_t send_dali_data; // data to send to DALI bus
-// uint16_t received_dali_data; // data received from DALI bus
-// Processing variables
-// uint8_t flag; // DALI status flag
-// uint8_t bit_count; // nr of rec/send bits
-// uint16_t tick_count; // nr of ticks of the timer
-
-// bool bit_value; // value of actual bit
-// bool actual_val; // bit value in this tick of timer
-// bool former_val; // bit value in previous tick of timer
-
struct DALI {
// Data variables
uint16_t send_dali_data; // data to send to DALI bus
@@ -390,7 +381,7 @@ void DaliPreInit() {
digitalWrite(Pin(GPIO_DALI_TX), HIGH);
pinMode(Pin(GPIO_DALI_RX), INPUT);
- DALI_timer = timerBegin(0, 13, true);
+ DALI_timer = timerBegin(DALI_TIMER, 13, true);
timerAttachInterrupt(DALI_timer, &DALI_Tick_Handler, true);
timerAlarmWrite(DALI_timer, 641, true);
From 5dc5e11dc98d65967d76b051f838f5c0b32a41d4 Mon Sep 17 00:00:00 2001
From: Staars
Date: Sat, 29 Oct 2022 10:56:53 +0200
Subject: [PATCH 25/71] check for valid cdc config: board vs env
---
pio-tools/post_esp32.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py
index 3ded90386..370934845 100644
--- a/pio-tools/post_esp32.py
+++ b/pio-tools/post_esp32.py
@@ -139,6 +139,11 @@ def esp32_create_combined_bin(source, target, env):
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
chip = env.get("BOARD_MCU")
tasmota_platform = esp32_create_chip_string(chip)
+
+ if "-DUSE_USB_CDC_CONSOLE" in env.BoardConfig().get("build.extra_flags") and "cdc" not in tasmota_platform:
+ tasmota_platform += "cdc"
+ print("WARNING: board definition uses CDC configuration, but environment name does not -> changing tasmota safeboot binary to:", tasmota_platform + "-safeboot.bin")
+
if not os.path.exists(variants_dir):
os.makedirs(variants_dir)
if("safeboot" in firmware_name):
From 6c0e38e38d783646b0ed12d3485ceb244ff9d61b Mon Sep 17 00:00:00 2001
From: eeak
Date: Sat, 29 Oct 2022 12:50:41 +0300
Subject: [PATCH 26/71] Data struct rebuilded. Thanks barbudor for help
---
tasmota/my_user_config.h | 2 +-
.../xdrv_89_esp32_dali.ino | 135 +++++++++---------
2 files changed, 69 insertions(+), 68 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 3e2d83a5b..24077f12f 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1034,7 +1034,7 @@
#define USE_ESP32_SENSORS // Add support for ESP32 temperature and optional hall effect sensor
-#define USE_DALI // Add support for DALI
+// #define USE_DALI // Add support for DALI
#define DALI_IN_INVERT 0 // DALI RX inverted ?
#define DALI_OUT_INVERT 0 // DALI TX inverted ?
#define DALI_TIMER 0 // ESP32 hardware timer number 0-3 !!! timer 3 used in xdrv_10_scripter.ino !!!
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 87523b6e0..0a247a2bd 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -58,19 +58,16 @@ enum DALI_Commands { // commands for Console
};
struct DALI {
- // Data variables
uint16_t send_dali_data; // data to send to DALI bus
uint16_t received_dali_data; // data received from DALI bus
- // Processing variables
- uint8_t flag; // DALI status flag
- uint8_t bit_count; // nr of rec/send bits
- uint16_t tick_count; // nr of ticks of the timer
- bool former_val; // bit value in previous tick of timer
+ uint8_t flag; // DALI status flag
+ uint8_t bit_count; // nr of rec/send bits
+ uint16_t tick_count; // nr of ticks of the timer
+ bool former_val; // bit value in previous tick of timer
+ hw_timer_t *timer; // hardware timer
+} *Dali = nullptr;
- bool present = false;// DALI initialized
-} Dali;
-hw_timer_t *DALI_timer = NULL;
/*********************************************************************************************\
* DALI low level
@@ -99,8 +96,8 @@ void IRAM_ATTR DALI_Tick_Handler(void)
* @retval None
*/
void enableDaliRxInterrupt() {
- Dali.flag = DALI_NO_ACTION;
- timerAlarmDisable(DALI_timer);
+ Dali->flag = DALI_NO_ACTION;
+ timerAlarmDisable(Dali->timer);
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
}
@@ -110,7 +107,7 @@ void enableDaliRxInterrupt() {
* @retval None
*/
void disableRxInterrupt() {
- timerAlarmEnable(DALI_timer);
+ timerAlarmEnable(Dali->timer);
detachInterrupt(Pin(GPIO_DALI_RX));
}
@@ -121,7 +118,7 @@ void disableRxInterrupt() {
*/
uint8_t getDaliFlag(void)
{
- return Dali.flag;
+ return Dali->flag;
}
/**
@@ -130,7 +127,7 @@ uint8_t getDaliFlag(void)
* @retval uint8_t flag
*/
void DataReceivedCallback() {
- AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali.received_dali_data>>9, Dali.received_dali_data&0xff);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali->received_dali_data>>9, Dali->received_dali_data&0xff);
}
/*************** R E C E I V E * P R O C E D U R E S *******/
@@ -143,12 +140,12 @@ void DataReceivedCallback() {
void receiveDaliData()
{
// null variables
- Dali.received_dali_data = 0;
- Dali.bit_count = 0;
- Dali.tick_count = 0;
- Dali.former_val = true;
+ Dali->received_dali_data = 0;
+ Dali->bit_count = 0;
+ Dali->tick_count = 0;
+ Dali->former_val = true;
- Dali.flag = DALI_RECEIVING_DATA;
+ Dali->flag = DALI_RECEIVING_DATA;
disableRxInterrupt();
}
@@ -177,61 +174,61 @@ void receive_tick(void)
{
// four ticks per bit
bool actual_val = get_DALIIN();
- Dali.tick_count++;
+ Dali->tick_count++;
// edge detected
- if(actual_val != Dali.former_val)
+ if(actual_val != Dali->former_val)
{
- switch(Dali.bit_count)
+ switch(Dali->bit_count)
{
case 0:
- if (Dali.tick_count > 2)
+ if (Dali->tick_count > 2)
{
- Dali.tick_count = 0;
- Dali.bit_count = 1; // start bit
+ Dali->tick_count = 0;
+ Dali->bit_count = 1; // start bit
}
break;
case 17: // 1st stop bit
- if(Dali.tick_count > 6) { // stop bit error, no edge should exist
- Dali.flag = DALI_ERROR;
+ if(Dali->tick_count > 6) { // stop bit error, no edge should exist
+ Dali->flag = DALI_ERROR;
}
break;
default: // other bits
- if(Dali.tick_count > 6)
+ if(Dali->tick_count > 6)
{
- Dali.received_dali_data |= (actual_val << (16-Dali.bit_count));
- Dali.bit_count++;
- Dali.tick_count = 0;
+ Dali->received_dali_data |= (actual_val << (16-Dali->bit_count));
+ Dali->bit_count++;
+ Dali->tick_count = 0;
}
break;
}
}else // voltage level stable
{
- switch(Dali.bit_count)
+ switch(Dali->bit_count)
{
case 0:
- if(Dali.tick_count==8) { // too long start bit
- Dali.flag = DALI_ERROR;
+ if(Dali->tick_count==8) { // too long start bit
+ Dali->flag = DALI_ERROR;
}
break;
case 17:
// First stop bit
- if (Dali.tick_count==8)
+ if (Dali->tick_count==8)
{
if (actual_val==0) // wrong level of stop bit
{
- Dali.flag = DALI_ERROR;
+ Dali->flag = DALI_ERROR;
}
else
{
- Dali.bit_count++;
- Dali.tick_count = 0;
+ Dali->bit_count++;
+ Dali->tick_count = 0;
}
}
break;
case 18:
// Second stop bit
- if (Dali.tick_count==8)
+ if (Dali->tick_count==8)
{
enableDaliRxInterrupt();
DataReceivedCallback();
@@ -239,14 +236,14 @@ void receive_tick(void)
}
break;
default: // normal bits
- if(Dali.tick_count==10)
+ if(Dali->tick_count==10)
{ // too long delay before edge
- Dali.flag = DALI_ERROR;
+ Dali->flag = DALI_ERROR;
}
break;
}
}
- Dali.former_val = actual_val;
+ Dali->former_val = actual_val;
if(getDaliFlag() == DALI_ERROR)
{
enableDaliRxInterrupt();
@@ -284,12 +281,12 @@ bool get_DALIOUT(void)
*/
void sendDaliData(uint8_t firstByte, uint8_t secondByte)
{
- Dali.send_dali_data = firstByte << 8;
- Dali.send_dali_data += secondByte & 0xff;
- Dali.bit_count = 0;
- Dali.tick_count = 0;
+ Dali->send_dali_data = firstByte << 8;
+ Dali->send_dali_data += secondByte & 0xff;
+ Dali->bit_count = 0;
+ Dali->tick_count = 0;
- Dali.flag = DALI_SENDING_DATA;
+ Dali->flag = DALI_SENDING_DATA;
disableRxInterrupt();
}
@@ -306,67 +303,67 @@ void sendDaliData(uint8_t firstByte, uint8_t secondByte)
void send_tick(void)
{
// access to the routine just every 4 ticks = every half bit
- if ((Dali.tick_count & 0x03) == 0)
+ if ((Dali->tick_count & 0x03) == 0)
{
- if (Dali.tick_count < 160)
+ if (Dali->tick_count < 160)
{
// settling time between forward and backward frame
- if (Dali.tick_count < 24)
+ if (Dali->tick_count < 24)
{
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
// start of the start bit
- if (Dali.tick_count == 24)
+ if (Dali->tick_count == 24)
{
// GPIOB->ODR ^= GPIO_ODR_7;
set_DALIOUT(false);
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
// edge of the start bit
// 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
- if (Dali.tick_count == 28)
+ if (Dali->tick_count == 28)
{
set_DALIOUT(true);
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
// bit value (edge) selection
- bool bit_value = (bool)((Dali.send_dali_data >> (15 - Dali.bit_count)) & 0x01);
+ bool bit_value = (bool)((Dali->send_dali_data >> (15 - Dali->bit_count)) & 0x01);
// Every half bit -> Manchester coding
- if (!((Dali.tick_count - 24) & 0x0007))
+ if (!((Dali->tick_count - 24) & 0x0007))
{ // div by 8
if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
set_DALIOUT((bool)(1 - bit_value));
}
// Generate edge for actual bit
- if (!((Dali.tick_count - 28) & 0x0007))
+ if (!((Dali->tick_count - 28) & 0x0007))
{
set_DALIOUT(bit_value);
- Dali.bit_count++;
+ Dali->bit_count++;
}
}
else
{ // end of data byte, start of stop bits
- if (Dali.tick_count == 160)
+ if (Dali->tick_count == 160)
{
set_DALIOUT(true); // start of stop bit
}
// end of stop bits, no settling time
- if (Dali.tick_count == 176)
+ if (Dali->tick_count == 176)
{
enableDaliRxInterrupt();
}
}
}
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
@@ -381,13 +378,17 @@ void DaliPreInit() {
digitalWrite(Pin(GPIO_DALI_TX), HIGH);
pinMode(Pin(GPIO_DALI_RX), INPUT);
- DALI_timer = timerBegin(DALI_TIMER, 13, true);
- timerAttachInterrupt(DALI_timer, &DALI_Tick_Handler, true);
- timerAlarmWrite(DALI_timer, 641, true);
+ Dali = (DALI*)calloc(1,sizeof(DALI));
+ if (!Dali) {
+ AddLog(LOG_LEVEL_INFO, PSTR("DLI: Memory allocation error"));
+ return;
+ }
+ Dali->timer = timerBegin(DALI_TIMER, 13, true);
+ timerAttachInterrupt(Dali->timer, &DALI_Tick_Handler, true);
+ timerAlarmWrite(Dali->timer, 641, true);
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
enableDaliRxInterrupt();
- Dali.present = true;
}
void DaliPwr(uint8_t val){
@@ -563,7 +564,7 @@ bool Xdrv89(uint8_t function)
{
DaliPreInit();
}
- else if (Dali.present)
+ else if (Dali)
{
switch (function)
{
From 4e98cbb387d619a2e4d93a785acecc81b680111a Mon Sep 17 00:00:00 2001
From: eeak
Date: Sat, 29 Oct 2022 16:09:09 +0300
Subject: [PATCH 27/71] moved D_CMND_xx to i18n.h
---
tasmota/include/i18n.h | 4 ++++
tasmota/language/af_AF.h | 2 --
tasmota/language/bg_BG.h | 2 --
tasmota/language/ca_AD.h | 2 --
tasmota/language/cs_CZ.h | 2 --
tasmota/language/de_DE.h | 2 --
tasmota/language/el_GR.h | 2 --
tasmota/language/en_GB.h | 2 --
tasmota/language/es_ES.h | 2 --
tasmota/language/fr_FR.h | 2 --
tasmota/language/fy_NL.h | 2 --
tasmota/language/he_HE.h | 2 --
tasmota/language/hu_HU.h | 2 --
tasmota/language/it_IT.h | 2 --
tasmota/language/ko_KO.h | 2 --
tasmota/language/nl_NL.h | 2 --
tasmota/language/pl_PL.h | 2 --
tasmota/language/pt_BR.h | 2 --
tasmota/language/pt_PT.h | 2 --
tasmota/language/ro_RO.h | 2 --
tasmota/language/ru_RU.h | 2 --
tasmota/language/sk_SK.h | 2 --
tasmota/language/sv_SE.h | 2 --
tasmota/language/tr_TR.h | 2 --
tasmota/language/uk_UA.h | 2 --
tasmota/language/vi_VN.h | 2 --
tasmota/language/zh_CN.h | 2 --
tasmota/language/zh_TW.h | 2 --
28 files changed, 4 insertions(+), 54 deletions(-)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 84c0a78a6..1c46f3df4 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -753,6 +753,10 @@
// Commands xdrv_60_shift595.ino - 74x595 family shift register driver
#define D_CMND_SHIFT595_DEVICE_COUNT "Shift595DeviceCount"
+// Commands xdrv_89_dali.ino
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// Commands xsns_02_analog.ino
#define D_CMND_ADCPARAM "AdcParam"
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 39dc3126b..53f836a14 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie Vandag"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 21ecbce73..784a15f90 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Консумация за днес"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 01cf177b1..c01ee0d66 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index f1fea69ec..eb3d4d797 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotřeba Dnes"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index df8a827b1..d4ba67d4a 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie heute"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index 0d7500450..a7e79adf7 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index d59a97f01..392abdb0e 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index b75beec9a..62043d5c5 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energía Hoy"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 5f3eac5a3..3a26c486f 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xsns_03_energy.ino
#define D_ENERGY_TODAY "Énergie aujourd'hui"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index a5f22689a..4e2bb00a1 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Konsumpsje hjoed"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 31d969f78..afde4734d 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "צריכה יומית"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index c2204ea65..1d753de1b 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Mai energia"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 5db1e1220..15b933509 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia - oggi"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 7e85879cc..7fd6d1864 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "금일 전력 사용량"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index f2355a709..d0f96fe48 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Verbruik vandaag"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index c523cec6f..a4237e480 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia dzisiaj"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index b87b1a618..ed31fc1f9 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index c050785fa..e1bde2d58 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 77ca813dc..b9db344a1 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia de Azi"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index fd9c3a7ee..5e38b74f9 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Конфигурация DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Энергия Сегодня"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 8b1f107df..2565fd648 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotreba dnes"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index a603635c3..6c85c366f 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energi idag"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index 4c6d46b49..a32bd177a 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 1a6f34161..b786a6700 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Енергія Сьогодні"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index 7416d1dae..c054ed967 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Năng lượng tiêu thụ hôm nay"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 4f93019fc..63d885088 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用电量"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 641f8192c..30db4a4f1 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用電量"
From 06350618b7a312be04fc90578880e9c00ca78577 Mon Sep 17 00:00:00 2001
From: eeak
Date: Sat, 29 Oct 2022 16:12:10 +0300
Subject: [PATCH 28/71] cleanup tasmota_template.h
---
tasmota/include/tasmota_template.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 76977bde0..831115456 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -198,9 +198,7 @@ enum UserSelectablePins {
GPIO_ADE7953_RST, // ADE7953 Reset
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
-#ifdef ESP32
GPIO_DALI_RX, GPIO_DALI_TX, // Dali
-#endif
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -446,9 +444,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ADE7953_RST "|"
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
-#ifdef ESP32
D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
-#endif
;
const char kSensorNamesFixed[] PROGMEM =
From 7fac661b2eda447ccb6176aea61bfe4fe750888e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 29 Oct 2022 16:00:47 +0200
Subject: [PATCH 29/71] Update changelogs
---
CHANGELOG.md | 6 ++++--
RELEASENOTES.md | 4 ++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b4db35d4..1ace4e9ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,14 +5,16 @@ All notable changes to this project will be documented in this file.
## [12.2.0.2]
### Added
+- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
### Breaking Changed
### Changed
-- Prepare for extended calibration and move some persistent data (PowerLow)
-- Tasmota ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
+- Prepare for two phase power calibration and move some persistent data (PowerLow)
+- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
### Fixed
+- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
### Removed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a56da4e9f..3c44ef42c 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -112,17 +112,21 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
+- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
### Breaking Changed
### Changed
+- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
+- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
+
### Removed
From 314dbf5e6b498b6d37ed403bc517a7d1efac1eac Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 29 Oct 2022 19:08:06 +0200
Subject: [PATCH 30/71] Add support for second energy channel calibration
---
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 75 ++++++++++++-------
.../tasmota_xnrg_energy/xnrg_01_hlw8012.ino | 6 +-
.../tasmota_xnrg_energy/xnrg_02_cse7766.ino | 9 ++-
.../tasmota_xnrg_energy/xnrg_04_mcp39f501.ino | 8 +-
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 23 ++++--
.../tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 17 +++--
.../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 16 ++--
.../tasmota_xnrg_energy/xnrg_22_bl6523.ino | 60 +++++++--------
tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino | 11 ++-
9 files changed, 135 insertions(+), 90 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index f6e90ca2b..d0a308a16 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -637,11 +637,6 @@ void EnergyEverySecond(void)
* Commands
\*********************************************************************************************/
-void EnergyCommandCalResponse(uint32_t nvalue) {
- snprintf_P(XdrvMailbox.command, CMDSZ, PSTR("%sCal"), XdrvMailbox.command);
- ResponseCmndNumber(nvalue);
-}
-
void ResponseCmndEnergyTotalYesterdayToday(void) {
char value_chr[TOPSZ]; // Used by EnergyFormatIndex
char value2_chr[TOPSZ];
@@ -835,71 +830,101 @@ void CmndTariff(void) {
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
}
+void EnergyCommandCalSetResponse(uint32_t cal_type) {
+ if (XdrvMailbox.payload > 999) {
+ uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
+ if (channel) {
+ switch (cal_type) {
+ case 0: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
+ case 1: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
+ case 2: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
+ case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ }
+ } else {
+ switch (cal_type) {
+ case 0: Settings->energy_power_calibration = XdrvMailbox.payload; break;
+ case 1: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
+ case 2: Settings->energy_current_calibration = XdrvMailbox.payload; break;
+ case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ }
+ }
+ }
+ if (3 == cal_type) {
+ ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration);
+ } else {
+ uint32_t cal_array[2][3];
+ memcpy(&cal_array, &Settings->energy_power_calibration, 24);
+ if (2 == Energy.phase_count) {
+ ResponseAppend_P(PSTR("[%d,%d]}"), cal_array[0][cal_type], cal_array[1][cal_type]);
+ } else {
+ ResponseAppend_P(PSTR("%d}"), cal_array[0][cal_type]);
+ }
+ }
+}
+
+void EnergyCommandCalResponse(uint32_t cal_type) {
+ Response_P(PSTR("{\"%s\":"), XdrvMailbox.command);
+ EnergyCommandCalSetResponse(cal_type);
+}
+
+void EnergyCommandSetCalResponse(uint32_t cal_type) {
+ Response_P(PSTR("{\"%sCal\":"), XdrvMailbox.command);
+ EnergyCommandCalSetResponse(cal_type);
+}
+
void CmndPowerCal(void) {
Energy.command_code = CMND_POWERCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_power_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_power_calibration);
+ EnergyCommandCalResponse(0);
}
}
void CmndVoltageCal(void) {
Energy.command_code = CMND_VOLTAGECAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_voltage_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_voltage_calibration);
+ EnergyCommandCalResponse(1);
}
}
void CmndCurrentCal(void) {
Energy.command_code = CMND_CURRENTCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_current_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_current_calibration);
+ EnergyCommandCalResponse(2);
}
}
void CmndFrequencyCal(void) {
Energy.command_code = CMND_FREQUENCYCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_frequency_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_frequency_calibration);
+ EnergyCommandCalResponse(3);
}
}
void CmndPowerSet(void) {
Energy.command_code = CMND_POWERSET;
if (XnrgCall(FUNC_COMMAND)) { // Watt
- EnergyCommandCalResponse(Settings->energy_power_calibration);
+ EnergyCommandSetCalResponse(0);
}
}
void CmndVoltageSet(void) {
Energy.command_code = CMND_VOLTAGESET;
if (XnrgCall(FUNC_COMMAND)) { // Volt
- EnergyCommandCalResponse(Settings->energy_voltage_calibration);
+ EnergyCommandSetCalResponse(1);
}
}
void CmndCurrentSet(void) {
Energy.command_code = CMND_CURRENTSET;
if (XnrgCall(FUNC_COMMAND)) { // milliAmpere
- EnergyCommandCalResponse(Settings->energy_current_calibration);
+ EnergyCommandSetCalResponse(2);
}
}
void CmndFrequencySet(void) {
Energy.command_code = CMND_FREQUENCYSET;
if (XnrgCall(FUNC_COMMAND)) { // Hz
- EnergyCommandCalResponse(Settings->energy_frequency_calibration);
+ EnergyCommandSetCalResponse(3);
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
index 883dfdbb2..d28347af5 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
@@ -290,17 +290,17 @@ bool HlwCommand(void) {
}
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Hlw.cf_power_pulse_length ) {
- Settings->energy_power_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio;
+ XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio;
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Hlw.cf1_voltage_pulse_length ) {
- Settings->energy_voltage_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio;
+ XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio;
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Hlw.cf1_current_pulse_length) {
- Settings->energy_current_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio;
+ XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio;
}
}
else serviced = false; // Unknown command
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
index 296bd6520..6717304cf 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
@@ -63,7 +63,8 @@ void CseReceived(void) {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load
// 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W)
- // 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok
+ // 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok, F1 = CF overflow, no problem
+ // 55 5A 02 F1 E8 00 07 9D 00 3F 3E 00 35 F8 50 DB 38 00 B2 A2 F1 D6 97 3E - CF overflow
// 55 5A 02 DB 40 00 03 25 00 3D 18 03 8E CD 4F 0A 60 2A 56 85 61 01 02 1A - OK voltage
// 55 5A 02 DB 40 07 17 1D 00 3D 18 03 8E CD 4F 0A 60 2B EF EA 61 01 02 2C - Wrong voltage
@@ -256,17 +257,17 @@ bool CseCommand(void) {
if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Cse.power_cycle) {
- Settings->energy_power_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF;
+ XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF;
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Cse.voltage_cycle) {
- Settings->energy_voltage_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF;
+ XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF;
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Cse.current_cycle) {
- Settings->energy_current_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000;
+ XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000;
}
}
else serviced = false; // Unknown command
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
index 7601731a4..807176c64 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
@@ -602,7 +602,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_active_power) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 100);
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
- Settings->energy_power_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_POWER;
McpGetCalibration();
}
@@ -612,7 +612,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_voltage_rms) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
if ((value > 1000) && (value < 2600)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_VOLTAGE;
McpGetCalibration();
}
@@ -622,7 +622,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_current_rms) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
if ((value > 100) && (value < 80000)) { // Between 10mA and 8A
- Settings->energy_current_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_CURRENT;
McpGetCalibration();
}
@@ -632,7 +632,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_line_frequency) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 1000);
if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz
- Settings->energy_frequency_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_FREQUENCY;
McpGetFrequency();
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 49686aca8..4cf12061b 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -463,12 +463,16 @@ void Ade7953GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
+ float power_calibration = ((channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration) / 10;
+ float voltage_calibration = (channel) ? Settings->energy_voltage_calibration2 : Settings->energy_voltage_calibration;
+ float current_calibration = ((channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration) * 10;
+
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
if (ADE7953_SHELLY_EM == Ade7953.model) {
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
@@ -478,12 +482,12 @@ void Ade7953GetData(void) {
Energy.reactive_power[channel] *= -1;
}
}
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : current_calibration;
Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider;
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
}
@@ -657,6 +661,9 @@ void Ade7953DrvInit(void) {
Settings->energy_power_calibration = ADE7953_PREF;
Settings->energy_voltage_calibration = ADE7953_UREF;
Settings->energy_current_calibration = ADE7953_IREF;
+ Settings->energy_power_calibration2 = ADE7953_PREF;
+ Settings->energy_voltage_calibration2 = ADE7953_UREF;
+ Settings->energy_current_calibration2 = ADE7953_IREF;
}
Ade7953Defaults();
@@ -705,21 +712,21 @@ bool Ade7953Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
- Settings->energy_power_calibration = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
+ XdrvMailbox.payload = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) {
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
+ XdrvMailbox.payload = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.current_rms[channel]) {
if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A
- Settings->energy_current_calibration = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
+ XdrvMailbox.payload = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
}
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
index f73a276b8..dd44ac14f 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
@@ -193,9 +193,11 @@ void Bl09XXUpdateEnergy() {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature);
#endif
for (uint32_t chan = 0; chan < Energy.phase_count; chan++) {
- if (Bl09XX.power[chan] > Settings->energy_power_calibration) { // We need at least 1W
- Energy.active_power[chan] = (float)Bl09XX.power[chan] / Settings->energy_power_calibration;
- Energy.current[chan] = (float)Bl09XX.current[chan] / Settings->energy_current_calibration;
+ uint32_t power_calibration = (chan) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
+ uint32_t current_calibration = (chan) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
+ if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W
+ Energy.active_power[chan] = (float)Bl09XX.power[chan] / power_calibration;
+ Energy.current[chan] = (float)Bl09XX.current[chan] / current_calibration;
} else {
Energy.active_power[chan] = 0;
Energy.current[chan] = 0;
@@ -289,6 +291,9 @@ void Bl09XXInit(void) {
Settings->energy_voltage_calibration = bl09xx_uref[Bl09XX.model];
Settings->energy_current_calibration = bl09xx_iref[Bl09XX.model];
Settings->energy_power_calibration = bl09xx_pref[Bl09XX.model];
+ Settings->energy_voltage_calibration2 = bl09xx_uref[Bl09XX.model];
+ Settings->energy_current_calibration2 = bl09xx_iref[Bl09XX.model];
+ Settings->energy_power_calibration2 = bl09xx_pref[Bl09XX.model];
}
if ((BL0940_MODEL == Bl09XX.model) && (Settings->energy_current_calibration < (BL0940_IREF / 20))) {
Settings->energy_current_calibration *= 100;
@@ -357,17 +362,17 @@ bool Bl09XXCommand(void) {
if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Bl09XX.power[channel]) {
- Settings->energy_power_calibration = (Bl09XX.power[channel] * 100) / value;
+ XdrvMailbox.payload = (Bl09XX.power[channel] * 100) / value;
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Bl09XX.voltage) {
- Settings->energy_voltage_calibration = (Bl09XX.voltage * 100) / value;
+ XdrvMailbox.payload = (Bl09XX.voltage * 100) / value;
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Bl09XX.current[channel]) {
- Settings->energy_current_calibration = (Bl09XX.current[channel] * 100) / value;
+ XdrvMailbox.payload = (Bl09XX.current[channel] * 100) / value;
}
}
else serviced = false; // Unknown command
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
index ec6647a76..02c13e121 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
@@ -226,6 +226,8 @@ bool Cse7761ChipInit(void) {
Settings->energy_voltage_calibration = Cse7761Ref(RmsUC);
Settings->energy_current_calibration = Cse7761Ref(RmsIAC);
Settings->energy_power_calibration = Cse7761Ref(PowerPAC);
+ Settings->energy_current_calibration2 = Settings->energy_current_calibration;
+ Settings->energy_power_calibration2 = Settings->energy_power_calibration;
}
// Just to fix intermediate users
if (Settings->energy_frequency_calibration < CSE7761_FREF / 2) {
@@ -466,15 +468,17 @@ void Cse7761GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
+ uint32_t power_calibration = (channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
// Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
- Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / Settings->energy_power_calibration; // W
+ Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
+ uint32_t current_calibration = (channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
// Current = RmsIA * RmsIAC / 0x800000
// Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
- Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / Settings->energy_current_calibration; // A
+ Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A
CSE7761Data.energy[channel] += Energy.active_power[channel];
CSE7761Data.energy_update[channel]++;
}
@@ -616,7 +620,7 @@ bool Cse7761Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.active_power[channel]) {
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
- Settings->energy_power_calibration = ((CSE7761Data.active_power[channel]) / value) * 100;
+ XdrvMailbox.payload = ((CSE7761Data.active_power[channel]) / value) * 100;
}
}
}
@@ -627,7 +631,7 @@ bool Cse7761Command(void) {
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.voltage_rms) {
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = (CSE7761Data.voltage_rms * 100) / value;
+ XdrvMailbox.payload = (CSE7761Data.voltage_rms * 100) / value;
}
}
}
@@ -638,7 +642,7 @@ bool Cse7761Command(void) {
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.current_rms[channel]) {
if ((value > 1000) && (value < 1000000)) { // Between 10mA and 10A
- Settings->energy_current_calibration = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000;
+ XdrvMailbox.payload = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000;
}
}
}
@@ -650,7 +654,7 @@ bool Cse7761Command(void) {
else if (CMND_FREQUENCYSET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.frequency) {
if ((value > 4500) && (value < 6500)) { // Between 45.00Hz and 65.00Hz
- Settings->energy_frequency_calibration = (CSE7761Data.frequency * 8 * value) / 100;
+ XdrvMailbox.payload = (CSE7761Data.frequency * 8 * value) / 100;
}
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
index f9714b052..c87fd2a30 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
@@ -22,24 +22,24 @@
/*********************************************************************************************\
* Chinese BL6523 based Watt hour meter
*
- * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
+ * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
* To use Tasmota the user needs to add an ESP8266 or ESP32
* Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
- *
+ *
* Connection Eg (ESP8266) - Non - Isolated:
* BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
* BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
* BL6523 GND -> ESP GND
- *
+ *
* Connection Eg (ESP32) - Non - Isolated:
* BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
* BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
* BL6523 GND -> ESP GND
- *
+ *
* To build add the below to user_config_override.h
* #define USE_ENERGY_SENSOR // Enable Energy sensor framework
* #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
- *
+ *
* After Installation use the below template sample:
* {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
\*********************************************************************************************/
@@ -106,7 +106,7 @@ bool Bl6523ReadData(void)
Bl6523RxSerial->flush(); // Make room for another burst
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
-
+
i=0;
while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
{
@@ -116,15 +116,15 @@ bool Bl6523ReadData(void)
break;
}
}
-
+
uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
Bl6523TxSerial->flush(); // Make room for another burst
-
+
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
-
+
/* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
uint8_t crc = rx_buffer[1]; //Addr
for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
@@ -136,15 +136,15 @@ bool Bl6523ReadData(void)
if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
{
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE));
- Bl6523TxSerial->flush();
- Bl6523RxSerial->flush();
+ Bl6523TxSerial->flush();
+ Bl6523RxSerial->flush();
return false;
}
/* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
WRITE Sample(RX):
RX: CA 3E 55 00 00 6C (WRPROT - allow)
-RX: CA 14 00 00 10 DB (MODE)
+RX: CA 14 00 00 10 DB (MODE)
RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
RX: CA 19 08 00 00 DE (WA_CFDIV )
RX: CA 3E AA 00 00 17 (WRPROT - disable)
@@ -154,8 +154,8 @@ RX: CA 3E AA 00 00 17 (WRPROT - disable)
READ Sample(RX-TX) Data:
RX: 35 05 TX: E4 00 00 16 (IA rms )
RX: 35 07 TX: D5 A3 2E 52 (V rms )
-RX: 35 09 TX: F0 FB 02 09 (FREQ)
-RX: 35 0A TX: 00 00 00 F5 (WATT)
+RX: 35 09 TX: F0 FB 02 09 (FREQ)
+RX: 35 0A TX: 00 00 00 F5 (WATT)
RX: 35 08 TX: 00 00 00 F7 (PF)
RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
*/
@@ -169,7 +169,7 @@ switch(rx_buffer[1]) {
break;
case BL6523_REG_FREQ :
Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_frequency_calibration; // 50.0 Hz
- break;
+ break;
case BL6523_REG_WATTS :
Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_power_calibration; // -196.3 W
break;
@@ -181,7 +181,7 @@ switch(rx_buffer[1]) {
powf_buf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
powf_word = (powf_buf >> 23) ? ~(powf_buf & 0x7fffff) : powf_buf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
- powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
+ powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
powf_word = powf_word & (0x7fffff >> (1+i));
}
powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
@@ -190,8 +190,8 @@ switch(rx_buffer[1]) {
case BL6523_REG_WATTHR :
Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / ( Settings->energy_power_calibration - BL6523_PWHRREF_D ); // 6.216 kWh => used in EnergyUpdateTotal()
break;
- default :
- break;
+ default :
+ break;
}
Energy.data_valid[SINGLE_PHASE] = 0;
EnergyUpdateTotal();
@@ -201,7 +201,7 @@ switch(rx_buffer[1]) {
Bl6523.discovery_triggered = true;
}
return true;
-
+
}
/*********************************************************************************************/
@@ -216,7 +216,7 @@ void Bl6523Update(void)
{
if (Bl6523.valid) {
Bl6523.valid--;
- }
+ }
}
}
@@ -224,7 +224,7 @@ void Bl6523Update(void)
void Bl6523Init(void)
{
-
+
Bl6523.type = 0;
Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
@@ -247,7 +247,7 @@ void Bl6523Init(void)
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" ));
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
-
+
}
bool Bl6523Command(void) {
@@ -262,28 +262,28 @@ bool Bl6523Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 100) && (abs_value < 200000)) { // Between 1.00 and 2000.00 W
- Settings->energy_power_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 10000) && (abs_value < 26000)) { // Between 100.00 and 260.00 V
- Settings->energy_voltage_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 1000) && (abs_value < 1000000)) { // Between 10.00 mA and 10.00000 A
- Settings->energy_current_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_FREQUENCYSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 4500) && (abs_value < 6500)) { // Between 45.00 and 65.00 Hz
- Settings->energy_frequency_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
@@ -323,7 +323,7 @@ void Bl6523DrvInit(void)
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" ));
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
-
+
}
/*********************************************************************************************\
@@ -333,7 +333,7 @@ void Bl6523DrvInit(void)
bool Xnrg22(uint8_t function)
{
bool result = false;
-
+
switch (function)
{
case FUNC_EVERY_250_MSECOND:
@@ -341,7 +341,7 @@ bool Xnrg22(uint8_t function)
break;
case FUNC_COMMAND:
result = Bl6523Command();
- break;
+ break;
case FUNC_INIT:
Bl6523Init();
break;
@@ -349,7 +349,7 @@ bool Xnrg22(uint8_t function)
Bl6523DrvInit();
break;
}
-
+
return result;
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
index 065c909af..b77474a12 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
@@ -84,28 +84,28 @@ bool NrgDummyCommand(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 100) && (abs_value <= 16000000)) { // Between 1.00 and 160000.00 W
- Settings->energy_power_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 10000) && (abs_value <= 40000)) { // Between 100.00 and 400.00 V
- Settings->energy_voltage_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 1000) && (abs_value <= 40000000)) { // Between 10.00 mA and 400.00000 A
- Settings->energy_current_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_FREQUENCYSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 4500) && (abs_value <= 6500)) { // Between 45.00 and 65.00 Hz
- Settings->energy_frequency_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
@@ -134,6 +134,9 @@ void NrgDummyDrvInit(void) {
Settings->energy_voltage_calibration = NRG_DUMMY_UREF;
Settings->energy_current_calibration = NRG_DUMMY_IREF;
Settings->energy_power_calibration = NRG_DUMMY_PREF;
+ Settings->energy_voltage_calibration2 = NRG_DUMMY_UREF;
+ Settings->energy_current_calibration2 = NRG_DUMMY_IREF;
+ Settings->energy_power_calibration2 = NRG_DUMMY_PREF;
}
Energy.phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;
From 1378d573772f7b9976a7b1013b3b1f21e3a5ac9d Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sat, 29 Oct 2022 20:13:00 +0200
Subject: [PATCH 31/71] allow webcam to reuse and share I2C bus 2
---
.../tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
index ba4dbab50..11e57f2c4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
@@ -191,8 +191,9 @@ bool WcPinUsed(void) {
}
if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) ||
!PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) ||
- !PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) {
- pin_used = false;
+ ((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled_2) // preferred option is to reuse and share I2Cbus 2
+ ) {
+ pin_used = false;
}
return pin_used;
}
@@ -341,8 +342,14 @@ uint32_t WcSetup(int32_t fsiz) {
config.pin_pclk = Pin(GPIO_WEBCAM_PCLK); // PCLK_GPIO_NUM;
config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC); // VSYNC_GPIO_NUM;
config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM;
- config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM;
- config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM;
+ config.pin_sccb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM; - unset to use shared I2C bus 2
+ config.pin_sccb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM;
+ if(TasmotaGlobal.i2c_enabled_2){ // configure SIOD and SIOC as SDA,2 and SCL,2
+ config.sccb_i2c_port = 1; // reuse initialized bus 2, can be shared now
+ if(config.pin_sccb_sda < 0){ // GPIO_WEBCAM_SIOD must not be set to really make it happen
+ AddLog(LOG_LEVEL_INFO, PSTR("CAM: use I2C bus 2"));
+ }
+ }
config.pin_pwdn = Pin(GPIO_WEBCAM_PWDN); // PWDN_GPIO_NUM;
config.pin_reset = Pin(GPIO_WEBCAM_RESET); // RESET_GPIO_NUM;
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: Template pin config"));
From 5711fe65a29cd61d35a4ddfdd34b001de95b7565 Mon Sep 17 00:00:00 2001
From: bovirus <1262554+bovirus@users.noreply.github.com>
Date: Sun, 30 Oct 2022 10:17:01 +0100
Subject: [PATCH 32/71] Update italian language
---
tasmota/language/it_IT.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 15b933509..05dc90c7e 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele.
*
- * Updated until v9.4.0.1 - Last update 05.10.2022
+ * Updated until v9.4.0.1 - Last update 30.10.2022
\*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@@ -512,9 +512,9 @@
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizzazione parametri Zigbee, controlla con \"ZbConfig\""
// xdrv_89_dali.ino
-#define D_SENSOR_DALI_RX "Dali RX"
-#define D_SENSOR_DALI_TX "Dali TX"
-#define D_CONFIGURE_DALI "Config DALI"
+#define D_SENSOR_DALI_RX "Dali - RX"
+#define D_SENSOR_DALI_TX "Dali - TX"
+#define D_CONFIGURE_DALI "DALI - Config"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia - oggi"
From cd14c15c41fa6e32cb3c3d298de10b19e3fb6847 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sun, 30 Oct 2022 11:03:05 +0100
Subject: [PATCH 33/71] rm cam_hal.h...
since not needed anymore with core 2.0.5.2
---
lib/default/headers/cam_hal.h | 60 -----------------------------------
1 file changed, 60 deletions(-)
delete mode 100644 lib/default/headers/cam_hal.h
diff --git a/lib/default/headers/cam_hal.h b/lib/default/headers/cam_hal.h
deleted file mode 100644
index c8e38ed47..000000000
--- a/lib/default/headers/cam_hal.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include "esp_camera.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Uninitialize the lcd_cam module
- *
- * @param handle Provide handle pointer to release resources
- *
- * @return
- * - ESP_OK Success
- * - ESP_FAIL Uninitialize fail
- */
-esp_err_t cam_deinit(void);
-
-/**
- * @brief Initialize the lcd_cam module
- *
- * @param config Configurations - see lcd_cam_config_t struct
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- * - ESP_ERR_NO_MEM No memory to initialize lcd_cam
- * - ESP_FAIL Initialize fail
- */
-esp_err_t cam_init(const camera_config_t *config);
-
-esp_err_t cam_config(const camera_config_t *config, framesize_t frame_size, uint16_t sensor_pid);
-
-void cam_stop(void);
-
-void cam_start(void);
-
-camera_fb_t *cam_take(TickType_t timeout);
-
-void cam_give(camera_fb_t *dma_buffer);
-
-#ifdef __cplusplus
-}
-#endif
From 41b65fd6b73b3fbe51857e3522e28a3e61a5603c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 30 Oct 2022 11:15:17 +0100
Subject: [PATCH 34/71] Add support for two phase power calibration
Add support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
---
CHANGELOG.md | 3 +-
RELEASENOTES.md | 1 +
tasmota/tasmota_support/settings.ino | 6 +-
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 61 ++++++++++++-------
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 6 +-
.../tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 4 +-
.../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 4 +-
tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino | 16 +++--
8 files changed, 64 insertions(+), 37 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ace4e9ac..eeeab257e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,11 +6,12 @@ All notable changes to this project will be documented in this file.
## [12.2.0.2]
### Added
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
+- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
### Breaking Changed
### Changed
-- Prepare for two phase power calibration and move some persistent data (PowerLow)
+- Move some persistent data (PowerLow)
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
### Fixed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3c44ef42c..2c6521331 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,6 +109,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.2
### Added
+- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index bf1f9ba63..ecfe30063 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -45,7 +45,7 @@ void RtcSettingsSave(void) {
if (RTC_MEM_VALID != RtcSettings.valid) {
memset(&RtcSettings, 0, sizeof(RtcSettings));
RtcSettings.valid = RTC_MEM_VALID;
-// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2;
+// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
for (uint32_t i = 0; i < 3; i++) {
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
@@ -1535,8 +1535,8 @@ void SettingsDelta(void) {
memset(&Settings->energy_kWhtoday_ph, 0, 36);
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
- Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2;
- Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2;
+ Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
+ Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2; // = ex_energy_kWhyesterday
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
RtcSettings.energy_kWhtotal_ph[0] = RtcSettings.ex_energy_kWhtotal;
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index d0a308a16..57d34ab43 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -41,6 +41,9 @@
#define D_CMND_TARIFF "Tariff"
#define D_CMND_MODULEADDRESS "ModuleAddress"
+enum EnergyCalibration {
+ ENERGY_POWER_CALIBRATION, ENERGY_VOLTAGE_CALIBRATION, ENERGY_CURRENT_CALIBRATION, ENERGY_FREQUENCY_CALIBRATION };
+
enum EnergyCommands {
CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, CMND_FREQUENCYCAL,
CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_ENERGYCONFIG };
@@ -830,34 +833,50 @@ void CmndTariff(void) {
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
}
+uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) {
+ uint32_t channel = ((1 == chan) && (2 == Energy.phase_count)) ? 1 : 0;
+ if (channel) {
+ switch (cal_type) {
+ case ENERGY_POWER_CALIBRATION: return Settings->energy_power_calibration2;
+ case ENERGY_VOLTAGE_CALIBRATION: return Settings->energy_voltage_calibration2;
+ case ENERGY_CURRENT_CALIBRATION: return Settings->energy_current_calibration2;
+ }
+ } else {
+ switch (cal_type) {
+ case ENERGY_POWER_CALIBRATION: return Settings->energy_power_calibration;
+ case ENERGY_VOLTAGE_CALIBRATION: return Settings->energy_voltage_calibration;
+ case ENERGY_CURRENT_CALIBRATION: return Settings->energy_current_calibration;
+ }
+ }
+ return Settings->energy_frequency_calibration;
+}
+
void EnergyCommandCalSetResponse(uint32_t cal_type) {
if (XdrvMailbox.payload > 999) {
uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
if (channel) {
switch (cal_type) {
- case 0: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
- case 1: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
- case 2: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
- case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
+ case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
+ case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
+ case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
}
} else {
switch (cal_type) {
- case 0: Settings->energy_power_calibration = XdrvMailbox.payload; break;
- case 1: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
- case 2: Settings->energy_current_calibration = XdrvMailbox.payload; break;
- case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration = XdrvMailbox.payload; break;
+ case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
+ case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration = XdrvMailbox.payload; break;
+ case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
}
}
}
- if (3 == cal_type) {
+ if (ENERGY_FREQUENCY_CALIBRATION == cal_type) {
ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration);
} else {
- uint32_t cal_array[2][3];
- memcpy(&cal_array, &Settings->energy_power_calibration, 24);
if (2 == Energy.phase_count) {
- ResponseAppend_P(PSTR("[%d,%d]}"), cal_array[0][cal_type], cal_array[1][cal_type]);
+ ResponseAppend_P(PSTR("[%d,%d]}"), EnergyGetCalibration(0, cal_type), EnergyGetCalibration(1, cal_type));
} else {
- ResponseAppend_P(PSTR("%d}"), cal_array[0][cal_type]);
+ ResponseAppend_P(PSTR("%d}"), EnergyGetCalibration(0, cal_type));
}
}
}
@@ -875,56 +894,56 @@ void EnergyCommandSetCalResponse(uint32_t cal_type) {
void CmndPowerCal(void) {
Energy.command_code = CMND_POWERCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(0);
+ EnergyCommandCalResponse(ENERGY_POWER_CALIBRATION);
}
}
void CmndVoltageCal(void) {
Energy.command_code = CMND_VOLTAGECAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(1);
+ EnergyCommandCalResponse(ENERGY_VOLTAGE_CALIBRATION);
}
}
void CmndCurrentCal(void) {
Energy.command_code = CMND_CURRENTCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(2);
+ EnergyCommandCalResponse(ENERGY_CURRENT_CALIBRATION);
}
}
void CmndFrequencyCal(void) {
Energy.command_code = CMND_FREQUENCYCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(3);
+ EnergyCommandCalResponse(ENERGY_FREQUENCY_CALIBRATION);
}
}
void CmndPowerSet(void) {
Energy.command_code = CMND_POWERSET;
if (XnrgCall(FUNC_COMMAND)) { // Watt
- EnergyCommandSetCalResponse(0);
+ EnergyCommandSetCalResponse(ENERGY_POWER_CALIBRATION);
}
}
void CmndVoltageSet(void) {
Energy.command_code = CMND_VOLTAGESET;
if (XnrgCall(FUNC_COMMAND)) { // Volt
- EnergyCommandSetCalResponse(1);
+ EnergyCommandSetCalResponse(ENERGY_VOLTAGE_CALIBRATION);
}
}
void CmndCurrentSet(void) {
Energy.command_code = CMND_CURRENTSET;
if (XnrgCall(FUNC_COMMAND)) { // milliAmpere
- EnergyCommandSetCalResponse(2);
+ EnergyCommandSetCalResponse(ENERGY_CURRENT_CALIBRATION);
}
}
void CmndFrequencySet(void) {
Energy.command_code = CMND_FREQUENCYSET;
if (XnrgCall(FUNC_COMMAND)) { // Hz
- EnergyCommandSetCalResponse(3);
+ EnergyCommandSetCalResponse(ENERGY_FREQUENCY_CALIBRATION);
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 4cf12061b..0bb88e293 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -463,9 +463,9 @@ void Ade7953GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
- float power_calibration = ((channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration) / 10;
- float voltage_calibration = (channel) ? Settings->energy_voltage_calibration2 : Settings->energy_voltage_calibration;
- float current_calibration = ((channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration) * 10;
+ float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 10;
+ float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION);
+ float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) * 10;
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
index dd44ac14f..740029725 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
@@ -193,8 +193,8 @@ void Bl09XXUpdateEnergy() {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature);
#endif
for (uint32_t chan = 0; chan < Energy.phase_count; chan++) {
- uint32_t power_calibration = (chan) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
- uint32_t current_calibration = (chan) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
+ uint32_t power_calibration = EnergyGetCalibration(chan, ENERGY_POWER_CALIBRATION);
+ uint32_t current_calibration = EnergyGetCalibration(chan, ENERGY_CURRENT_CALIBRATION);
if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W
Energy.active_power[chan] = (float)Bl09XX.power[chan] / power_calibration;
Energy.current[chan] = (float)Bl09XX.current[chan] / current_calibration;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
index 02c13e121..5a282bc50 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
@@ -468,14 +468,14 @@ void Cse7761GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
- uint32_t power_calibration = (channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
+ uint32_t power_calibration = EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION);
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
// Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- uint32_t current_calibration = (channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
+ uint32_t current_calibration = EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION);
// Current = RmsIA * RmsIAC / 0x800000
// Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
index b77474a12..021003e3a 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
@@ -55,14 +55,20 @@ struct {
void NrgDummyEverySecond(void) {
if (Energy.power_on) { // Powered on
for (uint32_t channel = 0; channel < Energy.phase_count; channel++) {
- Energy.voltage[channel] = ((float)Settings->energy_voltage_calibration / 100); // V
- Energy.frequency[channel] = ((float)Settings->energy_frequency_calibration / 100); // Hz
- if (bitRead(TasmotaGlobal.power, channel)) { // Emulate power read only if device is powered on
- Energy.active_power[channel] = (NrgDummy.power[channel]) ? ((float)NrgDummy.power[channel] / 1000) : ((float)Settings->energy_power_calibration / 100); // W
+
+ float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 100;
+ float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION) / 100;
+ float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) / 100000;
+ float frequency_calibration = (float)EnergyGetCalibration(channel, ENERGY_FREQUENCY_CALIBRATION) / 100;
+
+ Energy.voltage[channel] = power_calibration; // V
+ Energy.frequency[channel] = frequency_calibration; // Hz
+ if (bitRead(TasmotaGlobal.power, channel)) { // Emulate power read only if device is powered on
+ Energy.active_power[channel] = (NrgDummy.power[channel]) ? ((float)NrgDummy.power[channel] / 1000) : voltage_calibration; // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- Energy.current[channel] = (NrgDummy.current[channel]) ? ((float)NrgDummy.current[channel] / 1000) : ((float)Settings->energy_current_calibration / 100000); // A
+ Energy.current[channel] = (NrgDummy.current[channel]) ? ((float)NrgDummy.current[channel] / 1000) : current_calibration; // A
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
}
Energy.data_valid[channel] = 0;
From 7167eb2f46e83d0ae63cfd105ed6537d871a47c2 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 30 Oct 2022 12:20:56 +0100
Subject: [PATCH 35/71] Changed ADE7953 monitoring
Changed ADE7953 monitoring from instant power to accumulated energy (#16941)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 51 ++++++++++++++-----
4 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eeeab257e..27bc3984c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Move some persistent data (PowerLow)
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
+- ADE7953 monitoring from instant power to accumulated energy (#16941)
### Fixed
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 2c6521331..7a1468d74 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -124,6 +124,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
+- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 57d34ab43..4aaa4e4ee 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -852,7 +852,7 @@ uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) {
}
void EnergyCommandCalSetResponse(uint32_t cal_type) {
- if (XdrvMailbox.payload > 999) {
+ if (XdrvMailbox.payload > 99) {
uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
if (channel) {
switch (cal_type) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 0bb88e293..0cef9b6ab 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -69,6 +69,8 @@
/*********************************************************************************************/
+#define ADE7953_ACCU_ENERGY // Use accumulating energy instead of instant power
+
//#define ADE7953_DUMP_REGS
#define ADE7953_PREF 1540 // 4194304 / (1540 / 1000) = 2723574 (= WGAIN, VAGAIN and VARGAIN)
@@ -201,10 +203,22 @@ const uint16_t Ade7953CalibRegs[2][ADE7953_CALIBREGS] {
const uint8_t ADE7953_REGISTERS = 6;
const uint16_t Ade7953Registers[2][ADE7953_REGISTERS] {
+#ifdef ADE7953_ACCU_ENERGY
+ { ADE7953_IRMSA, ADE7953_AENERGYA, ADE7953_APENERGYA, ADE7953_RENERGYA, ADE7953_VRMS, ADE7943_Period },
+ { ADE7953_IRMSB, ADE7953_AENERGYB, ADE7953_APENERGYB, ADE7953_RENERGYB, ADE7953_VRMS, ADE7943_Period }
+#else // No ADE7953_ACCU_ENERGY
{ ADE7953_IRMSA, ADE7953_AWATT, ADE7953_AVA, ADE7953_AVAR, ADE7953_VRMS, ADE7943_Period },
{ ADE7953_IRMSB, ADE7953_BWATT, ADE7953_BVA, ADE7953_BVAR, ADE7953_VRMS, ADE7943_Period }
+#endif // ADE7953_ACCU_ENERGY
};
+#ifdef ADE7953_ACCU_ENERGY
+const float ADE7953_LSB_PER_WATTSECOND = 2.5;
+const float ADE7953_POWER_CORRECTION = 23.41494; // See https://github.com/arendst/Tasmota/pull/16941
+#else // No ADE7953_ACCU_ENERGY
+const float ADE7953_LSB_PER_WATTSECOND = 44;
+#endif // ADE7953_ACCU_ENERGY
+
struct Ade7953 {
uint32_t voltage_rms[2] = { 0, 0 };
uint32_t current_rms[2] = { 0, 0 };
@@ -272,7 +286,7 @@ void Ade7953Write(uint16_t reg, uint32_t val) {
}
int32_t Ade7953Read(uint16_t reg) {
- uint32_t response = 0;
+ uint32_t response = 0;
int size = Ade7953RegSize(reg);
if (size) {
@@ -304,7 +318,7 @@ int32_t Ade7953Read(uint16_t reg) {
}
#endif // USE_ESP32_SPI
}
- return response;
+ return response;
}
#ifdef ADE7953_DUMP_REGS
@@ -439,6 +453,9 @@ void Ade7953GetData(void) {
acc_mode, reg[0][4], reg[1][4], reg[0][5], reg[1][5],
reg[0][0], reg[1][0], reg[0][1], reg[1][1], reg[0][2], reg[1][2], reg[0][3], reg[1][3]);
+ // If the device is initializing, we read the energy registers to reset them, but don't report the values as the first read may be inaccurate
+ if (Ade7953.init_step) { return; }
+
uint32_t apparent_power[2] = { 0, 0 };
uint32_t reactive_power[2] = { 0, 0 };
@@ -464,15 +481,18 @@ void Ade7953GetData(void) {
Energy.data_valid[channel] = 0;
float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 10;
+#ifdef ADE7953_ACCU_ENERGY
+ power_calibration /= ADE7953_POWER_CORRECTION;
+#endif // ADE7953_ACCU_ENERGY
float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION);
float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) * 10;
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
if (ADE7953_SHELLY_EM == Ade7953.model) {
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
@@ -482,7 +502,7 @@ void Ade7953GetData(void) {
Energy.reactive_power[channel] *= -1;
}
}
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
@@ -497,14 +517,13 @@ void Ade7953GetData(void) {
}
void Ade7953EnergyEverySecond(void) {
- if (Ade7953.init_step) {
- if (1 == Ade7953.init_step) {
- Ade7953Init();
- }
+ if (Ade7953.init_step) {
+ if (2 == Ade7953.init_step) { Ade7953Init(); }
+ if (1 == Ade7953.init_step) { Ade7953GetData(); } // Read registers but do not display yet
Ade7953.init_step--;
- } else {
- Ade7953GetData();
- }
+ } else {
+ Ade7953GetData();
+ }
}
/*********************************************************************************************/
@@ -668,7 +687,7 @@ void Ade7953DrvInit(void) {
Ade7953Defaults();
- Ade7953.init_step = 2;
+ Ade7953.init_step = 3;
// Energy.phase_count = 1;
// Energy.voltage_common = false;
@@ -712,7 +731,13 @@ bool Ade7953Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
+#ifdef ADE7953_ACCU_ENERGY
+ float power_calibration = (float)(Ade7953.active_power[channel] * 1000) / value; // 0.00 W
+ power_calibration *= ADE7953_POWER_CORRECTION;
+ XdrvMailbox.payload = (uint32_t)power_calibration; // 0.00 W
+#else // No ADE7953_ACCU_ENERGY
XdrvMailbox.payload = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
+#endif // ADE7953_ACCU_ENERGY
}
}
}
From f1f8d27079d39832f740f0260f12700c14cde36a Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sun, 30 Oct 2022 20:09:52 +0300
Subject: [PATCH 36/71] Added prefix to all functions
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 54 +++++++++----------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index c5afefa9f..aaad8602a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -1,7 +1,7 @@
/*
xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader on Tasmota
- Copyright (C) 2021 Andre Thomas and Theo Arends
+ Copyright (C) 2021 Andre Thomas, Theo Arends and md5sum-as (https://github.com/md5sum-as)
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
@@ -354,7 +354,7 @@ void PN532_inRelease(void) {
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
}
-uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
+uint8_t PN532_mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
uint8_t i;
uint8_t _key[6];
uint8_t _uid[7];
@@ -391,7 +391,7 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
return 1;
}
-uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
+uint8_t PN532_mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the command */
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
@@ -418,7 +418,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
return 1;
}
-uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
+uint8_t PN532_mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
@@ -435,7 +435,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
-uint8_t ntag21x_probe (void) {
+uint8_t PN532_ntag21x_probe (void) {
uint8_t result=0;
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
@@ -461,7 +461,7 @@ uint8_t ntag21x_probe (void) {
return result; //Return configuration page address
}
-bool ntag21x_auth(void) {
+bool PN532_ntag21x_auth(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH;
@@ -479,7 +479,7 @@ bool ntag21x_auth(void) {
return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0;
}
-bool ntag2xx_read16 (const uint8_t page, char *out) {
+bool PN532_ntag2xx_read16 (const uint8_t page, char *out) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG2XX_CMD_READ;
@@ -497,7 +497,7 @@ bool ntag2xx_read16 (const uint8_t page, char *out) {
return true;
}
-bool ntag2xx_write4(uint8_t page, char *in) {
+bool PN532_ntag2xx_write4(uint8_t page, char *in) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE;
@@ -514,29 +514,29 @@ bool ntag2xx_write4(uint8_t page, char *in) {
return true;
}
-bool ntag2xx_write16(uint8_t page, char *in) {
+bool PN532_ntag2xx_write16(uint8_t page, char *in) {
for (uint8_t i = 0; i < 4; i++) {
- if (!ntag2xx_write4(page +i, &in[i << 2])) {
+ if (!PN532_ntag2xx_write4(page +i, &in[i << 2])) {
return false;
}
}
return true;
}
-bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
+bool PN532_ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
char card_datas[16];
- if (ntag2xx_read16(confPage, card_datas)) {
+ if (PN532_ntag2xx_read16(confPage, card_datas)) {
if (unsetPasswd) {
card_datas[3]=0xFF;
- return ntag2xx_write4(confPage, card_datas);
+ return PN532_ntag2xx_write4(confPage, card_datas);
}
card_datas[3]=0; // Set AUTH0 for protect all pages
card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
- return ntag2xx_write16(confPage, card_datas);
+ return PN532_ntag2xx_write16(confPage, card_datas);
}
return false;
}
@@ -558,50 +558,50 @@ void PN532_ScanForTag(void) {
uint8_t confPage=0;
uint8_t nuid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t nuid_len = 0;
- if ((confPage=ntag21x_probe())>0) {
+ if ((confPage=PN532_ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag2xx_read16(4, card_datas)) {
+ if (!PN532_ntag2xx_read16(4, card_datas)) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (ntag21x_auth()) {
+ if (PN532_ntag21x_auth()) {
str_pwd=PWD_OK;
if (Pn532.function == 3) { /* new password */
- success = ntag21x_set_password(confPage, false);
+ success = PN532_ntag21x_set_password(confPage, false);
}
if (Pn532.function == 4) { /* clear password */
- success = ntag21x_set_password(confPage, true);
+ success = PN532_ntag21x_set_password(confPage, true);
}
} else {
str_pwd=PWD_NOK;
}
- if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
+ if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
} else {
if (Pn532.function == 3) { /* new password */
- success = ntag21x_set_password(confPage, false);
+ success = PN532_ntag21x_set_password(confPage, false);
}
}
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
+ if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
}
if ((Pn532.function == 1) || (Pn532.function == 2)) {
- success = ntag2xx_write16(4, (char *)Pn532.newdata);
- if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
+ success = PN532_ntag2xx_write16(4, (char *)Pn532.newdata);
+ if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
+ if (PN532_mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
if ((Pn532.function == 1) || (Pn532.function == 2)) {
- success=mifareclassic_WriteDataBlock(1, Pn532.newdata);
+ success=PN532_mifareclassic_WriteDataBlock(1, Pn532.newdata);
}
- if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
+ if (PN532_mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
for (uint32_t i = 0; i < 16; i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
From 87b403f10d59e9cda2c7e13d5efc5d7a250deb4f Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sun, 30 Oct 2022 18:40:32 +0100
Subject: [PATCH 37/71] support RISCV ULP for ESP32S2 and ESP32S3
---
.../xdrv_52_3_berry_ulp.ino | 58 +++++++++++++++----
1 file changed, 46 insertions(+), 12 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino
index 4dbc24b3c..9d154a8da 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino
@@ -1,5 +1,5 @@
/*
- xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32
+ xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32, ESP32S2, ESP32S3
Copyright (C) 2021 Stephan Hadinger & Christian Baars, Berry language by Guan Wenliang https://github.com/Skiars/berry
@@ -21,9 +21,21 @@
#ifdef USE_BERRY_ULP
#include
-#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
+#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
+#if defined(CONFIG_IDF_TARGET_ESP32)
#include "esp32/ulp.h"
+#endif // esp32
+#if defined(CONFIG_IDF_TARGET_ESP32S2)
+#include "esp32s2/ulp.h"
+#include "esp32s2/ulp_riscv.h"
+#include "esp32s2/ulp_riscv_adc.h"
+#endif // s2
+#if defined(CONFIG_IDF_TARGET_ESP32S3)
+#include "esp32s3/ulp.h"
+#include "esp32s3/ulp_riscv.h"
+#include "esp32s3/ulp_riscv_adc.h"
+#endif //s3
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
@@ -36,7 +48,11 @@ extern "C" {
//
// `ULP.run() -> nil`
void be_ULP_run(int32_t entry) {
+#if defined(CONFIG_IDF_TARGET_ESP32)
ulp_run(entry); // entry point should be at the beginning of program
+#else // S2 or S3
+ ulp_riscv_run();
+#endif
}
// `ULP.wake_period(period_index:int, period_us:int) -> nil`
@@ -52,7 +68,11 @@ extern "C" {
// `ULP.get_mem(position:int) -> int`
int32_t be_ULP_get_mem(int32_t pos) {
- return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
+#else
+ return RTC_SLOW_MEM[pos]; // full 32bit for RISCV ULP
+#endif
}
// `ULP.gpio_init(pin:int, mode:int) -> rtc_pin:int`
@@ -70,25 +90,40 @@ extern "C" {
// `ULP.adc_config(channel:int, attenuation:int, width:int) -> nil`
//
// enums: channel 0-7, attenuation 0-3, width 0-3
- void be_ULP_adc_config(struct bvm *vm, adc1_channel_t channel, adc_atten_t attenuation, adc_bits_width_t width) {
- esp_err_t err = adc1_config_channel_atten(channel, attenuation);
- err += adc1_config_width(width);
+ void be_ULP_adc_config(struct bvm *vm, int32_t channel, int32_t attenuation, int32_t width) {
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ esp_err_t err = adc1_config_channel_atten((adc1_channel_t)channel, (adc_atten_t)attenuation);
+ err += adc1_config_width((adc_bits_width_t)width);
if (err != ESP_OK) {
be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
} else {
adc1_ulp_enable();
}
+#else // S2 or S3
+ ulp_riscv_adc_cfg_t cfg = {
+ .channel = (adc_channel_t)channel,
+ .atten = (adc_atten_t)attenuation,
+ .width = (adc_bits_width_t)width
+ };
+ esp_err_t err = ulp_riscv_adc_init(&cfg);
+ if (err != ESP_OK) {
+ be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
+ }
+#endif
}
/**
* @brief Load a Berry byte buffer containing a ULP program as raw byte data
*
* @param vm as `ULP.load(code:bytes) -> nil`
- * @return void
+ * @return void for ESP32 or binary type as int32_t on RISCV capable SOC's
*/
void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size) {
- // AddLog(LOG_LEVEL_INFO, "ULP: load addr=%p size=%i %*_H", buf, size/4, size, buf);
- esp_err_t err = ulp_load_binary(0, buf, size / 4);
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ esp_err_t err = ulp_load_binary(0, buf, size / 4); // FSM type only, specific header, size in long words
+#else // S2 or S3
+ esp_err_t err = ulp_riscv_load_binary(buf, size); // there are no header bytes, just load and hope for a valid binary - size in bytes
+#endif // defined(CONFIG_IDF_TARGET_ESP32)
if (err != ESP_OK) {
be_raisef(vm, "ulp_load_error", "ULP: invalid code err=%i", err);
}
@@ -109,10 +144,9 @@ extern "C" {
esp_deep_sleep_start();
}
-
} //extern "C"
-#endif //CONFIG_IDF_TARGET_ESP32
+#endif //CONFIG_IDF_TARGET_ESP32 .. S2 .. S3
#endif // USE_BERRY_ULP
-#endif // USE_BERRY
\ No newline at end of file
+#endif // USE_BERRY
From ed6c21ad806f9cdb43e25d719b75906402b9feaa Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sun, 30 Oct 2022 18:42:47 +0100
Subject: [PATCH 38/71] allow ULP not only for ESP32
---
lib/libesp32/berry/default/be_modtab.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index c02e2ca6d..c4a2147d1 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -166,7 +166,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_ALEXA_AVS
&be_native_module(crypto),
#endif
-#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
+#if defined(USE_BERRY_ULP)
&be_native_module(ULP),
#endif // USE_BERRY_ULP
#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
From 0b063f62dfa505f67dfb12ca68cc1ac409710803 Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sun, 30 Oct 2022 18:43:37 +0100
Subject: [PATCH 39/71] allow ULP on ESP32, S2 and S3
---
lib/libesp32/berry_tasmota/src/be_ULP_lib.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/lib/libesp32/berry_tasmota/src/be_ULP_lib.c b/lib/libesp32/berry_tasmota/src/be_ULP_lib.c
index 7edf43206..a5fe0e417 100644
--- a/lib/libesp32/berry_tasmota/src/be_ULP_lib.c
+++ b/lib/libesp32/berry_tasmota/src/be_ULP_lib.c
@@ -6,9 +6,9 @@
#include "be_constobj.h"
#include "be_mapping.h"
-#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
+#if defined(USE_BERRY_ULP) && (defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
-#include "esp32/ulp.h"
+// #include "esp32/ulp.h"
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
@@ -37,8 +37,6 @@ BE_FUNC_CTYPE_DECLARE(be_ULP_sleep, "", "[i]"); // optional int arg
extern void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size);
BE_FUNC_CTYPE_DECLARE(be_ULP_load, "", "@(bytes)~"); // pass: 1/ vm, 2/ bytes point, 3/ bytes size
-#include "be_fixed_ULP.h"
-
/* @const_object_info_begin
module ULP (scope: global) {
run, ctype_func(be_ULP_run)
@@ -51,5 +49,6 @@ module ULP (scope: global) {
adc_config, ctype_func(be_ULP_adc_config)
}
@const_object_info_end */
+#include "be_fixed_ULP.h"
-#endif // USE_BERRY_ULP
\ No newline at end of file
+#endif // USE_BERRY_ULP
From 79536d8714c7be457e1a5b4fd3d8cf2a3d663f9f Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 10:59:49 +0100
Subject: [PATCH 40/71] Update changelog
---
CHANGELOG.md | 2 ++
RELEASENOTES.md | 2 ++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27bc3984c..6f93336f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
+- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
### Breaking Changed
@@ -19,6 +20,7 @@ All notable changes to this project will be documented in this file.
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
### Removed
+- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
## [12.2.0.1] 20221026
### Added
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 7a1468d74..3177f027d 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -114,6 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
+- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
@@ -132,3 +133,4 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Removed
+- Define ``USE_PN532_DATA_RAW`` from NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
From c351c62baf015d6c05987efffe7176da7db56c5b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 11:25:00 +0100
Subject: [PATCH 41/71] Fix possible serial watchdogs
---
lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
index 99dc6caeb..f750b956f 100644
--- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
+++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
@@ -95,7 +95,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
void TasmotaSerial::end(bool turnOffDebug) {
#ifdef ESP8266
if (m_hardserial) {
- Serial.end();
+// Serial.end(); // Keep active for logging
} else {
if (m_rx_pin > -1) {
detachInterrupt(m_rx_pin);
From 817819e603b3cf066b4263a03db52143727ee479 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 13:38:26 +0100
Subject: [PATCH 42/71] Add PN532 persistent slots (#16939)
---
tasmota/include/tasmota_types.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index 0fa7d6f69..7f952b8f5 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -574,8 +574,7 @@ typedef struct {
SOBitfield3 flag3; // 3A0
uint16_t energy_kWhdoy; // 3A4
uint16_t energy_min_power; // 3A6
-
- uint8_t free_3A8[4]; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
+ uint32_t pn532_password; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
#ifdef CONFIG_IDF_TARGET_ESP32S3
// ------------------------------------
@@ -688,15 +687,15 @@ typedef struct {
uint16_t mqtt_socket_timeout; // 52E
uint8_t mqtt_wifi_timeout; // 530
uint8_t ina219_mode; // 531
- uint16_t ex_pulse_timer[8]; // 532 Free since 11.0.0.3
+
+ uint16_t ex_pulse_timer[8]; // 532 ex_pulse_timer free since 11.0.0.3
+
uint16_t button_debounce; // 542
uint32_t ipv4_address[5]; // 544
uint32_t ipv4_rgx_address; // 558
uint32_t ipv4_rgx_subnetmask; // 55C
uint16_t pwm_value_ext[16-5]; // 560 Extension to pwm_value to store up to 16 PWM for ESP32. This array stores values 5..15
-
- uint8_t free_576[2]; // 576
-
+ uint16_t pn532_pack; // 576
int32_t weight_offset; // 578
uint16_t pulse_timer[MAX_PULSETIMERS]; // 57C
SysMBitfield1 flag2; // 5BC
@@ -842,7 +841,9 @@ typedef struct {
uint16_t flowratemeter_calibration[2];// F78
int32_t energy_kWhexport_ph[3]; // F7C
uint32_t eth_ipv4_address[5]; // F88
+
uint32_t ex_energy_kWhtotal; // F9C
+
SBitfield1 sbflag1; // FA0
TeleinfoCfg teleinfo; // FA4
uint64_t rf_protocol_mask; // FA8
From 9db8a2340143ce597bff1cb37d631b5ec9429c33 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 14:01:15 +0100
Subject: [PATCH 43/71] Fix Shelly Pro detection when using buttons (#16733)
---
tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 60f0f0a88..096f46e60 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -64,9 +64,9 @@ void ShellyProPreInit(void) {
PinUsed(GPIO_SPI_CS) &&
TasmotaGlobal.gpio_optiona.shelly_pro) { // Option_A7
- if (PinUsed(GPIO_SWT1)) {
+ if (PinUsed(GPIO_SWT1) || PinUsed(GPIO_KEY1)) {
TasmotaGlobal.devices_present++; // Shelly Pro 1
- if (PinUsed(GPIO_SWT1, 1)) {
+ if (PinUsed(GPIO_SWT1, 1) || PinUsed(GPIO_KEY1, 1)) {
TasmotaGlobal.devices_present++; // Shelly Pro 2
}
From e9d99a088be44e9258c0c771dc9a3a3d83fc7f78 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 15:02:29 +0100
Subject: [PATCH 44/71] Fix hardware watchdog at power on
---
tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 4aaa4e4ee..cef329705 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -415,8 +415,8 @@ bool EnergyMargin(bool type, uint16_t margin, uint16_t value, bool &flag, bool &
return (change != save_flag);
}
-void EnergyMarginCheck(void)
-{
+void EnergyMarginCheck(void) {
+ if (!Energy.phase_count || (TasmotaGlobal.uptime < 8)) { return; }
if (Energy.power_steady_counter) {
Energy.power_steady_counter--;
return;
@@ -1094,9 +1094,6 @@ void EnergyDrvInit(void) {
Energy.voltage_available = true; // Enable if voltage is measured
Energy.current_available = true; // Enable if current is measured
Energy.power_on = true;
-#ifdef USE_ENERGY_MARGIN_DETECTION
- Energy.power_steady_counter = 8; // Allow for power on stabilization
-#endif // USE_ENERGY_MARGIN_DETECTION
TasmotaGlobal.energy_driver = ENERGY_NONE;
XnrgCall(FUNC_PRE_INIT); // Find first energy driver
From ad484ad194a1c4316d5e7f00e26eb8adf8c2ad94 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Mon, 31 Oct 2022 18:37:46 +0300
Subject: [PATCH 45/71] Saving the PN532 password and PACK in Settings
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index aaad8602a..68eb3c8c6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -85,8 +85,8 @@ struct PN532 {
#ifdef USE_PN532_DATA_FUNCTION
uint8_t newdata[16];
uint8_t function = 0;
- uint32_t pwd_auth=0x64636261;
- uint16_t pwd_pack=0x6665;
+ uint32_t pwd_auth;
+ uint16_t pwd_pack;
uint32_t pwd_auth_new;
uint16_t pwd_pack_new;
#endif // USE_PN532_DATA_FUNCTION
@@ -106,6 +106,8 @@ void PN532_Init(void) {
PN532_SAMConfig();
AddLog(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
Pn532.present = true;
+ Pn532.pwd_auth=Settings->pn532_password;
+ Pn532.pwd_pack=Settings->pn532_pack;
}
}
}
@@ -708,6 +710,9 @@ bool PN532_Command(void) {
if (ArgC() > 2) {
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
}
+ Settings->pn532_password=Pn532.pwd_auth;
+ Settings->pn532_pack=Pn532.pwd_pack;
+
serviced = true;
}
if (!strcmp_P(argument,PSTR("SET_PWD"))) {
From a3391ddc2b26fa5179fd7b2d0a528d119806e71f Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Mon, 31 Oct 2022 19:07:03 +0300
Subject: [PATCH 46/71] Fixed a compilation error: added conditional
compilation
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 68eb3c8c6..4c39f4342 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -106,8 +106,10 @@ void PN532_Init(void) {
PN532_SAMConfig();
AddLog(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
Pn532.present = true;
+#ifdef USE_PN532_DATA_FUNCTION
Pn532.pwd_auth=Settings->pn532_password;
Pn532.pwd_pack=Settings->pn532_pack;
+#endif
}
}
}
From 1011ee2cbb0a0dd1e7a1be48332c74e8218f1694 Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Tue, 1 Nov 2022 15:55:01 +0100
Subject: [PATCH 47/71] ignore USE_BERRY_ULP on unsupported platforms
---
lib/libesp32/berry/default/be_modtab.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index c4a2147d1..1cc28efee 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -166,7 +166,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_ALEXA_AVS
&be_native_module(crypto),
#endif
-#if defined(USE_BERRY_ULP)
+#if defined(USE_BERRY_ULP) && ((CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
&be_native_module(ULP),
#endif // USE_BERRY_ULP
#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
From da65c8798bb192465f4fabd8a95e4c4c6b54f87b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 1 Nov 2022 17:19:42 +0100
Subject: [PATCH 48/71] Shelly Pro better light show
---
.../xdrv_88_esp32_shelly_pro.ino | 30 +++++++++++--------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 096f46e60..a822b04c9 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -49,13 +49,15 @@ void ShellyProUpdate(void) {
// bit 3 = wifi led green
// bit 4 = wifi led red
// bit 5 - 7 = nc
- uint32_t val = SPro.power | SPro.ledlink;
+ // OE is connected to Gnd with 470 ohm resistor R62 AND a capacitor C81 to 3V3
+ // - this inhibits output of signals (also relay state) during power on for a few seconds
+ uint8_t val = SPro.power | SPro.ledlink;
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
SPI.transfer(val); // Write 74HC595 shift register
SPI.endTransaction();
- delayMicroseconds(2); // Wait for SPI clock to stop
+// delayMicroseconds(2); // Wait for SPI clock to stop
digitalWrite(SPro.pin_shift595_rclk, 1); // Latch data
- delayMicroseconds(2); // Shelly 10mS
+ delayMicroseconds(1); // Shelly 10mS
digitalWrite(SPro.pin_shift595_rclk, 0);
}
@@ -76,21 +78,18 @@ void ShellyProPreInit(void) {
// Does nothing if SPI is already initiated (by ADE7953) so no harm done
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
- SPro.power = TasmotaGlobal.power &3; // Restore power
- SPro.ledlink = 0x18; // Blue led on
- ShellyProUpdate();
-
+ SPro.ledlink = 0x18; // Blue led on - set by first call ShellyProPower()
SPro.detected = true;
}
}
}
void ShellyProInit(void) {
- int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
-// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
+ int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
+// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
digitalWrite(pin_lan_reset, 0);
pinMode(pin_lan_reset, OUTPUT);
- delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
+ delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
digitalWrite(pin_lan_reset, 1);
AddLog(LOG_LEVEL_INFO, PSTR("HDW: Shelly Pro %d%s initialized"),
@@ -123,9 +122,14 @@ void ShellyProLedLink(void) {
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
*/
SPro.last_update = TasmotaGlobal.uptime;
- uint32_t ledlink = 0x1C; // All leds off
- if (XdrvMailbox.index) { ledlink &= 0xFB; } // Blue blinks if wifi/mqtt lost
- if (!TasmotaGlobal.global_state.wifi_down) { ledlink &= 0xF7; } // Green On
+ uint32_t ledlink = 0x1C; // All leds off
+ if (XdrvMailbox.index) {
+ ledlink &= 0xFB; // Blue blinks if wifi/mqtt lost
+ }
+ else if (!TasmotaGlobal.global_state.wifi_down) {
+ ledlink &= 0xF7; // Green On
+ }
+
ShellyProUpdateLedLink(ledlink);
}
From 4c896cd8bc7c46c1c851dcb520bd60a375bf2873 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 1 Nov 2022 23:07:15 +0100
Subject: [PATCH 49/71] Added Berry ``bytes().reverse()`` method
---
CHANGELOG.md | 1 +
lib/libesp32/berry/src/be_byteslib.c | 69 ++++++++++++++++++++++++++--
lib/libesp32/berry/tests/bytes.be | 23 ++++++++++
3 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f93336f0..2e4175b87 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
+- Added Berry ``bytes().reverse()`` method
### Breaking Changed
diff --git a/lib/libesp32/berry/src/be_byteslib.c b/lib/libesp32/berry/src/be_byteslib.c
index b2dc9856a..6fcd457db 100644
--- a/lib/libesp32/berry/src/be_byteslib.c
+++ b/lib/libesp32/berry/src/be_byteslib.c
@@ -957,7 +957,6 @@ static int m_setfloat(bvm *vm)
* `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
*
*/
-#include
static int m_setbytes(bvm *vm)
{
int argc = be_top(vm);
@@ -968,7 +967,7 @@ static int m_setbytes(bvm *vm)
size_t from_len_total;
const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
if (idx < 0) { idx = 0; }
- if ((size_t)idx >= attr.len) { idx = attr.len; }
+ if (idx >= attr.len) { idx = attr.len; }
int32_t from_byte = 0;
if (argc >= 4 && be_isint(vm, 4)) {
@@ -981,9 +980,9 @@ static int m_setbytes(bvm *vm)
if (argc >= 5 && be_isint(vm, 5)) {
from_len = be_toint(vm, 5);
if (from_len < 0) { from_len = 0; }
- if (from_len >= from_len_total) { from_len = from_len_total; }
+ if (from_len >= (int32_t)from_len_total) { from_len = from_len_total; }
}
- if ((size_t) idx + (size_t)from_len >= attr.len) { from_len = attr.len - idx; }
+ if (idx + from_len >= attr.len) { from_len = attr.len - idx; }
// all parameters ok
if (from_len > 0) {
@@ -993,6 +992,66 @@ static int m_setbytes(bvm *vm)
be_return_nil(vm);
}
+
+/*
+ * Reverses in-place a sub-buffer composed of groups of n-bytes packets
+ *
+ * This is useful for pixel manipulation when displaying RGB pixels
+ *
+ * `reverse([index:int, len:int, grouplen:int]) -> self`
+ *
+ */
+static int m_reverse(bvm *vm)
+{
+ int argc = be_top(vm);
+ buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
+ check_ptr(vm, &attr);
+
+ int32_t idx = 0; /* start from index 0 */
+ int32_t len = attr.len; /* entire len */
+ int32_t grouplen = 1; /* default to 1-byte group */
+
+ if (argc >= 2 && be_isint(vm, 2)) {
+ idx = be_toint(vm, 2);
+ if (idx < 0) { idx = 0; } /* railguards */
+ if (idx > attr.len) { idx = attr.len; }
+ }
+ if (argc >= 3 && be_isint(vm, 3)) {
+ len = be_toint(vm, 3);
+ if (len < 0) { len = attr.len - idx; } /* negative len means */
+ }
+ if (idx + len >= attr.len) { len = attr.len - idx; }
+
+ // truncate len to multiple of grouplen
+ if (argc >= 4 && be_isint(vm, 4)) {
+ grouplen = be_toint(vm, 4);
+ if (grouplen <= 0) { grouplen = 1; }
+ }
+ len = len - (len % grouplen);
+
+ // apply reverse
+ if (len > 0) {
+ if (grouplen == 1) {
+ /* fast version if simple byte inversion */
+ for (int32_t i = idx, j = idx + len -1; i < j; i++, j--) {
+ uint8_t temp = attr.bufptr[i];
+ attr.bufptr[i] = attr.bufptr[j];
+ attr.bufptr[j] = temp;
+ }
+ } else {
+ for (int32_t i = idx, j = idx + len - grouplen; i < j; i += grouplen, j -= grouplen) {
+ for (int32_t k = 0; k < grouplen; k++) {
+ uint8_t temp = attr.bufptr[i+k];
+ attr.bufptr[i+k] = attr.bufptr[j+k];
+ attr.bufptr[j+k] = temp;
+ }
+ }
+ }
+ }
+ be_pushvalue(vm, 1); /* push bytes object */
+ be_return(vm);
+}
+
static int m_setitem(bvm *vm)
{
int argc = be_top(vm);
@@ -1627,6 +1686,7 @@ void be_load_byteslib(bvm *vm)
{ "size", m_size },
{ "resize", m_resize },
{ "clear", m_clear },
+ { "reverse", m_reverse },
{ "copy", m_copy },
{ "+", m_merge },
{ "..", m_connect },
@@ -1672,6 +1732,7 @@ class be_class_bytes (scope: global, name: bytes) {
size, func(m_size)
resize, func(m_resize)
clear, func(m_clear)
+ reverse, func(m_reverse)
copy, func(m_copy)
+, func(m_merge)
.., func(m_connect)
diff --git a/lib/libesp32/berry/tests/bytes.be b/lib/libesp32/berry/tests/bytes.be
index 44d3f56aa..d2b2c1573 100644
--- a/lib/libesp32/berry/tests/bytes.be
+++ b/lib/libesp32/berry/tests/bytes.be
@@ -225,3 +225,26 @@ assert(a == bytes('112233445566CCDD99'))
a = b.copy()
a.setbytes(0, a0)
assert(a == bytes('112233445566'))
+
+# reverse
+assert(bytes().reverse() == bytes())
+assert(bytes("AA").reverse() == bytes("AA"))
+assert(bytes("1122334455").reverse() == bytes("5544332211"))
+assert(bytes("11223344").reverse() == bytes("44332211"))
+
+assert(bytes("0011223344").reverse(1) == bytes("0044332211"))
+assert(bytes("0011223344").reverse(3) == bytes("0011224433"))
+assert(bytes("0011223344").reverse(4) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(5) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(15) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(-2) == bytes("4433221100"))
+
+assert(bytes("0011223344").reverse(1,3) == bytes("0033221144"))
+assert(bytes("0011223344").reverse(1,0) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(2,2) == bytes("0011332244"))
+assert(bytes("0011223344").reverse(0,2) == bytes("1100223344"))
+assert(bytes("0011223344").reverse(nil,2) == bytes("1100223344"))
+assert(bytes("0011223344").reverse(1, nil) == bytes("0044332211"))
+
+assert(bytes("0011223344").reverse(nil, nil, 2) == bytes("2233001144"))
+assert(bytes("001122334455").reverse(nil, nil, 3) == bytes("334455001122"))
From 0632377192d63d4b9678391e0b6a9be87fa69af9 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 2 Nov 2022 11:24:24 +0100
Subject: [PATCH 50/71] Fix serial initialization
Fix serial initialization for baudrate and config (#16970)
---
CHANGELOG.md | 3 ++-
RELEASENOTES.md | 4 +++-
tasmota/tasmota.ino | 2 +-
tasmota/tasmota_support/support.ino | 7 +++++++
4 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e4175b87..cd5d59493 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
-- Added Berry ``bytes().reverse()`` method
+- Berry ``bytes().reverse()`` method (#16977)
### Breaking Changed
@@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
### Fixed
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
+- Serial initialization for baudrate and config (#16970)
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3177f027d..ab0e97a8a 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -115,7 +115,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
-- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
+- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
+- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
### Breaking Changed
@@ -130,6 +131,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
+- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
### Removed
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 707f95771..c0652c563 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -516,7 +516,7 @@ void setup(void) {
Settings->baudrate = APP_BAUDRATE / 300;
Settings->serial_config = TS_SERIAL_8N1;
}
- SetSerialBaudrate(Settings->baudrate * 300); // Reset serial interface if current baudrate is different from requested baudrate
+ SetSerialInitBegin(); // Reset serial interface if current baudrate and/or config is different from requested settings
if (1 == RtcReboot.fast_reboot_count) { // Allow setting override only when all is well
UpdateQuickPowerCycle(true);
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index 3dbebd6e0..f082a2206 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -1977,6 +1977,13 @@ void SetSerialBegin(void) {
#endif // ESP32
}
+void SetSerialInitBegin(void) {
+ TasmotaGlobal.baudrate = Settings->baudrate * 300;
+ if ((GetSerialBaudrate() != TasmotaGlobal.baudrate) || (TS_SERIAL_8N1 != Settings->serial_config)) {
+ SetSerialBegin();
+ }
+}
+
void SetSerialConfig(uint32_t serial_config) {
if (serial_config > TS_SERIAL_8O2) {
serial_config = TS_SERIAL_8N1;
From b2e9001ca29f6f9b68d74debea15c6d086ca79db Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 2 Nov 2022 22:37:53 +0100
Subject: [PATCH 51/71] Support for DMX ArtNet Led matrix animations
---
CHANGELOG.md | 1 +
tasmota/berry/artnet/artnet.be | 89 +++++++++++++++++++
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 11 ++-
3 files changed, 98 insertions(+), 3 deletions(-)
create mode 100644 tasmota/berry/artnet/artnet.be
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd5d59493..4ac716257 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 two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
- Berry ``bytes().reverse()`` method (#16977)
+- Support for DMX ArtNet Led matrix animations
### Breaking Changed
diff --git a/tasmota/berry/artnet/artnet.be b/tasmota/berry/artnet/artnet.be
new file mode 100644
index 000000000..001987736
--- /dev/null
+++ b/tasmota/berry/artnet/artnet.be
@@ -0,0 +1,89 @@
+# Art-Net driver
+
+class ArtNet
+ var matrix # the led matrix
+ var port # port number for listening for incoming packets
+ var udp_server # instance of `udp` class
+ var universe_start # base universe number
+ var universe_end # last universe number allowed (excluded)
+ static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
+
+ var packet # try reusing the same packer bytes() object for performance
+
+ # local copy of led matrix attributes for faster access
+ var alternate # field from matrix, alternate lines (reversed). Contains 0 if not alternate, or the number of bytes per pixel
+
+ def init(matrix, universe_start, port, ip_addr)
+ self.matrix = matrix
+ self.alternate = matrix.alternate ? matrix.pixel_size() : 0
+ # self.v = self.matrix.v
+ if universe_start == nil universe_start = 0 end
+ self.universe_start = universe_start
+ self.universe_end = universe_start + matrix.h
+
+ if port == nil port = 6454 end
+ # self.artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes
+ self.port = int(port)
+ if ip_addr == nil ip_addr = "" end
+
+ self.udp_server = udp()
+ self.udp_server.begin(ip_addr, self.port)
+
+ # register as fast_loop
+ tasmota.add_fast_loop(/-> self.fast_loop())
+ # set sleep to 5 for a smooth animation
+ tasmota.global.sleep = 5
+ end
+
+ def fast_loop()
+ var universe_start = self.universe_start
+ var universe_end = self.universe_end
+ var dirty = false
+ var packet = self.udp_server.read(self.packet)
+ while (packet != nil)
+ if size(packet) >= 18 && packet[0..7] == self.artnet_sig # check that we have a packet containing the 8 bytes header
+ var opcode = packet.get(8, 2) # should be 0x5000
+ var protocol = packet.get(10, -2) # big endian, should be 14
+ var universe = packet.get(14, 2)
+
+ if opcode == 0x5000 && protocol == 14 && universe >= universe_start && universe < universe_end
+ # tasmota.log("DMX: received Art-Net packet :" + packet.tohex())
+ # var seq = packet.get(12, 1)
+ # var phy = packet.get(13, 1)
+ var data_len = packet.get(16, -2)
+ # data starts at offset 18
+ if size(packet) >= 18 + data_len # check size
+ if self.alternate > 0 && (universe - self.universe_start) % 2
+ packet.reverse(18, self.alternate, -1)
+ end
+ self.matrix.set_bytes(universe, packet, 18, data_len)
+ dirty = true
+ end
+ # import string
+ # tasmota.log(string.format("DMX: opcode=0x%04X protocol=%i seq=%i phy=%i universe=%i data_len=%i data=%s",
+ # opcode, protocol, seq, phy, universe, data_len, packet[18..-1].tohex()))
+ end
+ end
+ packet = self.udp_server.read(packet)
+ if packet == nil
+ tasmota.delay_microseconds(20) # wait 20 us just in case
+ packet = self.udp_server.read(packet)
+ end
+ end
+ self.packet = packet # save bytes() object for next iteration and avoid allocation of new object
+
+ if dirty
+ self.matrix.dirty()
+ self.matrix.show()
+ end
+ end
+end
+
+return ArtNet
+
+#-
+# Example for M5Stack ATOM Matrix (5x5 matrix without alternate)
+var strip = Leds(25, gpio.pin(gpio.WS2812, 0))
+var m = strip.create_matrix(5, 5, 0)
+var dmx = ArtNet(m)
+-#
\ No newline at end of file
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index 27acc5ae7..538da6b09 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -1763,6 +1763,7 @@ void LightReapplyColor(void) {
void LightAnimate(void)
{
bool power_off = false;
+ static int32_t sleep_previous = -1; // previous value of sleep before changing it to PWM_MAX_SLEEP, -1 means unchanged
// make sure we update CT range in case SetOption82 was changed
Light.strip_timer_counter++;
@@ -1770,13 +1771,17 @@ void LightAnimate(void)
// set sleep parameter: either settings,
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
if (Light.power || Light.fade_running) {
- if (Settings->sleep > PWM_MAX_SLEEP) {
+ if (TasmotaGlobal.sleep > PWM_MAX_SLEEP) {
+ sleep_previous = TasmotaGlobal.sleep; // save previous value of sleep
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maximum value (in milliseconds) to sleep to ensure that animations are smooth
} else {
- TasmotaGlobal.sleep = Settings->sleep; // or keep the current sleep if it's low enough
+ sleep_previous = -1; // if low enough, don't change it
}
} else {
- TasmotaGlobal.sleep = Settings->sleep;
+ if (sleep_previous > 0) {
+ TasmotaGlobal.sleep = sleep_previous;
+ sleep_previous = -1; // rearm
+ }
}
if (!Light.power) { // All channels powered off
From f3b6cd1d7391d60498ebd5a84e000591ae37aa29 Mon Sep 17 00:00:00 2001
From: Dmytro Shestakov
Date: Wed, 2 Nov 2022 18:38:53 +0200
Subject: [PATCH 52/71] Add TM1637 driver written in Berry
It allows to use this type of display in addition to any standard
Tasmota display simultaneously
---
tasmota/berry/drivers/tm1637.be | 190 ++++++++++++++++++++++++++++++++
1 file changed, 190 insertions(+)
create mode 100644 tasmota/berry/drivers/tm1637.be
diff --git a/tasmota/berry/drivers/tm1637.be b/tasmota/berry/drivers/tm1637.be
new file mode 100644
index 000000000..9e7b572f0
--- /dev/null
+++ b/tasmota/berry/drivers/tm1637.be
@@ -0,0 +1,190 @@
+#-
+Simplified Tasmota TM1637 driver written in Berry
+Might be helpful in the case of using multiple displays
+Supports only the 4 digit basic display
+
+DIO_PIN and CLK_PIN are your esp32 pin numbers
+How to use
+
+> load('tm1637')
+> tm = Tm1637(DIO_PIN, CLK_PIN)
+> tm.set_on(4)
+> tm.print('0123')
+> tm.print(456)
+
+Add custom commands to the native Tasmota console:
+> tm_add_custom_commands(DIO_PIN, CLK_PIN)
+
+And then:
+TmBrightness 2
+TmPrint 0123
+TmPrint -5.67
+
+Note: adding these commands to autoexec.be should be performed via creating an additional .be file with the content:
+ tm_add_custom_commands(DIO_PIN, CLK_PIN)
+
+and then loading it in autoexec.be via load('tm1637') and load('script_name')
+The direct addition may not work
+-#
+
+class Tm1637
+ static var CMD_CTRL = 0x80
+ static var CMD_DISP_ON = 0x08
+ static var CMD_DATA = 0x40
+ static var CMD_ADDR = 0xC0
+
+ static var SYMB_DOT = 0x80
+
+ static var DIGIT_MAP = {
+ '0': 0x3F,
+ '1': 0x06,
+ '2': 0x5B,
+ '3': 0x4F,
+ '4': 0x66,
+ '5': 0x6D,
+ '6': 0x7D,
+ '7': 0x07,
+ '8': 0x7F,
+ '9': 0x6F,
+ '-': 0x40,
+ ' ': 0x00
+ }
+
+ var PIN_DIO
+ var PIN_CLK
+
+ def init(dio, clk)
+ self.PIN_DIO = dio
+ self.PIN_CLK = clk
+ gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
+ gpio.pin_mode(self.PIN_CLK, gpio.OUTPUT)
+ gpio.digital_write(self.PIN_DIO, 1)
+ gpio.digital_write(self.PIN_CLK, 1)
+ end
+
+ def start()
+ gpio.digital_write(self.PIN_DIO, 1)
+ gpio.digital_write(self.PIN_CLK, 1)
+ gpio.digital_write(self.PIN_DIO, 0)
+ end
+
+ def stop()
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.digital_write(self.PIN_DIO, 0)
+ gpio.digital_write(self.PIN_CLK, 1)
+ gpio.digital_write(self.PIN_DIO, 1)
+ end
+
+ def ack()
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.pin_mode(self.PIN_DIO, gpio.INPUT_PULLUP)
+ var ack_state = gpio.digital_read(self.PIN_DIO) == 0
+ gpio.digital_write(self.PIN_CLK, 1)
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
+ return ack_state
+ end
+
+ def write_bit(bitval)
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.digital_write(self.PIN_DIO, bitval)
+ gpio.digital_write(self.PIN_CLK, 1)
+ end
+
+ def write_byte(byteval)
+ for pos: 0..7
+ self.write_bit((byteval >> pos) & 0x01)
+ end
+ end
+
+ def send_command(command)
+ self.start()
+ self.write_byte(command)
+ var ack_state = self.ack()
+ self.stop()
+ return ack_state
+ end
+
+ def send_data(data)
+ var ack_state = true
+ self.start()
+ for i : 0..size(data)-1
+ self.write_byte(data[i])
+ ack_state = self.ack() && ack_state
+ end
+ self.stop()
+ return ack_state
+ end
+
+ # 0-8 range, 0 to 'OFF'
+ def set_on(brightness)
+ if brightness == nil || brightness > 8
+ brightness = 8
+ elif brightness < 0
+ brightness = 0
+ end
+ var cmd = self.CMD_CTRL
+ if brightness
+ cmd |= self.CMD_DISP_ON
+ brightness -= 1
+ end
+ return self.send_command(cmd | brightness)
+ end
+
+ def print(num)
+ import string
+
+ num = str(num)
+ var max_str_len = 4
+
+ do
+ var dot_pos = string.find(num, '.')
+ if dot_pos >= 0 && dot_pos < 5
+ max_str_len = 5
+ end
+ end
+ if size(num) > max_str_len
+ num = string.split(num, max_str_len)[0]
+ end
+ num = string.format('%4s', num)
+ var payload = bytes(-5)
+ payload[0] = self.CMD_ADDR
+ var int_offset = 1
+ for i : 0..size(num)-1
+ if num[i] == '.'
+ payload[i] |= self.SYMB_DOT
+ int_offset = 0
+ else
+ payload[i + int_offset] = self.DIGIT_MAP[num[i]]
+ end
+ end
+ var ack_state = self.send_command(self.CMD_DATA) && self.send_data(payload)
+ if !ack_state
+ log('TM1637 - no ACK, please check connections')
+ end
+ return ack_state
+ end
+
+ def clear()
+ self.print(' ')
+ end
+
+ # Won't be called on the system restart
+ def deinit()
+ self.set_on(0)
+ end
+end
+
+def tm_add_custom_commands(dio, clk)
+ var tm = Tm1637(dio, clk)
+ tm.clear()
+ tm.set_on(4)
+ tasmota.add_cmd('tmprint', def(cmd, idx, payload)
+ tm.print(payload) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
+ end)
+ # 0-8 range, 0 to 'OFF'
+ tasmota.add_cmd('tmbrightness', def(cmd, idx, payload)
+ tm.set_on(int(payload)) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
+ end)
+ log("Tasmota custom commands registered: TmPrint, TmBrightness")
+end
From 9bd458337f73763aa6ba4b24aefb3e1a9bc1adc4 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 3 Nov 2022 14:24:41 +0100
Subject: [PATCH 53/71] Zigbee fix checksum in ZBBridge Pro router firmware
---
.../SonoffZBPro_router_20220125.hex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex b/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
index 1d220c012..19bb38b64 100644
--- a/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
+++ b/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
@@ -5717,6 +5717,6 @@
:20CA1800A0C902000C010020A8C9020000010020B0C9020004010020B8C902000801002086
:020000040005F5
:207FA800000080011000C0FFFDFF58003AC1B9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
-:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF90
+:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF97
:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
:00000001FF
From 4e9cfc762929d34fe1d12588ff876ae09fd8da35 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 3 Nov 2022 17:26:54 +0100
Subject: [PATCH 54/71] Add command ``SetOption47 1..255``
Add command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge
---
CHANGELOG.md | 3 +-
RELEASENOTES.md | 2 +
tasmota/include/tasmota.h | 2 +-
tasmota/tasmota.ino | 2 +
tasmota/tasmota_support/support.ino | 5 ++
tasmota/tasmota_support/support_tasmota.ino | 52 +++++++++++++++++++--
6 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ac716257..ac4a43954 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,8 @@ All notable changes to this project will be documented in this file.
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
- Berry ``bytes().reverse()`` method (#16977)
-- Support for DMX ArtNet Led matrix animations
+- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
+- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index ab0e97a8a..e582f6c68 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,6 +109,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.2
### Added
+- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
@@ -118,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
+- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
### Breaking Changed
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index 3dee90dad..a78a5edb1 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -362,7 +362,7 @@ enum SO32_49Index { P_HOLD_TIME, // SetOption32 - (Button/Switch) K
P_IR_TOLERANCE, // SetOption44 - (IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)
P_BISTABLE_PULSE, // SetOption45 - (Bistable) Pulse time for two coil bistable latching relays (default 40)
P_POWER_ON_DELAY, // SetOption46 - (PowerOn) Add delay of 10 x value milliseconds at power on
- P_SO47_FREE, // SetOption47
+ P_POWER_ON_DELAY2, // SetOption47 - (PowerOn) Add delay of value seconds at power on before activating relays
P_SO48_FREE, // SetOption48
P_SO49_FREE // SetOption49
}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index c0652c563..f8cebb836 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -253,6 +253,7 @@ struct TasmotaGlobal_t {
power_t blink_power; // Blink power state
power_t blink_powersave; // Blink start power save state
power_t blink_mask; // Blink relay active mask
+ power_t power_on_delay_state;
int serial_in_byte_counter; // Index in receive buffer
@@ -333,6 +334,7 @@ struct TasmotaGlobal_t {
uint8_t last_source; // Last command source
uint8_t shutters_present; // Number of actual define shutters
uint8_t discovery_counter; // Delayed discovery counter
+ uint8_t power_on_delay; // Delay relay power on to reduce power surge (SetOption47)
#ifdef USE_PWM_DIMMER
uint8_t restore_powered_off_led_counter; // Seconds before powered-off LED (LEDLink) is restored
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index f082a2206..2e1e77dd0 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -106,6 +106,11 @@ uint32_t ResetReason(void) {
return ESP_ResetInfoReason();
}
+bool ResetReasonPowerOn(void) {
+ uint32_t reset_reason = ESP_ResetInfoReason();
+ return ((reset_reason == REASON_DEFAULT_RST) || (reset_reason == REASON_EXT_SYS_RST));
+}
+
String GetResetReason(void) {
if (OsWatchBlockedLoop()) {
char buff[32];
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index b51856b4b..a2a9ba8bf 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -240,6 +240,11 @@ void SetLatchingRelay(power_t lpower, uint32_t state) {
}
void SetDevicePower(power_t rpower, uint32_t source) {
+ if (TasmotaGlobal.power_on_delay) {
+ TasmotaGlobal.power_on_delay_state = rpower;
+ return;
+ }
+
ShowSource(source);
TasmotaGlobal.last_source = source;
@@ -384,7 +389,7 @@ void SetPowerOnState(void)
SetDevicePower(1, SRC_RESTART);
} else {
power_t devices_mask = POWER_MASK >> (POWER_SIZE - TasmotaGlobal.devices_present);
- if ((ResetReason() == REASON_DEFAULT_RST) || (ResetReason() == REASON_EXT_SYS_RST)) {
+ if (ResetReasonPowerOn()) {
switch (Settings->poweronstate) {
case POWER_ALL_OFF:
case POWER_ALL_OFF_PULSETIME_ON:
@@ -422,7 +427,8 @@ void SetPowerOnState(void)
uint32_t port = 0;
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
#ifdef ESP8266
- if (!Settings->flag3.no_power_feedback) { // SetOption63 - Don't scan relay power state at restart - #5594 and #5663
+ if (!Settings->flag3.no_power_feedback && // SetOption63 - Don't scan relay power state at restart - #5594 and #5663
+ !TasmotaGlobal.power_on_delay) { // SetOption47 - Delay switching relays to reduce power surge at power on
if ((port < MAX_RELAYS) && PinUsed(GPIO_REL1, port)) {
if (bitRead(TasmotaGlobal.rel_bistable, port)) {
port++; // Skip both bistable relays as always 0
@@ -1056,6 +1062,29 @@ void PerformEverySecond(void)
#endif
}
+ if (TasmotaGlobal.power_on_delay) {
+ if (1 == Settings->param[P_POWER_ON_DELAY2]) { // SetOption47 1
+ // Allow relay power on once network is available
+ if (!TasmotaGlobal.global_state.network_down) {
+ TasmotaGlobal.power_on_delay = 0;
+ }
+ }
+ else if (2 == Settings->param[P_POWER_ON_DELAY2]) { // SetOption47 2
+ // Allow relay power on once mqtt is available
+ if (!TasmotaGlobal.global_state.mqtt_down) {
+ TasmotaGlobal.power_on_delay = 0;
+ }
+ }
+ else { // SetOption47 3..255
+ // Allow relay power on after x seconds
+ TasmotaGlobal.power_on_delay--;
+ }
+ if (!TasmotaGlobal.power_on_delay && TasmotaGlobal.power_on_delay_state) {
+ // Set relays according to last SetDevicePower() request
+ SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_RESTART);
+ }
+ }
+
if (TasmotaGlobal.mqtt_cmnd_blocked_reset) {
TasmotaGlobal.mqtt_cmnd_blocked_reset--;
if (!TasmotaGlobal.mqtt_cmnd_blocked_reset) {
@@ -2046,6 +2075,19 @@ void GpioInit(void)
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, nitems(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0]));
+ if (ResetReasonPowerOn()) {
+ TasmotaGlobal.power_on_delay = Settings->param[P_POWER_ON_DELAY2]; // SetOption47 - Delay switching relays to reduce power surge at power on
+ if (TasmotaGlobal.power_on_delay) {
+ // This is the earliest possibility to disable relays connected to esp8266/esp32 gpios at power up to reduce power surge
+ for (uint32_t i = 0; i < MAX_RELAYS; i++) {
+ if (PinUsed(GPIO_REL1, i)) {
+ DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); // Off
+ }
+ }
+ AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 Power off relays"));
+ }
+ }
+
analogWriteRange(Settings->pwm_range); // Default is 1023 (Arduino.h)
analogWriteFreq(Settings->pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
@@ -2169,7 +2211,11 @@ void GpioInit(void)
}
}
- delay(Settings->param[P_POWER_ON_DELAY] * 10); // SetOption46 - Allow Wemos D1 power to stabilize before starting I2C polling for devices powered locally
+ if (Settings->param[P_POWER_ON_DELAY]) { // SetOption46 - Allow Wemos D1 power to stabilize before starting I2C polling for devices powered locally
+ uint32_t init_delay = Settings->param[P_POWER_ON_DELAY] * 10;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO46 Wait %d msec"), init_delay);
+ delay(init_delay);
+ }
#ifdef USE_I2C
TasmotaGlobal.i2c_enabled = (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA));
From 1caffb353c2bf246f4658945f75cf4f653f053a5 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 3 Nov 2022 17:50:47 +0100
Subject: [PATCH 55/71] Add more SO47 info
---
tasmota/include/tasmota.h | 4 ++--
tasmota/tasmota_support/support_tasmota.ino | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index a78a5edb1..99a5f780c 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -459,10 +459,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
- SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_MAX };
+ SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_MAX };
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
- "Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole";
+ "Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47";
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index a2a9ba8bf..00fdd00f9 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1081,7 +1081,7 @@ void PerformEverySecond(void)
}
if (!TasmotaGlobal.power_on_delay && TasmotaGlobal.power_on_delay_state) {
// Set relays according to last SetDevicePower() request
- SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_RESTART);
+ SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_SO47);
}
}
@@ -2084,7 +2084,7 @@ void GpioInit(void)
DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); // Off
}
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 Power off relays"));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 %d Power off relays"), Settings->param[P_POWER_ON_DELAY2]);
}
}
From a5e791770486dcbf17db68c0ba01e0a90813b558 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 3 Nov 2022 21:54:21 +0100
Subject: [PATCH 56/71] ESP32 DMX ArtNet optimization to avoid any object
allocation and avoid garbage collector pauses
---
CHANGELOG.md | 1 +
lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 26 ++++++++--
.../berry_tasmota/src/embedded/leds.be | 12 +++--
.../src/solidify/solidified_leds.h | 51 +++++++++++++------
tasmota/berry/artnet/artnet.be | 21 +++++---
.../xdrv_52_3_berry_leds.ino | 8 ---
6 files changed, 83 insertions(+), 36 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac4a43954..d5c140e23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Berry ``bytes().reverse()`` method (#16977)
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
+- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
### Breaking Changed
diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
index 439771fba..4186673c5 100644
--- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
+++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
@@ -94,10 +94,30 @@ extern "C" {
int32_t be_udp_read(struct bvm *vm) {
WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL);
if (udp->parsePacket()) {
- int btr = udp->available();
- uint8_t * buf = (uint8_t*) be_pushbuffer(vm, btr);
+ int btr = udp->available(); // btr contains the size of bytes_to_read
+
+ int argc = be_top(vm);
+ if (argc >= 2 && be_isbytes(vm, 2)) {
+ // we have already a bytes() buffer
+ be_pushvalue(vm, 2); // push on top
+ // resize to btr
+ be_getmember(vm, -1, "resize");
+ be_pushvalue(vm, -2);
+ be_pushint(vm, btr);
+ be_call(vm, 2);
+ be_pop(vm, 3);
+ } else {
+ be_pushbytes(vm, nullptr, btr); // allocate a buffer of size btr filled with zeros
+ }
+
+ // get the address of the buffer
+ be_getmember(vm, -1, "_buffer");
+ be_pushvalue(vm, -2);
+ be_call(vm, 1);
+ uint8_t * buf = (uint8_t*) be_tocomptr(vm, -2);
+ be_pop(vm, 2);
+
int32_t btr2 = udp->read(buf, btr);
- be_pushbytes(vm, buf, btr2);
// set remotet ip
IPAddress remote_ip = udp->remoteIP();
diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be
index 82b154186..23f24ef07 100644
--- a/lib/libesp32/berry_tasmota/src/embedded/leds.be
+++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be
@@ -117,8 +117,14 @@ class Leds : Leds_ntv
def dirty()
self.call_native(5)
end
- def pixels_buffer()
- return self.call_native(6)
+ def pixels_buffer(old_buf)
+ var buf = self.call_native(6) # address of buffer in memory
+ if old_buf == nil
+ return bytes(buf, self.pixel_size() * self.pixel_count())
+ else
+ old_buf._change_buffer(buf)
+ return old_buf
+ end
end
def pixel_size()
return self.call_native(7)
@@ -275,7 +281,7 @@ class Leds : Leds_ntv
# don't trigger on segment, you will need to trigger on full strip instead
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
self.strip.show()
- self.pix_buffer = self.strip.pixels_buffer() # update buffer after show()
+ self.pix_buffer = self.strip.pixels_buffer(self.pix_buffer) # update buffer after show()
end
end
def can_show()
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
index 589c59460..8c8692405 100644
--- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
@@ -1118,7 +1118,7 @@ be_local_closure(Leds_matrix_pixel_count, /* name */
********************************************************************/
be_local_closure(Leds_matrix_show, /* name */
be_nested_proto(
- 4, /* nstack */
+ 5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
@@ -1139,29 +1139,30 @@ be_local_closure(Leds_matrix_show, /* name */
}),
&be_const_str_show,
&be_const_str_solidified,
- ( &(const binstruction[22]) { /* code */
+ ( &(const binstruction[23]) { /* code */
0x60080017, // 0000 GETGBL R2 G23
0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1
0x740A0009, // 0003 JMPT R2 #000E
0x88080100, // 0004 GETMBR R2 R0 K0
0x1C080501, // 0005 EQ R2 R2 K1
- 0x780A000D, // 0006 JMPF R2 #0015
+ 0x780A000E, // 0006 JMPF R2 #0016
0x88080102, // 0007 GETMBR R2 R0 K2
0x880C0103, // 0008 GETMBR R3 R0 K3
0x08080403, // 0009 MUL R2 R2 R3
0x880C0104, // 000A GETMBR R3 R0 K4
0x880C0705, // 000B GETMBR R3 R3 K5
0x1C080403, // 000C EQ R2 R2 R3
- 0x780A0006, // 000D JMPF R2 #0015
+ 0x780A0007, // 000D JMPF R2 #0016
0x88080104, // 000E GETMBR R2 R0 K4
0x8C080506, // 000F GETMET R2 R2 K6
0x7C080200, // 0010 CALL R2 1
0x88080104, // 0011 GETMBR R2 R0 K4
0x8C080508, // 0012 GETMET R2 R2 K8
- 0x7C080200, // 0013 CALL R2 1
- 0x90020E02, // 0014 SETMBR R0 K7 R2
- 0x80000000, // 0015 RET 0
+ 0x88100107, // 0013 GETMBR R4 R0 K7
+ 0x7C080400, // 0014 CALL R2 2
+ 0x90020E02, // 0015 SETMBR R0 K7 R2
+ 0x80000000, // 0016 RET 0
})
)
);
@@ -1452,24 +1453,44 @@ be_local_closure(Leds_create_matrix, /* name */
********************************************************************/
be_local_closure(Leds_pixels_buffer, /* name */
be_nested_proto(
- 4, /* nstack */
- 1, /* argc */
+ 8, /* nstack */
+ 2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
+ ( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str(call_native),
+ /* K1 */ be_nested_str(pixel_size),
+ /* K2 */ be_nested_str(pixel_count),
+ /* K3 */ be_nested_str(_change_buffer),
}),
&be_const_str_pixels_buffer,
&be_const_str_solidified,
- ( &(const binstruction[ 4]) { /* code */
- 0x8C040100, // 0000 GETMET R1 R0 K0
- 0x540E0005, // 0001 LDINT R3 6
- 0x7C040400, // 0002 CALL R1 2
- 0x80040200, // 0003 RET 1 R1
+ ( &(const binstruction[21]) { /* code */
+ 0x8C080100, // 0000 GETMET R2 R0 K0
+ 0x54120005, // 0001 LDINT R4 6
+ 0x7C080400, // 0002 CALL R2 2
+ 0x4C0C0000, // 0003 LDNIL R3
+ 0x1C0C0203, // 0004 EQ R3 R1 R3
+ 0x780E0009, // 0005 JMPF R3 #0010
+ 0x600C0015, // 0006 GETGBL R3 G21
+ 0x5C100400, // 0007 MOVE R4 R2
+ 0x8C140101, // 0008 GETMET R5 R0 K1
+ 0x7C140200, // 0009 CALL R5 1
+ 0x8C180102, // 000A GETMET R6 R0 K2
+ 0x7C180200, // 000B CALL R6 1
+ 0x08140A06, // 000C MUL R5 R5 R6
+ 0x7C0C0400, // 000D CALL R3 2
+ 0x80040600, // 000E RET 1 R3
+ 0x70020003, // 000F JMP #0014
+ 0x8C0C0303, // 0010 GETMET R3 R1 K3
+ 0x5C140400, // 0011 MOVE R5 R2
+ 0x7C0C0400, // 0012 CALL R3 2
+ 0x80040200, // 0013 RET 1 R1
+ 0x80000000, // 0014 RET 0
})
)
);
diff --git a/tasmota/berry/artnet/artnet.be b/tasmota/berry/artnet/artnet.be
index 001987736..1fcdd5053 100644
--- a/tasmota/berry/artnet/artnet.be
+++ b/tasmota/berry/artnet/artnet.be
@@ -6,7 +6,9 @@ class ArtNet
var udp_server # instance of `udp` class
var universe_start # base universe number
var universe_end # last universe number allowed (excluded)
- static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
+ # static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
+ static var artnet_sig_0 = 0x4172742D # "Art-"
+ static var artnet_sig_4 = 0x4E657400 # "Net\x00"
var packet # try reusing the same packer bytes() object for performance
@@ -22,10 +24,11 @@ class ArtNet
self.universe_end = universe_start + matrix.h
if port == nil port = 6454 end
- # self.artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes
self.port = int(port)
if ip_addr == nil ip_addr = "" end
+ self.packet = bytes() # instanciate a single bytes() buffer that will be used for all received packets
+
self.udp_server = udp()
self.udp_server.begin(ip_addr, self.port)
@@ -38,10 +41,13 @@ class ArtNet
def fast_loop()
var universe_start = self.universe_start
var universe_end = self.universe_end
+ var artnet_sig_0 = self.artnet_sig_0
+ var artnet_sig_4 = self.artnet_sig_4
var dirty = false
var packet = self.udp_server.read(self.packet)
while (packet != nil)
- if size(packet) >= 18 && packet[0..7] == self.artnet_sig # check that we have a packet containing the 8 bytes header
+ if size(packet) >= 18 &&
+ packet.get(0, -4) == artnet_sig_0 && packet.get(4, -4) == artnet_sig_4
var opcode = packet.get(8, 2) # should be 0x5000
var protocol = packet.get(10, -2) # big endian, should be 14
var universe = packet.get(14, 2)
@@ -64,13 +70,12 @@ class ArtNet
# opcode, protocol, seq, phy, universe, data_len, packet[18..-1].tohex()))
end
end
- packet = self.udp_server.read(packet)
+ packet = self.udp_server.read(self.packet)
if packet == nil
tasmota.delay_microseconds(20) # wait 20 us just in case
- packet = self.udp_server.read(packet)
+ packet = self.udp_server.read(self.packet)
end
end
- self.packet = packet # save bytes() object for next iteration and avoid allocation of new object
if dirty
self.matrix.dirty()
@@ -83,7 +88,9 @@ return ArtNet
#-
# Example for M5Stack ATOM Matrix (5x5 matrix without alternate)
+import artnet
+# var artnet = ArtNet
var strip = Leds(25, gpio.pin(gpio.WS2812, 0))
var m = strip.create_matrix(5, 5, 0)
-var dmx = ArtNet(m)
+var dmx = artnet(m)
-#
\ No newline at end of file
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino
index 54c6c2c15..3d6b8f86b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino
@@ -151,19 +151,11 @@ extern "C" {
break;
case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer)
{
- size_t pixels_bytes;
- if (s_ws2812_grb) pixels_bytes = s_ws2812_grb->PixelsSize();
- if (s_sk6812_grbw) pixels_bytes = s_sk6812_grbw->PixelsSize();
-
uint8_t * pixels;
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
- be_getbuiltin(vm, "bytes");
be_pushcomptr(vm, pixels);
- be_pushint(vm, pixels_bytes);
- be_call(vm, 2);
- be_pop(vm, 2);
}
break;
case 7: // # 07 : PixelSize void -> int
From e7ac249f8f8dc1eab70876cae10f38de80213135 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 3 Nov 2022 22:01:24 +0100
Subject: [PATCH 57/71] Berry reduce detailed GC logs
---
tasmota/my_user_config.h | 1 +
tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino | 2 ++
2 files changed, 3 insertions(+)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e107c385d..b4bc564ef 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1074,6 +1074,7 @@
#define USE_BERRY_PSRAM // Allocate Berry memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
#define USE_BERRY_IRAM // Allocate some data structures in IRAM (which is ususally unused) when possible and if no PSRAM is available
// #define USE_BERRY_DEBUG // Compile Berry bytecode with line number information, makes exceptions easier to debug. Adds +8% of memory consumption for compiled code
+ // #define UBE_BERRY_DEBUG_GC // Print low-level GC metrics
// #define USE_BERRY_INT64 // Add 64 bits integer support (+1.7KB Flash)
#define USE_WEBCLIENT // Enable `webclient` to make HTTP/HTTPS requests. Can be disabled for security reasons.
// #define USE_WEBCLIENT_HTTPS // Enable HTTPS outgoing requests based on BearSSL (much ligher then mbedTLS, 42KB vs 150KB) in insecure mode (no verification of server's certificate)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
index 36ac8b4e0..d28e0e41e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
@@ -231,6 +231,7 @@ void BerryObservability(bvm *vm, int event...) {
slots_used_before_gc, slots_allocated_before_gc,
slots_used_after_gc, slots_allocated_after_gc);
+#ifdef UBE_BERRY_DEBUG_GC
// Add more in-deptch metrics
AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_BERRY "GC timing (us) 1:%i 2:%i 3:%i 4:%i 5:%i total:%i",
vm->micros_gc1 - vm->micros_gc0,
@@ -254,6 +255,7 @@ void BerryObservability(bvm *vm, int event...) {
vm->gc_mark_module,
vm->gc_mark_comobj
);
+#endif
// make new threshold tighter when we reach high memory usage
if (!UsePSRAM() && vm->gc.threshold > 20*1024) {
vm->gc.threshold = vm->gc.usage + 10*1024; // increase by only 10 KB
From e910f3071c6c03df41cb51eb7804ece1b7d4586c Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 6 Nov 2022 10:52:17 +0100
Subject: [PATCH 58/71] Berry add ``dyn`` class
---
CHANGELOG.md | 1 +
lib/libesp32/berry/default/be_modtab.c | 2 +
lib/libesp32/berry_tasmota/src/be_dyn_class.c | 4 +
.../berry_tasmota/src/embedded/dyn.be | 27 +++
.../src/solidify/solidified_dyn.h | 157 ++++++++++++++++++
5 files changed, 191 insertions(+)
create mode 100644 lib/libesp32/berry_tasmota/src/be_dyn_class.c
create mode 100644 lib/libesp32/berry_tasmota/src/embedded/dyn.be
create mode 100644 lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5c140e23..52a1b30b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
+- Berry add ``dyn`` class
### Breaking Changed
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index 1cc28efee..5b018304e 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -178,6 +178,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
NULL /* do not remove */
};
+be_extern_native_class(dyn);
be_extern_native_class(tasmota);
be_extern_native_class(Trigger);
be_extern_native_class(Driver);
@@ -228,6 +229,7 @@ be_extern_native_class(int64);
BERRY_LOCAL bclass_array be_class_table = {
#ifdef TASMOTA
/* first list are direct classes */
+ &be_native_class(dyn),
&be_native_class(tasmota),
&be_native_class(Trigger),
&be_native_class(Driver),
diff --git a/lib/libesp32/berry_tasmota/src/be_dyn_class.c b/lib/libesp32/berry_tasmota/src/be_dyn_class.c
new file mode 100644
index 000000000..b41ac1b29
--- /dev/null
+++ b/lib/libesp32/berry_tasmota/src/be_dyn_class.c
@@ -0,0 +1,4 @@
+/********************************************************************
+ * Tasmota dyn class
+ *******************************************************************/
+#include "solidify/solidified_dyn.h"
diff --git a/lib/libesp32/berry_tasmota/src/embedded/dyn.be b/lib/libesp32/berry_tasmota/src/embedded/dyn.be
new file mode 100644
index 000000000..5266304ba
--- /dev/null
+++ b/lib/libesp32/berry_tasmota/src/embedded/dyn.be
@@ -0,0 +1,27 @@
+#################################################################################
+# dyn class
+#
+# Allows to use a map with members
+# see https://github.com/berry-lang/berry/wiki/Chapter-8
+#################################################################################
+#@ solidify:dyn
+class dyn
+ var _attr
+ def init()
+ self._attr = {}
+ end
+ def setmember(name, value)
+ self._attr[name] = value
+ end
+ def member(name)
+ if self._attr.contains(name)
+ return self._attr[name]
+ else
+ import undefined
+ return undefined
+ end
+ end
+ def tostring()
+ return self._attr.tostring()
+ end
+end
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h
new file mode 100644
index 000000000..ccb1c98e5
--- /dev/null
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h
@@ -0,0 +1,157 @@
+/* Solidification of dyn.h */
+/********************************************************************\
+* Generated code, don't edit *
+\********************************************************************/
+#include "be_constobj.h"
+
+/********************************************************************
+** Solidified function: tostring
+********************************************************************/
+be_local_closure(dyn_tostring, /* name */
+ be_nested_proto(
+ 3, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 2]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ /* K1 */ be_nested_str(tostring),
+ }),
+ &be_const_str_tostring,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x8C040301, // 0001 GETMET R1 R1 K1
+ 0x7C040200, // 0002 CALL R1 1
+ 0x80040200, // 0003 RET 1 R1
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: member
+********************************************************************/
+be_local_closure(dyn_member, /* name */
+ be_nested_proto(
+ 5, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 3]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ /* K1 */ be_nested_str(contains),
+ /* K2 */ be_nested_str(undefined),
+ }),
+ &be_const_str_member,
+ &be_const_str_solidified,
+ ( &(const binstruction[12]) { /* code */
+ 0x88080100, // 0000 GETMBR R2 R0 K0
+ 0x8C080501, // 0001 GETMET R2 R2 K1
+ 0x5C100200, // 0002 MOVE R4 R1
+ 0x7C080400, // 0003 CALL R2 2
+ 0x780A0003, // 0004 JMPF R2 #0009
+ 0x88080100, // 0005 GETMBR R2 R0 K0
+ 0x94080401, // 0006 GETIDX R2 R2 R1
+ 0x80040400, // 0007 RET 1 R2
+ 0x70020001, // 0008 JMP #000B
+ 0xA40A0400, // 0009 IMPORT R2 K2
+ 0x80040400, // 000A RET 1 R2
+ 0x80000000, // 000B RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: setmember
+********************************************************************/
+be_local_closure(dyn_setmember, /* name */
+ be_nested_proto(
+ 4, /* nstack */
+ 3, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ }),
+ &be_const_str_setmember,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 3]) { /* code */
+ 0x880C0100, // 0000 GETMBR R3 R0 K0
+ 0x980C0202, // 0001 SETIDX R3 R1 R2
+ 0x80000000, // 0002 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: init
+********************************************************************/
+be_local_closure(dyn_init, /* name */
+ be_nested_proto(
+ 2, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ }),
+ &be_const_str_init,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x60040013, // 0000 GETGBL R1 G19
+ 0x7C040000, // 0001 CALL R1 0
+ 0x90020001, // 0002 SETMBR R0 K0 R1
+ 0x80000000, // 0003 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified class: dyn
+********************************************************************/
+be_local_class(dyn,
+ 1,
+ NULL,
+ be_nested_map(5,
+ ( (struct bmapnode*) &(const bmapnode[]) {
+ { be_const_key(tostring, 2), be_const_closure(dyn_tostring_closure) },
+ { be_const_key(member, 3), be_const_closure(dyn_member_closure) },
+ { be_const_key(init, 4), be_const_closure(dyn_init_closure) },
+ { be_const_key(setmember, -1), be_const_closure(dyn_setmember_closure) },
+ { be_const_key(_attr, -1), be_const_var(0) },
+ })),
+ (bstring*) &be_const_str_dyn
+);
+/*******************************************************************/
+
+void be_load_dyn_class(bvm *vm) {
+ be_pushntvclass(vm, &be_class_dyn);
+ be_setglobal(vm, "dyn");
+ be_pop(vm, 1);
+}
+/********************************************************************/
+/* End of solidification */
From 31516f2d34649c0216640b205f7f67d11b2b0618 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 6 Nov 2022 10:12:08 +0100
Subject: [PATCH 59/71] Add ModbusBridge malloc error notes
---
.../xdrv_63_modbus_bridge.ino | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 479ea560b..43bea32bf 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -187,6 +187,10 @@ uint32_t swap_endian32(uint32_t num)
((num<<24)&0xff000000); // byte 0 to byte 3
}
+void ModbusBridgeAllocError(const char* s)
+{
+ AddLog(LOG_LEVEL_ERROR, PSTR("MBS: could not allocate %s buffer"), s);
+}
/********************************************************************************************/
//
@@ -248,6 +252,11 @@ void ModbusBridgeHandle(void)
uint8_t *buffer;
if (modbusBridge.byteCount == 0) modbusBridge.byteCount = modbusBridge.dataCount * 2;
buffer = (uint8_t *)malloc(9 + modbusBridge.byteCount); // Addres(1), Function(1), Length(1), Data(1..n), CRC(2)
+ if (nullptr == buffer)
+ {
+ ModbusBridgeAllocError(PSTR("read"));
+ return;
+ }
memset(buffer, 0, 9 + modbusBridge.byteCount);
uint32_t error = tasmotaModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
@@ -562,9 +571,9 @@ void ModbusBridgeInit(void)
#ifdef USE_MODBUS_BRIDGE_TCP
// If TCP bridge is enabled allocate a TCP receive buffer
modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
- if (!modbusBridgeTCP.tcp_buf)
+ if (nullptr == modbusBridgeTCP.tcp_buf)
{
- AddLog(LOG_LEVEL_ERROR, PSTR("MBS: MBRTCP could not allocate buffer"));
+ ModbusBridgeAllocError(PSTR("TCP"));
return;
}
#endif
@@ -674,6 +683,11 @@ void ModbusTCPHandle(void)
modbusBridge.dataCount = 1;
writeData = (uint16_t *)malloc((byteCount / 2)+1);
+ if (nullptr == writeData)
+ {
+ ModbusBridgeAllocError(PSTR("write"));
+ return;
+ }
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
else count = 1;
@@ -860,6 +874,11 @@ void CmndModbusBridgeSend(void)
else
{
writeData = (uint16_t *)malloc(modbusBridge.dataCount);
+ if (nullptr == writeData)
+ {
+ ModbusBridgeAllocError(PSTR("write"));
+ return;
+ }
for (uint8_t jsonDataArrayPointer = 0; jsonDataArrayPointer < writeDataSize; jsonDataArrayPointer++)
{
From f76bed338be31a2e92f5ba290dbc47820ff6347e Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 6 Nov 2022 10:23:05 +0100
Subject: [PATCH 60/71] Localize ModbusBridge global func/var names
---
.../xdrv_63_modbus_bridge.ino | 106 ++++++++----------
1 file changed, 49 insertions(+), 57 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 43bea32bf..0e39e97a6 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -35,10 +35,10 @@
*
* -- Write multiple coils --
* ModbusSend {"deviceaddress": 1, "functioncode": 15, "startaddress": 1, "type":"bit", "count":4, "values":[1,0,1,1]}
- *
- * Info for modbusBridgeTCPServer:
+ *
+ * Info for modbusBridgeTCPServer:
* https://ipc2u.com/articles/knowledge-base/detailed-description-of-the-modbus-tcp-protocol-with-command-examples/
- *
+ *
* Info for modbus serial communications:
* https://ozeki.hu/p_5879-mobdbus-function-code-4-read-input-registers.html
* https://www.modbustools.com/modbus.html
@@ -102,7 +102,7 @@ ModbusBridgeTCP modbusBridgeTCP;
#endif
#include
-TasmotaModbus *tasmotaModbus = nullptr;
+TasmotaModbus *modbusBridgeModbus = nullptr;
enum class ModbusBridgeError
{
@@ -172,21 +172,13 @@ ModbusBridge modbusBridge;
/********************************************************************************************/
//
-// Helper functions for data conversion between little and big endian
+// Helper functions
//
-uint16_t swap_endian16(uint16_t num)
+uint16_t ModbusBridgeSwapEndian16(uint16_t num)
{
return (num>>8) | (num<<8);
}
-uint32_t swap_endian32(uint32_t num)
-{
- return ((num>>24)&0xff) | // move byte 3 to byte 0
- ((num<<8)&0xff0000) | // move byte 1 to byte 2
- ((num>>8)&0xff00) | // move byte 2 to byte 1
- ((num<<24)&0xff000000); // byte 0 to byte 3
-}
-
void ModbusBridgeAllocError(const char* s)
{
AddLog(LOG_LEVEL_ERROR, PSTR("MBS: could not allocate %s buffer"), s);
@@ -203,7 +195,7 @@ bool ModbusBridgeBegin(void)
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
Settings->modbus_sconfig = TS_SERIAL_8N1;
- int result = tasmotaModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
+ int result = modbusBridgeModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
if (result)
{
if (2 == result)
@@ -215,7 +207,7 @@ bool ModbusBridgeBegin(void)
return result;
}
-void SetModbusBridgeConfig(uint32_t serial_config)
+void ModbusBridgeSetConfig(uint32_t serial_config)
{
if (serial_config > TS_SERIAL_8O2)
{
@@ -228,7 +220,7 @@ void SetModbusBridgeConfig(uint32_t serial_config)
}
}
-void SetModbusBridgeBaudrate(uint32_t baudrate)
+void ModbusBridgeSetBaudrate(uint32_t baudrate)
{
if ((baudrate >= 300) && (baudrate <= 115200))
{
@@ -246,7 +238,7 @@ void SetModbusBridgeBaudrate(uint32_t baudrate)
//
void ModbusBridgeHandle(void)
{
- bool data_ready = tasmotaModbus->ReceiveReady();
+ bool data_ready = modbusBridgeModbus->ReceiveReady();
if (data_ready)
{
uint8_t *buffer;
@@ -258,7 +250,7 @@ void ModbusBridgeHandle(void)
return;
}
memset(buffer, 0, 9 + modbusBridge.byteCount);
- uint32_t error = tasmotaModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
+ uint32_t error = modbusBridgeModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
#ifdef USE_MODBUS_BRIDGE_TCP
for (uint32_t i = 0; i < nitems(modbusBridgeTCP.client_tcp); i++)
@@ -283,7 +275,7 @@ void ModbusBridgeHandle(void)
nrOfBytes += 1;
client.write(header, 9);
}
- else if (buffer[1] <= 2)
+ else if (buffer[1] <= 2)
{
header[4] = modbusBridge.byteCount >> 8;
header[5] = modbusBridge.byteCount + 3;
@@ -293,7 +285,7 @@ void ModbusBridgeHandle(void)
client.write(buffer + 3, modbusBridge.byteCount); // Don't send CRC
nrOfBytes += modbusBridge.byteCount;
}
- else if (buffer[1] <= 4)
+ else if (buffer[1] <= 4)
{
header[4] = modbusBridge.byteCount >> 8;
header[5] = modbusBridge.byteCount + 3;
@@ -367,10 +359,10 @@ void ModbusBridgeHandle(void)
if (modbusBridge.type == ModbusBridgeType::mb_raw)
{
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"RAW\":["));
- for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
+ for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
{
ResponseAppend_P(PSTR("%d"), buffer[i]);
- if (i < tasmotaModbus->ReceiveCount() - 1)
+ if (i < modbusBridgeModbus->ReceiveCount() - 1)
ResponseAppend_P(PSTR(","));
}
ResponseAppend_P(PSTR("]}"));
@@ -380,10 +372,10 @@ void ModbusBridgeHandle(void)
else if (modbusBridge.type == ModbusBridgeType::mb_hex)
{
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"HEX\":["));
- for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
+ for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
{
ResponseAppend_P(PSTR("0x%02X"), buffer[i]);
- if (i < tasmotaModbus->ReceiveCount() - 1)
+ if (i < modbusBridgeModbus->ReceiveCount() - 1)
ResponseAppend_P(PSTR(","));
}
ResponseAppend_P(PSTR("]}"));
@@ -405,7 +397,7 @@ void ModbusBridgeHandle(void)
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
dataOffset = 4;
}
- ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
+ ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d,"), modbusBridge.count);
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_VALUES "\":["));
@@ -539,7 +531,7 @@ void ModbusBridgeHandle(void)
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_DEVICE_ADDRESS "\":%d,"), buffer[0]);
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_FUNCTION_CODE "\":%d,"), buffer[1]);
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
- ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
+ ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d"), (buffer[4] << 8) + buffer[5]);
ResponseAppend_P(PSTR("}"));
ResponseJsonEnd();
@@ -566,7 +558,7 @@ void ModbusBridgeInit(void)
{
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
{
- tasmotaModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
+ modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
ModbusBridgeBegin();
#ifdef USE_MODBUS_BRIDGE_TCP
// If TCP bridge is enabled allocate a TCP receive buffer
@@ -591,7 +583,7 @@ void ModbusTCPHandle(void)
bool busy; // did we transfer some data?
int32_t buf_len;
- if (!tasmotaModbus)
+ if (!modbusBridgeModbus)
return;
// check for a new client connection
@@ -665,8 +657,8 @@ void ModbusTCPHandle(void)
if (mbfunctioncode <= 2)
{
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
- modbusBridge.byteCount = ((count - 1) >> 3) + 1;
- modbusBridge.dataCount = ((count - 1) >> 4) + 1;
+ modbusBridge.byteCount = ((count - 1) >> 3) + 1;
+ modbusBridge.dataCount = ((count - 1) >> 4) + 1;
}
else if (mbfunctioncode <= 4)
{
@@ -676,7 +668,7 @@ void ModbusTCPHandle(void)
}
else
{
- // For functioncode 15 & 16 ignore bytecount, tasmotaModbus does calculate this
+ // For functioncode 15 & 16 ignore bytecount, modbusBridgeModbus does calculate this
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
uint16_t byteCount = (buf_len - dataStartByte);
modbusBridge.byteCount = 2;
@@ -688,10 +680,10 @@ void ModbusTCPHandle(void)
ModbusBridgeAllocError(PSTR("write"));
return;
}
-
+
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
else count = 1;
-
+
for (uint16_t dataPointer = 0; dataPointer < byteCount; dataPointer++)
{
if (dataPointer % 2 == 0)
@@ -699,7 +691,7 @@ void ModbusTCPHandle(void)
writeData[dataPointer / 2] = (uint16_t)(((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]) << 8);
}
else
- {
+ {
writeData[dataPointer / 2] |= ((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]);
}
}
@@ -708,7 +700,7 @@ void ModbusTCPHandle(void)
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: MBRTCP to Modbus TransactionId:%d, deviceAddress:%d, functionCode:%d, startAddress:%d, count:%d, recvCount:%d, recvBytes:%d"),
modbusBridgeTCP.tcp_transaction_id, mbdeviceaddress, mbfunctioncode, mbstartaddress, count, modbusBridge.dataCount, modbusBridge.byteCount);
- tasmotaModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
+ modbusBridgeModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
free(writeData);
}
@@ -908,7 +900,7 @@ void CmndModbusBridgeSend(void)
writeData[jsonDataArrayPointer / 2] = (int8_t)jsonDataArray[jsonDataArrayPointer / 2].getInt(0) << 8;
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
break;
-
+
case ModbusBridgeType::mb_hex:
case ModbusBridgeType::mb_raw:
case ModbusBridgeType::mb_uint8:
@@ -918,31 +910,31 @@ void CmndModbusBridgeSend(void)
writeData[jsonDataArrayPointer / 2] = (uint8_t)jsonDataArray[jsonDataArrayPointer].getUInt(0) << 8;
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
break;
-
+
case ModbusBridgeType::mb_int16:
- writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
+ writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
: (int16_t)jsonDataArray[jsonDataArrayPointer].getInt(0);
break;
-
+
case ModbusBridgeType::mb_uint16:
- writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
+ writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
: (int16_t)jsonDataArray[jsonDataArrayPointer].getUInt(0);
break;
-
+
case ModbusBridgeType::mb_int32:
- writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
+ writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
: (int16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16);
- writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
+ writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0));
break;
-
+
case ModbusBridgeType::mb_uint32:
- writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
+ writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16);
- writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
+ writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0));
break;
-
+
case ModbusBridgeType::mb_float:
// TODO
default:
@@ -971,20 +963,20 @@ void CmndModbusBridgeSend(void)
if ((modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleCoil) || (modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleRegister))
modbusBridge.dataCount = 1;
- uint8_t error = tasmotaModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
+ uint8_t error = modbusBridgeModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
free(writeData);
-
+
if (error)
{
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR Driver send error %u"), error);
return;
- }
+ }
ResponseCmndDone();
}
void CmndModbusBridgeSetBaudrate(void)
{
- SetModbusBridgeBaudrate(XdrvMailbox.payload);
+ ModbusBridgeSetBaudrate(XdrvMailbox.payload);
ResponseCmndNumber(Settings->modbus_sbaudrate * 300);
}
@@ -1000,7 +992,7 @@ void CmndModbusBridgeSetConfig(void)
{ // Use 0..23 as serial config option
if ((XdrvMailbox.payload >= TS_SERIAL_5N1) && (XdrvMailbox.payload <= TS_SERIAL_8O2))
{
- SetModbusBridgeConfig(XdrvMailbox.payload);
+ ModbusBridgeSetConfig(XdrvMailbox.payload);
}
}
else if ((XdrvMailbox.payload >= 5) && (XdrvMailbox.payload <= 8))
@@ -1008,7 +1000,7 @@ void CmndModbusBridgeSetConfig(void)
int8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
if (serial_config >= 0)
{
- SetModbusBridgeConfig(serial_config);
+ ModbusBridgeSetConfig(serial_config);
}
}
}
@@ -1023,7 +1015,7 @@ void CmndModbusBridgeSetConfig(void)
void CmndModbusTCPStart(void)
{
- if (!tasmotaModbus)
+ if (!modbusBridgeModbus)
{
return;
}
@@ -1076,7 +1068,7 @@ void CmndModbusTCPConnect(void)
{
int32_t tcp_port = XdrvMailbox.payload;
- if (!tasmotaModbus)
+ if (!modbusBridgeModbus)
{
return;
}
@@ -1135,7 +1127,7 @@ bool Xdrv63(uint8_t function)
{
ModbusBridgeInit();
}
- else if (tasmotaModbus)
+ else if (modbusBridgeModbus)
{
switch (function)
{
From 050f2e7e61f9544e4996735e6b006a34dc20f2d1 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 6 Nov 2022 12:32:02 +0100
Subject: [PATCH 61/71] Fix ModbusBridge buffer overflow (#16979)
---
CHANGELOG.md | 1 +
tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52a1b30b0..5a3da0ee0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file.
### Fixed
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
- Serial initialization for baudrate and config (#16970)
+- ModbusBridge buffer overflow (#16979)
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 0e39e97a6..31b1c7a19 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -258,7 +258,7 @@ void ModbusBridgeHandle(void)
WiFiClient &client = modbusBridgeTCP.client_tcp[i];
if (client)
{
- uint8_t header[8];
+ uint8_t header[9];
uint8_t nrOfBytes = 8;
header[0] = modbusBridgeTCP.tcp_transaction_id >> 8;
header[1] = modbusBridgeTCP.tcp_transaction_id;
From 0e32763a4eddaac4738a69cba4f936bd08bd58e0 Mon Sep 17 00:00:00 2001
From: Cossid
Date: Sun, 6 Nov 2022 09:14:03 -0600
Subject: [PATCH 62/71] BP1658CJ - Add support for BP1658CJ RGBCW led driver
control as used in Orein OS0100411267 Bulb
---
.../include/tasmota_configurations_ESP32.h | 1 +
tasmota/include/tasmota_template.h | 7 +
tasmota/language/af_AF.h | 2 +
tasmota/language/bg_BG.h | 2 +
tasmota/language/cs_CZ.h | 2 +
tasmota/language/de_DE.h | 2 +
tasmota/language/el_GR.h | 2 +
tasmota/language/en_GB.h | 2 +
tasmota/language/es_ES.h | 2 +
tasmota/language/fr_FR.h | 2 +
tasmota/language/fy_NL.h | 2 +
tasmota/language/he_HE.h | 2 +
tasmota/language/hu_HU.h | 2 +
tasmota/language/it_IT.h | 2 +
tasmota/language/ko_KO.h | 2 +
tasmota/language/nl_NL.h | 2 +
tasmota/language/pl_PL.h | 2 +
tasmota/language/pt_BR.h | 2 +
tasmota/language/pt_PT.h | 2 +
tasmota/language/ro_RO.h | 2 +
tasmota/language/ru_RU.h | 2 +
tasmota/language/sk_SK.h | 2 +
tasmota/language/sv_SE.h | 2 +
tasmota/language/tr_TR.h | 2 +
tasmota/language/uk_UA.h | 2 +
tasmota/language/vi_VN.h | 2 +
tasmota/language/zh_CN.h | 2 +
tasmota/language/zh_TW.h | 2 +
tasmota/my_user_config.h | 1 +
.../tasmota_xlgt_light/xlgt_10_bp1658cj.ino | 180 ++++++++++++++++++
30 files changed, 241 insertions(+)
create mode 100644 tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index b252a2275..661440aea 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -723,6 +723,7 @@
#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
//#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code)
//#define USE_THERMOSTAT // Add support for Thermostat
+#define USE_BP1658CJ // Add support for BP1658CJ 5 channel led controller as used in Orein OS0100411267 Bulb
#define USE_ETHERNET // Add support for ethernet (+20k code)
#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 display driver used by Sonoff POWR3xxD and THR3xxD
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 831115456..e778914ed 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -199,6 +199,7 @@ enum UserSelectablePins {
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
GPIO_DALI_RX, GPIO_DALI_TX, // Dali
+ GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -445,6 +446,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
+ D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|"
;
const char kSensorNamesFixed[] PROGMEM =
@@ -459,6 +461,7 @@ const char kSensorNamesFixed[] PROGMEM =
#define MAX_SM2135_DAT 10
#define MAX_SM2335_DAT 16
#define MAX_DSB 4
+#define MAX_BP1658CJ_DAT 16
const uint16_t kGpioNiceList[] PROGMEM = {
GPIO_NONE, // Not used
@@ -715,6 +718,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK
AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA
#endif // USE_SM2335
+#ifdef USE_BP1658CJ
+ AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK
+ AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT, // BP1658CJ DATA
+#endif // USE_BP1658CJ
#ifdef USE_BP5758D
AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK
AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 53f836a14..30093df20 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "Diep slaap"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 784a15f90..dc1fc3d93 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index eb3d4d797..082a1120f 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index d4ba67d4a..4c0db3230 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index a7e79adf7..faaf0bac8 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index 392abdb0e..12e6cd29f 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index 62043d5c5..104ceb164 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 3a26c486f..e24243a8f 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 DAT"
#define D_SENSOR_SM2335_CLK "SM2335 CLK"
#define D_SENSOR_SM2335_DAT "SM2335 DAT"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "Hibernation"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 4e2bb00a1..fbbf72aa7 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index afde4734d..b94395a19 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index 1d753de1b..1a87c6ba1 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 05dc90c7e..a335c9d16 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -798,6 +798,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 - DATI"
#define D_SENSOR_SM2335_CLK "SM2335 - CLK"
#define D_SENSOR_SM2335_DAT "SM2335 - DATI"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ - CLK"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ - DATI"
#define D_SENSOR_BP5758D_CLK "BP5758D - CLK"
#define D_SENSOR_BP5758D_DAT "BP5758D - DATI"
#define D_SENSOR_DEEPSLEEP "Sleep profondo"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 7fd6d1864..8b3419e98 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index d0f96fe48..4b1b33995 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index a4237e480..d0c98a130 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "Głęboko uśpiony"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index ed31fc1f9..1a429027c 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index e1bde2d58..0b3cd1411 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index b9db344a1..6ceff55a7 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 5e38b74f9..2cf65b605 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 2565fd648..8dec871f6 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index 6c85c366f..ee8eb9167 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index a32bd177a..c0dc1bc30 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index b786a6700..3205c06f6 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index c054ed967..1552aa798 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 63d885088..d34849db2 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 30db4a4f1..22f72da25 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index b4bc564ef..aacbc1b64 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -562,6 +562,7 @@
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
#define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code)
#define USE_SM2335 // Add support for SM2335 RGBCW led control as used in SwitchBot Color Bulb (+0k7 code)
+#define USE_BP1658CJ // Add support for BP1658CJ RGBCW led control as used in Orein OS0100411267 Bulb
#define USE_BP5758D // Add support for BP5758D RGBCW led control as used in some Tuya lightbulbs (+0k8 code)
#define USE_SONOFF_L1 // Add support for Sonoff L1 led control
#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code)
diff --git a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
new file mode 100644
index 000000000..840022e23
--- /dev/null
+++ b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
@@ -0,0 +1,180 @@
+/*
+ xlgt_10_bp1658cj.ino - bp1658cj five channel led support for Tasmota
+
+ Copyright (C) 2022 Theo Arends and Cossid
+
+ 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 .
+*/
+
+#define US_BP1658CJ
+#ifdef USE_LIGHT
+#ifdef USE_BP1658CJ
+/*********************************************************************************************\
+ * BP1658CJ RGBCW Led bulbs like the Orein OS0100411267 Bulb
+ *
+ * Orein OS0100411267 Bulb
+ *
+ *
+ * FIXME
+ * {"NAME":"Orein OS0100411267 Bulb","GPIO":[0,0,0,0,9129,9088,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
+\*********************************************************************************************/
+
+#define XLGT_10 10
+
+// 10 = identification | 00 = Standby | 0000 = start at OUT1/5
+#define BP1658CJ_ADDR_STANDBY 0x80 // 10000000 0x80
+// 10 = identification | 01 = 3 channels (RGB) | 0000 = start at OUT1/5
+//#define BP1658CJ_ADDR_START_3CH 0x90 // 10010000 0xC8
+// 10 = identification | 10 = 2 channels (CW) | 0000 = start at OUT1/5
+//#define BP1658CJ_ADDR_START_2CH 0xA0 // 10100000 0xA0
+// 10 = identification | 11 = 5 channels (RGB+CW) | 0000 = start at OUT1/5
+#define BP1658CJ_ADDR_START_5CH 0xB0 // 10110000 0xB0
+
+// Current values
+// 0x0 // 0000 RGB 0mA | CW 0mA
+// 0x1 // 0001 RGB 10mA | CW 5mA
+// 0x2 // 0010 RGB 20mA | CW 10mA
+// 0x3 // 0011 RGB 30mA | CW 15mA
+// 0x4 // 0100 RGB 40mA | CW 20mA
+// 0x5 // 0101 RGB 50mA | CW 25mA
+// 0x6 // 0110 RGB 60mA | CW 30mA
+// 0x7 // 0111 RGB 70mA | CW 35mA
+// 0x8 // 1000 RGB 80mA | CW 40mA
+// 0x9 // 1001 RGB 900mA | CW 45mA
+// 0xA // 1010 RGB 100mA | CW 50mA
+// 0xB // 1011 RGB 110mA | CW 55mA
+// 0xC // 1100 RGB 120mA | CW 60mA
+// 0xD // 1101 RGB 130mA | CW 65mA
+// 0xE // 1110 RGB 140mA | CW 70mA
+// 0xF // 1111 RGB 150mA | CW 75mA
+
+struct BP1658CJ {
+ uint8_t clk = 0;
+ uint8_t data = 0;
+ uint8_t current;
+} Bp1658cj;
+
+/*********************************************************************************************\
+ * BP1658CJ code - inspired by Bp5758d/SM2335
+\*********************************************************************************************/
+const uint8_t BP1658CJ_DELAY = 2;
+
+void BP1658CJInit(void) {
+ pinMode(Bp1658cj.data, OUTPUT);
+ pinMode(Bp1658cj.clk, OUTPUT);
+ BP1658CJStop();
+}
+
+void BP1658CJWrite(uint8_t value) {
+ for (int bit_idx = 7; bit_idx >= 0; bit_idx--) {
+ bool bit = bitRead(value, bit_idx);
+ digitalWrite(Bp1658cj.data, bit);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ }
+ // Wait for ACK
+ pinMode(Bp1658cj.data, INPUT);
+ digitalWrite(Bp1658cj.clk, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ pinMode(Bp1658cj.data, OUTPUT);
+}
+
+void BP1658CJStart(uint8_t addr) {
+ digitalWrite(Bp1658cj.data, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ BP1658CJWrite(addr);
+}
+
+void BP1658CJStop(void) {
+ digitalWrite(Bp1658cj.clk, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.data, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+}
+
+/********************************************************************************************/
+
+bool BP1658CJSetChannels(void) {
+ uint16_t *cur_col_10 = (uint16_t*)XdrvMailbox.command;
+
+ // If we receive 0 for all channels, we'll assume that the lightbulb is off, and activate BP1658CJ's standby mode.
+ if (cur_col_10[0] == 0 && cur_col_10[1] == 0 && cur_col_10[2] == 0 && cur_col_10[3] == 0 && cur_col_10[4] == 0) {
+ BP1658CJStart(BP1658CJ_ADDR_STANDBY);
+ // Clear all remaining data. This clears out Current, Red, Green, Blue, Cold White, Warm White.
+ for (int i = 0; i < 11; i++) {
+ BP1658CJWrite(0);
+ }
+ BP1658CJStop();
+ return true;
+ }
+
+ // Write the header activating all 5 channels
+ BP1658CJStart(BP1658CJ_ADDR_START_5CH);
+ // Set the current defined in ModuleSelected.
+ BP1658CJWrite(Bp1658cj.current);
+ // Set RGB and CW grayscale.
+ for (int i = 0; i < 5; i++) {
+ BP1658CJWrite((uint8_t)(cur_col_10[i] & 0x1F));
+ BP1658CJWrite((uint8_t)(cur_col_10[i] >> 5));
+ }
+ BP1658CJStop();
+ return true;
+}
+
+void BP1658CJModuleSelected(void)
+{
+ if (PinUsed(GPIO_BP1658CJ_CLK) && PinUsed(GPIO_BP1658CJ_DAT, GPIO_ANY)) {
+ Bp1658cj.clk = Pin(GPIO_BP1658CJ_CLK);
+ Bp1658cj.data = Pin(GPIO_BP1658CJ_DAT, GPIO_ANY);
+ // See #define MAX_BP1658CJ_DAT 16 in tasmota_template.h
+ int currentDat = GetPin(Bp1658cj.data) - AGPIO(GPIO_BP1658CJ_DAT); // 0 .. 15
+ // Split RGB and CW current.
+ Bp1658cj.current = (currentDat << 4) | currentDat;
+
+ BP1658CJInit();
+
+ TasmotaGlobal.light_type = LT_RGBWC;
+ TasmotaGlobal.light_driver = XLGT_10;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("LGT: BP1658CJ Found"));
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xlgt10(uint8_t function)
+{
+ bool result = false;
+
+ switch (function) {
+ case FUNC_SET_CHANNELS:
+ result = BP1658CJSetChannels();
+ break;
+ case FUNC_MODULE_INIT:
+ BP1658CJModuleSelected();
+ break;
+ }
+ return result;
+}
+
+#endif // USE_BP1658CJ
+#endif // USE_LIGHT
From 79928150cbabc5d5b585f1bcbd86763224ee880e Mon Sep 17 00:00:00 2001
From: Cossid
Date: Sun, 6 Nov 2022 09:18:52 -0600
Subject: [PATCH 63/71] BP1658CJ - Remove debugging define.
---
tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino | 1 -
1 file changed, 1 deletion(-)
diff --git a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
index 840022e23..c241e796d 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
@@ -17,7 +17,6 @@
along with this program. If not, see .
*/
-#define US_BP1658CJ
#ifdef USE_LIGHT
#ifdef USE_BP1658CJ
/*********************************************************************************************\
From 1e2e5c308cc118941a94c8acdab34fc2217949f1 Mon Sep 17 00:00:00 2001
From: Cossid
Date: Sun, 6 Nov 2022 09:26:37 -0600
Subject: [PATCH 64/71] BP1658CJ - Add missing language translation for ca_AD.
---
tasmota/language/ca_AD.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index c01ee0d66..153db03f4 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
From 8f920220dba8d78f49d324e632dbf6e295751030 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 6 Nov 2022 17:41:53 +0100
Subject: [PATCH 65/71] Fis default sserialconfig on new installs
---
tasmota/tasmota_support/settings.ino | 1 +
1 file changed, 1 insertion(+)
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index ecfe30063..c31a603bf 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -914,6 +914,7 @@ void SettingsDefaultSet2(void) {
// Serial
Settings->serial_config = TS_SERIAL_8N1;
Settings->baudrate = APP_BAUDRATE / 300;
+ Settings->sserial_config = TS_SERIAL_8N1;
Settings->sbaudrate = SOFT_BAUDRATE / 300;
Settings->serial_delimiter = 0xff;
Settings->seriallog_level = SERIAL_LOG_LEVEL;
From 479b8f4015a4cbfd48d45a768a87a667762011d4 Mon Sep 17 00:00:00 2001
From: Reimer Prochnow
Date: Sun, 6 Nov 2022 18:38:40 +0100
Subject: [PATCH 66/71] fix for #13955
Signed-off-by: Reimer Prochnow
---
tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
index 81f7b3a3e..859d0e5ed 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
@@ -118,11 +118,16 @@ void DeepSleepPrepare(void)
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
}
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep: time %ld, next %ld, slip %ld"),
+ timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
// It may happen that wakeup in just <5 seconds in future
// In this case also add deepsleep to nextwakeup
if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) {
- // ensure nextwakeup is at least in the future
+ // ensure nextwakeup is at least in the future, and add 5%
RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep;
+ RtcSettings.nextwakeup += Settings->deepsleep * 0.05;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep too short: time %ld, next %ld, slip %ld"),
+ timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
}
String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02
From a469b35f021ac2d0d8a8753cb39f22201af5ba00 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 11:06:17 +0100
Subject: [PATCH 67/71] Bump version to v12.2.0.3
---
CHANGELOG.md | 17 ++++++++++++++---
RELEASENOTES.md | 5 ++++-
tasmota/include/tasmota_version.h | 2 +-
tasmota/tasmota_support/support_features.ino | 13 +++++++++----
tools/decode-status.py | 8 ++++----
5 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a3da0ee0..6ed7e1001 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [12.2.0.2]
+## [12.2.0.3]
+### Added
+- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid (#17011)
+
+### Breaking Changed
+
+### Changed
+
+### Fixed
+
+### Removed
+
+## [12.2.0.2] 20221107
### Added
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
@@ -14,8 +26,6 @@ All notable changes to this project will be documented in this file.
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
- Berry add ``dyn`` class
-### Breaking Changed
-
### Changed
- Move some persistent data (PowerLow)
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
@@ -25,6 +35,7 @@ All notable changes to this project will be documented in this file.
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
- Serial initialization for baudrate and config (#16970)
- ModbusBridge buffer overflow (#16979)
+- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index e582f6c68..0fc183dd2 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -107,7 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v12.2.0.2
+## Changelog v12.2.0.3
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
@@ -116,6 +116,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
+- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
@@ -134,6 +135,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
+- ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979)
+- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
### Removed
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index 6d24b16b5..c2ac91bfd 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x0C020002; // 12.2.0.2
+const uint32_t VERSION = 0x0C020003; // 12.2.0.3
#endif // _TASMOTA_VERSION_H_
diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino
index 78d972340..9c728ef75 100644
--- a/tasmota/tasmota_support/support_features.ino
+++ b/tasmota/tasmota_support/support_features.ino
@@ -840,10 +840,15 @@ void ResponseAppendFeatures(void)
#if defined(USE_ENERGY_SENSOR) && defined(USE_MODBUS_ENERGY)
feature9 |= 0x00000010; // xnrg_29_modbus.ino
#endif
-// feature9 |= 0x00000020;
-// feature9 |= 0x00000040;
-// feature9 |= 0x00000080;
-
+#if defined(USE_SPI) && defined(USE_SHELLY_PRO)
+ feature9 |= 0x00000020; // xdrv_88_esp32_shelly_pro.ino
+#endif
+#ifdef USE_DALI
+ feature9 |= 0x00000040; // xdrv_89_esp32_dali.ino
+#endif
+#if defined(USE_LIGHT) && defined(USE_BP1658CJ)
+ feature9 |= 0x00000080; // xlgt_10_bp1658cj.ino
+#endif
// feature9 |= 0x00000100;
// feature9 |= 0x00000200;
// feature9 |= 0x00000400;
diff --git a/tools/decode-status.py b/tools/decode-status.py
index d076f11a2..1ae8641e2 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -97,8 +97,8 @@ a_setoption = [[
"(Rotary) Rotary step boundary (default 10)",
"(IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)",
"(Bistable) Pulse time in milliseconds for two coil bistable latching relays (default 40)",
- "(not used) Tuya MCU power Id",
- "(not used) Energy Tariff1 start hour",
+ "(PowerOn) Add delay of 10 x value milliseconds at power on",
+ "(PowerOn) Add delay of value seconds at power on before activating relays",
"(not used) Energy Tariff2 start hour",
"",
],[
@@ -287,7 +287,7 @@ a_features = [[
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
],[
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
- "USE_MODBUS_ENERGY","","","",
+ "USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
"","","","",
"","","","",
"","","","",
@@ -321,7 +321,7 @@ else:
obj = json.load(fp)
def StartDecode():
- print ("\n*** decode-status.py v12.1.1.4 by Theo Arends and Jacek Ziolkowski ***")
+ print ("\n*** decode-status.py v12.2.0.3 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj))
From 1c47744eeb43c26e31ad171a689d1c2168ea54f0 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 11:56:27 +0100
Subject: [PATCH 68/71] Clean up
---
tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
index 859d0e5ed..27377eeea 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
@@ -118,16 +118,14 @@ void DeepSleepPrepare(void)
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep: time %ld, next %ld, slip %ld"),
- timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DSL: Time %ld, next %ld, slip %ld"), timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
// It may happen that wakeup in just <5 seconds in future
// In this case also add deepsleep to nextwakeup
if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) {
// ensure nextwakeup is at least in the future, and add 5%
RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep;
RtcSettings.nextwakeup += Settings->deepsleep * 0.05;
- AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep too short: time %ld, next %ld, slip %ld"),
- timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DSL: Time too short: time %ld, next %ld, slip %ld"), timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
}
String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02
From 4ebd7a9cd32c9ed29a4baac91108afe986b79643 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 12:46:24 +0100
Subject: [PATCH 69/71] Update ESP32 processor detection
---
tasmota/tasmota_support/support_esp.ino | 91 ++++++++++++++++++++++---
1 file changed, 83 insertions(+), 8 deletions(-)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index b4fb28cf6..9f9e8cfde 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -104,7 +104,14 @@ String GetDeviceHardware(void) {
uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
-
+ /*
+ ESP8266 SoCs
+ - 32-bit MCU & 2.4 GHz Wi-Fi
+ - High-performance 160 MHz single-core CPU
+ - +19.5 dBm output power ensures a good physical range
+ - Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
+ - Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
+ */
if (((efuse1 & (1 << 4)) || (efuse2 & (1 << 16))) && (ESP.getFlashChipRealSize() < 1048577)) { // ESP8285 can only have 1M flash
return F("ESP8285");
}
@@ -768,6 +775,17 @@ typedef struct {
bool single_core = (1 == chip_info.cores);
if (chip_model < 2) { // ESP32
+ /*
+ ESP32 Series
+ - 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth/Bluetooth LE
+ - Two or one CPU core(s) with adjustable clock frequency, ranging from 80 MHz to 240 MHz
+ - +19.5 dBm output power ensures a good physical range
+ - Classic Bluetooth for legacy connections, also supporting L2CAP, SDP, GAP, SMP, AVDTP, AVCTP, A2DP (SNK) and AVRCP (CT)
+ - Support for Bluetooth Low Energy (Bluetooth LE) profiles including L2CAP, GAP, GATT, SMP, and GATT-based profiles like BluFi, SPP-like, etc
+ - Bluetooth Low Energy (Bluetooth LE) connects to smart phones, broadcasting low-energy beacons for easy detection
+ - Sleep current is less than 5 μA, making it suitable for battery-powered and wearable-electronics applications
+ - Peripherals include capacitive touch sensors, Hall sensor, SD card interface, Ethernet, high-speed SPI, UART, I2S and I2C
+ */
#ifdef CONFIG_IDF_TARGET_ESP32
/* esptool:
def get_pkg_version(self):
@@ -807,6 +825,15 @@ typedef struct {
return F("ESP32");
}
else if (2 == chip_model) { // ESP32-S2
+ /*
+ ESP32-S2 Series
+ - 32-bit MCU & 2.4 GHz Wi-Fi
+ - High-performance 240 MHz single-core CPU
+ - Ultra-low-power performance: fine-grained clock gating, dynamic voltage and frequency scaling
+ - Security features: eFuse、flash encryption, secure boot, signature verification, integrated AES, SHA and RSA algorithms
+ - Peripherals include 43 GPIOs, 1 full-speed USB OTG interface, SPI, I2S, UART, I2C, LED PWM, LCD interface, camera interface, ADC, DAC, touch sensor, temperature sensor
+ - Availability of common cloud connectivity agents and common product features shortens the time to market
+ */
#ifdef CONFIG_IDF_TARGET_ESP32S2
/* esptool:
def get_flash_version(self):
@@ -840,13 +867,19 @@ typedef struct {
#endif // CONFIG_IDF_TARGET_ESP32S2
return F("ESP32-S2");
}
- else if (9 == chip_model) { // ESP32-S3
-#ifdef CONFIG_IDF_TARGET_ESP32S3
- // no variants for now
-#endif // CONFIG_IDF_TARGET_ESP32S3
- return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1
+ else if (4 == chip_model) { // ESP32-S3(beta2)
+ return F("ESP32-S3");
}
- else if (5 == chip_model) { // ESP32-C3
+ else if (5 == chip_model) { // ESP32-C3 = ESP8685
+ /*
+ ESP32-C3 Series
+ - 32-bit RISC-V MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
+ - 32-bit RISC-V single-core processor with a four-stage pipeline that operates at up to 160 MHz
+ - State-of-the-art power and RF performance
+ - 400 KB of SRAM and 384 KB of ROM on the chip, and SPI, Dual SPI, Quad SPI, and QPI interfaces that allow connection to flash
+ - Reliable security features ensured by RSA-3072-based secure boot, AES-128-XTS-based flash encryption, the innovative digital signature and the HMAC peripheral, hardware acceleration support for cryptographic algorithms
+ - Rich set of peripheral interfaces and GPIOs, ideal for various scenarios and complex applications
+ */
#ifdef CONFIG_IDF_TARGET_ESP32C3
/* esptool:
def get_pkg_version(self):
@@ -894,7 +927,22 @@ typedef struct {
#endif // CONFIG_IDF_TARGET_ESP32C6
return F("ESP32-C6");
}
- else if (10 == chip_model) { // ESP32-H2
+ else if (9 == chip_model) { // ESP32-S3
+ /*
+ ESP32-S3 Series
+ - 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
+ - Xtensa® 32-bit LX7 dual-core processor that operates at up to 240 MHz
+ - 512 KB of SRAM and 384 KB of ROM on the chip, and SPI, Dual SPI, Quad SPI, Octal SPI, QPI, and OPI interfaces that allow connection to flash and external RAM
+ - Additional support for vector instructions in the MCU, which provides acceleration for neural network computing and signal processing workloads
+ - Peripherals include 45 programmable GPIOs, SPI, I2S, I2C, PWM, RMT, ADC and UART, SD/MMC host and TWAITM
+ - Reliable security features ensured by RSA-based secure boot, AES-XTS-based flash encryption, the innovative digital signature and the HMAC peripheral, “World Controller”
+ */
+#ifdef CONFIG_IDF_TARGET_ESP32S3
+ // no variants for now
+#endif // CONFIG_IDF_TARGET_ESP32S3
+ return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1
+ }
+ else if (10 == chip_model) { // ESP32-H2(beta1)
#ifdef CONFIG_IDF_TARGET_ESP32H2
/* esptool:
def get_pkg_version(self):
@@ -916,6 +964,33 @@ typedef struct {
#endif // CONFIG_IDF_TARGET_ESP32H2
return F("ESP32-H2");
}
+ else if (12 == chip_model) { // ESP32-C2 = ESP8684
+ /*
+ ESP32-C2 Series
+ - 32-bit RISC-V MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
+ - 32-bit RISC-V single-core processor that operates at up to 120 MHz
+ - State-of-the-art power and RF performance
+ - 576 KB ROM, 272 KB SRAM (16 KB for cache) on the chip
+ - 14 programmable GPIOs: SPI, UART, I2C, LED PWM controller, General DMA controller (GDMA), SAR ADC, Temperature sensor
+ */
+
+ return F("ESP32-C2");
+ }
+ else if (13 == chip_model) { // ESP32-C6
+ /*
+ ESP32-C6 Series
+ - 32-bit RISC-V MCU & 2.4 GHz Wi-Fi 6 & Bluetooth 5 (LE) & IEEE 802.15.4
+ - 32-bit RISC-V single-core processor that operates at up to 160 MHz
+ - State-of-the-art power and RF performance
+ - 320 KB ROM, 512 KB SRAM, 16 KB Low-power SRAM on the chip, and works with external flash
+ - 30 (QFN40) or 22 (QFN32) programmable GPIOs, with support for SPI, UART, I2C, I2S, RMT, TWAI and PWM
+ */
+
+ return F("ESP32-C6");
+ }
+ else if (14 == chip_model) { // ESP32-H2(beta2)
+ return F("ESP32-H2");
+ }
return F("ESP32");
}
From 7698178b90569a96281e1a2616f7b55b70f11afb Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 15:00:47 +0100
Subject: [PATCH 70/71] Update ESP8285 device detection
---
tasmota/tasmota_support/support_esp.ino | 51 ++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index 9f9e8cfde..9fa5c87cf 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -98,7 +98,7 @@ void *special_calloc(size_t num, size_t size) {
return calloc(num, size);
}
-String GetDeviceHardware(void) {
+String GetDeviceHardwareOld(void) {
// esptool.py get_efuses
uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
@@ -118,6 +118,55 @@ String GetDeviceHardware(void) {
return F("ESP8266EX");
}
+String GetDeviceHardware(void) {
+ /*
+ ESP8266 SoCs
+ - 32-bit MCU & 2.4 GHz Wi-Fi
+ - High-performance 160 MHz single-core CPU
+ - +19.5 dBm output power ensures a good physical range
+ - Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
+ - Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
+ */
+ // esptool.py get_efuses
+ uint32_t efuse0 = *(uint32_t*)(0x3FF00050);
+// uint32_t efuse1 = *(uint32_t*)(0x3FF00054);
+ uint32_t efuse2 = *(uint32_t*)(0x3FF00058);
+ uint32_t efuse3 = *(uint32_t*)(0x3FF0005C);
+
+ bool r0_4 = efuse0 & (1 << 4); // ESP8285
+ bool r2_16 = efuse2 & (1 << 16); // ESP8285
+ if (r0_4 || r2_16) { // ESP8285
+ // 1M 2M 2M 4M
+ // r0_4 1 1 0 0
+ bool r3_25 = efuse3 & (1 << 25); // ESP8285 flash matrix 0 0 1 1
+ bool r3_26 = efuse3 & (1 << 26); // ESP8285 flash matrix 0 1 0 1
+ bool r3_27 = efuse3 & (1 << 27); // ESP8285 flash matrix 0 0 0 0
+ uint32_t pkg_version = 0;
+ if (!r3_27) {
+ if (r0_4 && !r3_25) {
+ pkg_version = (r3_26) ? 2 : 1;
+ }
+ else if (!r0_4 && r3_25) {
+ pkg_version = (r3_26) ? 4 : 2;
+ }
+ }
+ bool max_temp = efuse0 & (1 << 5); // Max flash temperature (0 = 85C, 1 = 105C)
+ switch (pkg_version) {
+ case 1:
+ if (max_temp) { return F("ESP8285H08"); } // 1M flash
+ else { return F("ESP8285N08"); }
+ case 2:
+ if (max_temp) { return F("ESP8285H16"); } // 2M flash
+ else { return F("ESP8285N16"); }
+ case 4:
+ if (max_temp) { return F("ESP8285H32"); } // 4M flash
+ else { return F("ESP8285N32"); }
+ }
+ return F("ESP8285");
+ }
+ return F("ESP8266EX");
+}
+
String GetDeviceHardwareRevision(void) {
// No known revisions for ESP8266/85
return GetDeviceHardware();
From e8f24fdb6c624b78b112c7bdff10b33d094cf34c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 15:02:03 +0100
Subject: [PATCH 71/71] Update ESP8285 processor detection
---
tasmota/tasmota_support/support_esp.ino | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index 9fa5c87cf..a0ce1d228 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -98,26 +98,6 @@ void *special_calloc(size_t num, size_t size) {
return calloc(num, size);
}
-String GetDeviceHardwareOld(void) {
- // esptool.py get_efuses
- uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
- uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
-// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
-// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
- /*
- ESP8266 SoCs
- - 32-bit MCU & 2.4 GHz Wi-Fi
- - High-performance 160 MHz single-core CPU
- - +19.5 dBm output power ensures a good physical range
- - Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
- - Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
- */
- if (((efuse1 & (1 << 4)) || (efuse2 & (1 << 16))) && (ESP.getFlashChipRealSize() < 1048577)) { // ESP8285 can only have 1M flash
- return F("ESP8285");
- }
- return F("ESP8266EX");
-}
-
String GetDeviceHardware(void) {
/*
ESP8266 SoCs