From c8b8fe2da4f9347cd8190b4965ddfe2d7e83091f Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Tue, 15 Feb 2022 13:51:43 +1100 Subject: [PATCH 1/8] Added support for BL6523 chipset based Energy Monitors --- 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/tasmota_template.h | 6 + tasmota/xsns_96_bl6523.ino | 353 +++++++++++++++++++++++++++++++++++++ 28 files changed, 411 insertions(+) create mode 100644 tasmota/xsns_96_bl6523.ino diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 60460a97a..8a2c5e5f0 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 602091030..41485e29a 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 1a731d7fa..2a6f91636 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index bd4306de9..2c020ad3e 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Herzschlag" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index df9fd6fff..98b58c971 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 71bd64bac..8de4e9743 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index a317601ad..0831d4c8b 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 8a28c747d..5671da05d 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 7addac432..8305f8aac 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 9c0941429..e72ff9d8e 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 6fad9fbb5..702a476e4 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 9a5c7a78c..6a8ad1b93 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 - RX" #define D_SENSOR_HRG15_TX "HRG15 - TX" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Battito cardiaco" #define D_GPIO_SHIFT595_SRCLK "74x595 - SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 - RCLK" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 85306451c..713e3be14 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 17803a9b0..e4d5e8916 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 1b83b5639..64b3347d6 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "Kierunek wiatru" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index b3314554e..038d8354d 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 357aec476..932a10650 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index ab325f19a..6c5433891 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 927a5e38d..845bc6f30 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 322b412cb..3b2883bf2 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index ed1298eb2..38697b695 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index b238b88b9..e76e8076d 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index b75e1f04a..5e4a99e10 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 13242d134..f52e6599a 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index bd9b96293..882d9756e 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 8689fcddd..b7eb80a67 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -847,6 +847,8 @@ #define D_SENSOR_HRG15_RX "HRG15 Rx" #define D_SENSOR_HRG15_TX "HRG15 Tx" #define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" #define D_SENSOR_HEARTBEAT "Heartbeat" #define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 615c48630..7af28acd4 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -172,6 +172,7 @@ enum UserSelectablePins { GPIO_MCP2515_CS, // MCP2515 Chip Select GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface + GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2) GPIO_BL0942_RX, // BL0942 Serial interface GPIO_HM330X_SET, // HM330X SET pin (sleep when low) @@ -393,6 +394,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_MCP2515_CS "|" D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|" D_SENSOR_VINDRIKTNING_RX "|" + D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|" D_SENSOR_BL0939_RX "|" D_SENSOR_BL0942_RX "|" D_SENSOR_HM330X_SET "|" @@ -812,6 +814,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_VINDRIKTNING AGPIO(GPIO_VINDRIKTNING_RX), #endif +#ifdef USE_BL6523 + AGPIO(GPIO_BL6523_TX), + AGPIO(GPIO_BL6523_RX), +#endif #ifdef USE_HM330X AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) #endif diff --git a/tasmota/xsns_96_bl6523.ino b/tasmota/xsns_96_bl6523.ino new file mode 100644 index 000000000..7587a897f --- /dev/null +++ b/tasmota/xsns_96_bl6523.ino @@ -0,0 +1,353 @@ +/* + xsns_96_bl6523.ino - Chinese bl6523 based Watt hour meter support for Tasmota + + Copyright (C) 2022 Jeevas Vasudevan and the Internet + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_BL6523 +/*********************************************************************************************\ + * Chinese BL6523 based Watt hour meter + * + * 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_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} +\*********************************************************************************************/ + +#define XSNS_96 96 + +#include + +#define BL6523_RX_DATASET_SIZE 2 +#define BL6523_TX_DATASET_SIZE 4 + +#define BL6523_BAUD 4800 +#define BL6523_REG_AMPS 0x05 +#define BL6523_REG_VOLTS 0x07 +#define BL6523_REG_FREQ 0x09 +#define BL6523_REG_WATTS 0x0A +#define BL6523_REG_POWF 0x08 +#define BL6523_REG_WATTHR 0x0C + +/* No idea how to derive human readable units from the byte stream. +For now dividing the 24-bit values with below constants seems to yield something sane +that matches whatever displayed in the screen of my 240v model. Probably it would be possible +to extract these values from the write register commands (0xCA).*/ +#define BL6523_DIV_AMPS 297899.4f +#define BL6523_DIV_VOLTS 13304.0f +#define BL6523_DIV_FREQ 3907.0f +#define BL6523_DIV_WATTS 707.0f +#define BL6523_DIV_WATTHR 674.0f + +TasmotaSerial *Bl6523RxSerial; +TasmotaSerial *Bl6523TxSerial; + +struct BL6523 +{ + uint32_t amps = 0; + uint32_t volts = 0; + uint32_t freq = 0; + uint32_t watts = 0; + uint32_t powf = 0; + uint32_t watthr = 0; + + uint8_t type = 1; + uint8_t valid = 0; + uint8_t got_data_stone = 0; + bool discovery_triggered = false; +} Bl6523; + +bool Bl6523ReadData(void) +{ + + if (!Bl6523RxSerial->available()) + { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " )); + return false; + } + + while ((Bl6523RxSerial->peek() != 0x35) && Bl6523RxSerial->available()) + { + Bl6523RxSerial->read(); + } + + if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE) + { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " )); + return false; + } + + uint8_t rx_buffer[BL6523_RX_DATASET_SIZE]; + Bl6523RxSerial->readBytes(rx_buffer, BL6523_RX_DATASET_SIZE); + Bl6523RxSerial->flush(); // Make room for another burst + + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE); + + while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE) + { + // sleep till TX buffer is full + unsigned long timeout = millis() + 10; + while (millis() < timeout) {} + } + + + 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++) + { + crc += tx_buffer[i]; //Add Data_L,Data_M and Data_H to Addr + } + crc &= 0xff; // Bitwise AND 0xFF + crc = ~crc; // Invert the byte + if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1]) + { + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE)); + 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 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) +*/ + + /* READ DATA (format: command(read->0x35) address data_low data_mid data_high checksum ) +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 08 TX: 00 00 00 F7 (PF) +RX: 35 0C TX: 00 00 00 F3 (WATT_HR) +*/ + +switch(rx_buffer[1]) { + case BL6523_REG_AMPS : + Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<0; + break; + case BL6523_REG_VOLTS : + Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<1; + break; + case BL6523_REG_FREQ : + Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<2; + break; + case BL6523_REG_WATTS : + Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<3; + break; + case BL6523_REG_POWF : + Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<4; + break; + case BL6523_REG_WATTHR : + Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<5; + break; + default : + break; +} + +AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr); + + if (!Bl6523.discovery_triggered) + { + TasmotaGlobal.discovery_counter = 1; // force TasDiscovery() + Bl6523.discovery_triggered = true; + } + return true; + +} + +/*********************************************************************************************/ + +void Bl6523Update(void) +{ // Every 250 millisecond + if (Bl6523ReadData()) + { + Bl6523.valid = 60; + } + else + { + if (Bl6523.valid) { + Bl6523.valid--; + } + } +} + +/*********************************************************************************************/ + +void Bl6523Init(void) +{ + Bl6523.type = 0; + if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX))) + { + Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1); + Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1); + if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD))) + { + if (Bl6523RxSerial->hardwareSerial()) + { + ClaimSerial(); + } + if (Bl6523TxSerial->hardwareSerial()) + { + ClaimSerial(); + } + Bl6523.type = 1; + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " )); + } + } +} + +#ifdef USE_WEBSERVER +const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = , {e} = +const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = , {e} = +#endif // USE_WEBSERVER + +void Bl6523Show(bool json) +{ + uint32_t powf_word = 0; + float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0 .0f; + char amps_str[12], volts_str[12], freq_str[12]; + char watts_str[12], powf_str[12], watthr_str[12]; + + if (Bl6523.valid) + { + + amps = (float)Bl6523.amps / BL6523_DIV_AMPS; + volts = (float)Bl6523.volts / BL6523_DIV_VOLTS; + freq = (float)Bl6523.freq / BL6523_DIV_FREQ; + watts = (float)Bl6523.watts / BL6523_DIV_WATTS; + + /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。) + Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5 + */ + powf = 0.0f; + powf_word = Bl6523.powf & 0x7fffff; //Extract the 23 bits + for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits + powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1)))); + powf_word = powf_word & (0x7fffff >> (1+i)); + } + powf = (Bl6523.powf >> 23) ? (0.0f - (~powf)) : powf; // Negate if sign bit(24) is set + + watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR; + + ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s); + ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts); + ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq); + ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts); + ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf); + ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr); + + if (json) + { + ResponseAppend_P(PSTR(",\"BL6523\":{")); + ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str); + ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str); + ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str); + ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str); + ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str); + ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str); + ResponseJsonEnd(); +#ifdef USE_DOMOTICZ + if (0 == TasmotaGlobal.tele_period) + { + DomoticzSensor(DZ_CURRENT, amps_str); // Amps + DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage + DomoticzSensor(DZ_COUNT, freq_str); // Frequency + DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts + DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor + DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } + else + { + WSContentSend_PD(HTTP_BL6523_SNM); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns96(uint8_t function) +{ + bool result = false; + + if (Bl6523.type) + { + switch (function) + { + case FUNC_EVERY_250_MSECOND: + Bl6523Update(); + break; + case FUNC_JSON_APPEND: + Bl6523Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Bl6523Show(0); + break; +#endif // USE_WEBSERVER + case FUNC_INIT: + Bl6523Init(); + break; + } + } + return result; +} + +#endif // USE_BL6523 \ No newline at end of file From 73e3b4447758065b6cef47a194d0966aae57ed4c Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Tue, 15 Feb 2022 20:41:25 +1100 Subject: [PATCH 2/8] Converted BL6523 to nrg driver --- tasmota/tasmota_template.h | 6 + tasmota/xnrg_22_bl6523.ino | 355 +++++++++++++++++++++++++++++++++++++ 2 files changed, 361 insertions(+) create mode 100644 tasmota/xnrg_22_bl6523.ino diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 7af28acd4..fc57e9825 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -183,6 +183,7 @@ enum UserSelectablePins { GPIO_SDM230_TX, GPIO_SDM230_RX, // SDM230 Serial interface GPIO_ADC_MQ, // Analog MQ Sensor GPIO_CM11_TXD, GPIO_CM11_RXD, // CM11 Serial interface + GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -405,6 +406,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_SDM230_TX "|" D_SENSOR_SDM230_RX "|" D_SENSOR_ADC_MQ "|" D_SENSOR_CM11_TX "|" D_SENSOR_CM11_RX "|" + D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -772,6 +774,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface #endif +#ifdef USE_BL6523 + AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface + AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface +#endif #endif // USE_ENERGY_SENSOR /*-------------------------------------------------------------------------------------------*\ diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino new file mode 100644 index 000000000..98b39780f --- /dev/null +++ b/tasmota/xnrg_22_bl6523.ino @@ -0,0 +1,355 @@ +/* + xsns_96_bl6523.ino - Chinese bl6523 based Watt hour meter support for Tasmota + + Copyright (C) 2022 Jeevas Vasudevan and the Internet + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#ifdef USE_ENERGY_SENSOR +#ifdef USE_BL6523 +/*********************************************************************************************\ + * Chinese BL6523 based Watt hour meter + * + * 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_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} +\*********************************************************************************************/ + +#define XNRG_22 22 + +#include + +#define BL6523_RX_DATASET_SIZE 2 +#define BL6523_TX_DATASET_SIZE 4 + +#define BL6523_BAUD 4800 +#define BL6523_REG_AMPS 0x05 +#define BL6523_REG_VOLTS 0x07 +#define BL6523_REG_FREQ 0x09 +#define BL6523_REG_WATTS 0x0A +#define BL6523_REG_POWF 0x08 +#define BL6523_REG_WATTHR 0x0C + +/* No idea how to derive human readable units from the byte stream. +For now dividing the 24-bit values with below constants seems to yield something sane +that matches whatever displayed in the screen of my 240v model. Probably it would be possible +to extract these values from the write register commands (0xCA).*/ +#define BL6523_DIV_AMPS 297899.4f +#define BL6523_DIV_VOLTS 13304.0f +#define BL6523_DIV_FREQ 3907.0f +#define BL6523_DIV_WATTS 707.0f +#define BL6523_DIV_WATTHR 674.0f + +TasmotaSerial *Bl6523RxSerial; +TasmotaSerial *Bl6523TxSerial; + +struct BL6523 +{ + uint32_t amps = 0; + uint32_t volts = 0; + uint32_t freq = 0; + uint32_t watts = 0; + uint32_t powf = 0; + uint32_t watthr = 0; + + uint8_t type = 1; + uint8_t valid = 0; + uint8_t got_data_stone = 0; + bool discovery_triggered = false; +} Bl6523; + +bool Bl6523ReadData(void) +{ + + if (!Bl6523RxSerial->available()) + { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " )); + return false; + } + + while ((Bl6523RxSerial->peek() != 0x35) && Bl6523RxSerial->available()) + { + Bl6523RxSerial->read(); + } + + if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE) + { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " )); + return false; + } + + uint8_t rx_buffer[BL6523_RX_DATASET_SIZE]; + Bl6523RxSerial->readBytes(rx_buffer, BL6523_RX_DATASET_SIZE); + Bl6523RxSerial->flush(); // Make room for another burst + + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE); + + while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE) + { + // sleep till TX buffer is full + unsigned long timeout = millis() + 10; + while (millis() < timeout) {} + } + + + 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++) + { + crc += tx_buffer[i]; //Add Data_L,Data_M and Data_H to Addr + } + crc &= 0xff; // Bitwise AND 0xFF + crc = ~crc; // Invert the byte + if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1]) + { + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE)); + 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 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) +*/ + + /* READ DATA (format: command(read->0x35) address data_low data_mid data_high checksum ) +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 08 TX: 00 00 00 F7 (PF) +RX: 35 0C TX: 00 00 00 F3 (WATT_HR) +*/ + +switch(rx_buffer[1]) { + case BL6523_REG_AMPS : + Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<0; + break; + case BL6523_REG_VOLTS : + Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<1; + break; + case BL6523_REG_FREQ : + Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<2; + break; + case BL6523_REG_WATTS : + Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<3; + break; + case BL6523_REG_POWF : + Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<4; + break; + case BL6523_REG_WATTHR : + Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); + Bl6523.got_data_stone |= 1<<5; + break; + default : + break; +} + +AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr); + + if (!Bl6523.discovery_triggered) + { + TasmotaGlobal.discovery_counter = 1; // force TasDiscovery() + Bl6523.discovery_triggered = true; + } + return true; + +} + +/*********************************************************************************************/ + +void Bl6523Update(void) +{ // Every 250 millisecond + if (Bl6523ReadData()) + { + Bl6523.valid = 60; + } + else + { + if (Bl6523.valid) { + Bl6523.valid--; + } + } +} + +/*********************************************************************************************/ + +void Bl6523Init(void) +{ + Bl6523.type = 0; + if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX))) + { + Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1); + Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1); + if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD))) + { + if (Bl6523RxSerial->hardwareSerial()) + { + ClaimSerial(); + } + if (Bl6523TxSerial->hardwareSerial()) + { + ClaimSerial(); + } + Bl6523.type = 1; + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " )); + } + } +} + +#ifdef USE_WEBSERVER +const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = , {e} = +const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = , {e} = +#endif // USE_WEBSERVER + +void Bl6523Show(bool json) +{ + uint32_t powf_word = 0; + float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0.0f; + char amps_str[12], volts_str[12], freq_str[12]; + char watts_str[12], powf_str[12], watthr_str[12]; + + if (Bl6523.valid) + { + + amps = (float)Bl6523.amps / BL6523_DIV_AMPS; + volts = (float)Bl6523.volts / BL6523_DIV_VOLTS; + freq = (float)Bl6523.freq / BL6523_DIV_FREQ; + watts = (float)Bl6523.watts / BL6523_DIV_WATTS; + + /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。) + Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5 + */ + powf = 0.0f; + powf_word = (Bl6523.powf >> 23) ? ~(Bl6523.powf & 0x7fffff) : Bl6523.powf & 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_word = powf_word & (0x7fffff >> (1+i)); + } + powf = (Bl6523.powf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set + + watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR; + + ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s); + ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts); + ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq); + ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts); + ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf); + ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr); + + if (json) + { + ResponseAppend_P(PSTR(",\"BL6523\":{")); + ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str); + ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str); + ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str); + ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str); + ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str); + ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str); + ResponseJsonEnd(); +#ifdef USE_DOMOTICZ + if (0 == TasmotaGlobal.tele_period) + { + DomoticzSensor(DZ_CURRENT, amps_str); // Amps + DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage + DomoticzSensor(DZ_COUNT, freq_str); // Frequency + DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts + DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor + DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } + else + { + WSContentSend_PD(HTTP_BL6523_SNM); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str); + WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg22(uint8_t function) +{ + bool result = false; + +if ( FUNC_INIT == function ) +{ + Bl6523Init(); +} +else if ( Bl6523.type ) + { + switch (function) + { + case FUNC_EVERY_250_MSECOND: + Bl6523Update(); + break; + case FUNC_JSON_APPEND: + Bl6523Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Bl6523Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_BL6523 +#endif // USE_ENERGY_SENSOR \ No newline at end of file From 6a7cb4f95e79869827f15a0b5102810145c5a558 Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Tue, 15 Feb 2022 21:03:30 +1100 Subject: [PATCH 3/8] Squashed commit of the following: commit 1dc0638bbe4901efbe2c0bacefbcc32dac08e8ea Author: jeevasdev Date: Tue Feb 15 20:37:14 2022 +1100 Converted to xnrg as per review comment. commit fa5570b0980e4bff1773a72eb417d8853f5c9e8e Author: jeevasdev Date: Tue Feb 15 13:46:50 2022 +1100 Added helper message to main comment. commit bf7864fb56885161a19855a2ae92fe8a9348a8be Author: jeevasdev Date: Tue Feb 15 13:43:45 2022 +1100 Added BL6523 language files. commit 0920d5c530b8253c12e436437b2954913ef1126d Author: jeevasdev Date: Tue Feb 15 13:34:34 2022 +1100 Added BL6523 to tasmota_template. commit e119fc8a044e47179169b0caa7f1e31d099b4932 Author: jeevasdev Date: Tue Feb 15 13:28:38 2022 +1100 Add BL6523 based smartmeter support main ino. --- tasmota/xsns_96_bl6523.ino | 353 ------------------------------------- 1 file changed, 353 deletions(-) delete mode 100644 tasmota/xsns_96_bl6523.ino diff --git a/tasmota/xsns_96_bl6523.ino b/tasmota/xsns_96_bl6523.ino deleted file mode 100644 index 7587a897f..000000000 --- a/tasmota/xsns_96_bl6523.ino +++ /dev/null @@ -1,353 +0,0 @@ -/* - xsns_96_bl6523.ino - Chinese bl6523 based Watt hour meter support for Tasmota - - Copyright (C) 2022 Jeevas Vasudevan and the Internet - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_BL6523 -/*********************************************************************************************\ - * Chinese BL6523 based Watt hour meter - * - * 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_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} -\*********************************************************************************************/ - -#define XSNS_96 96 - -#include - -#define BL6523_RX_DATASET_SIZE 2 -#define BL6523_TX_DATASET_SIZE 4 - -#define BL6523_BAUD 4800 -#define BL6523_REG_AMPS 0x05 -#define BL6523_REG_VOLTS 0x07 -#define BL6523_REG_FREQ 0x09 -#define BL6523_REG_WATTS 0x0A -#define BL6523_REG_POWF 0x08 -#define BL6523_REG_WATTHR 0x0C - -/* No idea how to derive human readable units from the byte stream. -For now dividing the 24-bit values with below constants seems to yield something sane -that matches whatever displayed in the screen of my 240v model. Probably it would be possible -to extract these values from the write register commands (0xCA).*/ -#define BL6523_DIV_AMPS 297899.4f -#define BL6523_DIV_VOLTS 13304.0f -#define BL6523_DIV_FREQ 3907.0f -#define BL6523_DIV_WATTS 707.0f -#define BL6523_DIV_WATTHR 674.0f - -TasmotaSerial *Bl6523RxSerial; -TasmotaSerial *Bl6523TxSerial; - -struct BL6523 -{ - uint32_t amps = 0; - uint32_t volts = 0; - uint32_t freq = 0; - uint32_t watts = 0; - uint32_t powf = 0; - uint32_t watthr = 0; - - uint8_t type = 1; - uint8_t valid = 0; - uint8_t got_data_stone = 0; - bool discovery_triggered = false; -} Bl6523; - -bool Bl6523ReadData(void) -{ - - if (!Bl6523RxSerial->available()) - { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " )); - return false; - } - - while ((Bl6523RxSerial->peek() != 0x35) && Bl6523RxSerial->available()) - { - Bl6523RxSerial->read(); - } - - if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE) - { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " )); - return false; - } - - uint8_t rx_buffer[BL6523_RX_DATASET_SIZE]; - Bl6523RxSerial->readBytes(rx_buffer, BL6523_RX_DATASET_SIZE); - Bl6523RxSerial->flush(); // Make room for another burst - - AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE); - - while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE) - { - // sleep till TX buffer is full - unsigned long timeout = millis() + 10; - while (millis() < timeout) {} - } - - - 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++) - { - crc += tx_buffer[i]; //Add Data_L,Data_M and Data_H to Addr - } - crc &= 0xff; // Bitwise AND 0xFF - crc = ~crc; // Invert the byte - if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1]) - { - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE)); - 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 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) -*/ - - /* READ DATA (format: command(read->0x35) address data_low data_mid data_high checksum ) -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 08 TX: 00 00 00 F7 (PF) -RX: 35 0C TX: 00 00 00 F3 (WATT_HR) -*/ - -switch(rx_buffer[1]) { - case BL6523_REG_AMPS : - Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<0; - break; - case BL6523_REG_VOLTS : - Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<1; - break; - case BL6523_REG_FREQ : - Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<2; - break; - case BL6523_REG_WATTS : - Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<3; - break; - case BL6523_REG_POWF : - Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<4; - break; - case BL6523_REG_WATTHR : - Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<5; - break; - default : - break; -} - -AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr); - - if (!Bl6523.discovery_triggered) - { - TasmotaGlobal.discovery_counter = 1; // force TasDiscovery() - Bl6523.discovery_triggered = true; - } - return true; - -} - -/*********************************************************************************************/ - -void Bl6523Update(void) -{ // Every 250 millisecond - if (Bl6523ReadData()) - { - Bl6523.valid = 60; - } - else - { - if (Bl6523.valid) { - Bl6523.valid--; - } - } -} - -/*********************************************************************************************/ - -void Bl6523Init(void) -{ - Bl6523.type = 0; - if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX))) - { - Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1); - Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1); - if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD))) - { - if (Bl6523RxSerial->hardwareSerial()) - { - ClaimSerial(); - } - if (Bl6523TxSerial->hardwareSerial()) - { - ClaimSerial(); - } - Bl6523.type = 1; - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " )); - } - } -} - -#ifdef USE_WEBSERVER -const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = , {e} = -const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = , {e} = -#endif // USE_WEBSERVER - -void Bl6523Show(bool json) -{ - uint32_t powf_word = 0; - float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0 .0f; - char amps_str[12], volts_str[12], freq_str[12]; - char watts_str[12], powf_str[12], watthr_str[12]; - - if (Bl6523.valid) - { - - amps = (float)Bl6523.amps / BL6523_DIV_AMPS; - volts = (float)Bl6523.volts / BL6523_DIV_VOLTS; - freq = (float)Bl6523.freq / BL6523_DIV_FREQ; - watts = (float)Bl6523.watts / BL6523_DIV_WATTS; - - /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。) - Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5 - */ - powf = 0.0f; - powf_word = Bl6523.powf & 0x7fffff; //Extract the 23 bits - for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits - powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1)))); - powf_word = powf_word & (0x7fffff >> (1+i)); - } - powf = (Bl6523.powf >> 23) ? (0.0f - (~powf)) : powf; // Negate if sign bit(24) is set - - watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR; - - ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s); - ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts); - ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq); - ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts); - ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf); - ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr); - - if (json) - { - ResponseAppend_P(PSTR(",\"BL6523\":{")); - ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str); - ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str); - ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str); - ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str); - ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str); - ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str); - ResponseJsonEnd(); -#ifdef USE_DOMOTICZ - if (0 == TasmotaGlobal.tele_period) - { - DomoticzSensor(DZ_CURRENT, amps_str); // Amps - DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage - DomoticzSensor(DZ_COUNT, freq_str); // Frequency - DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts - DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor - DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour - } -#endif // USE_DOMOTICZ -#ifdef USE_WEBSERVER - } - else - { - WSContentSend_PD(HTTP_BL6523_SNM); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str); -#endif // USE_WEBSERVER - } - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xsns96(uint8_t function) -{ - bool result = false; - - if (Bl6523.type) - { - switch (function) - { - case FUNC_EVERY_250_MSECOND: - Bl6523Update(); - break; - case FUNC_JSON_APPEND: - Bl6523Show(1); - break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - Bl6523Show(0); - break; -#endif // USE_WEBSERVER - case FUNC_INIT: - Bl6523Init(); - break; - } - } - return result; -} - -#endif // USE_BL6523 \ No newline at end of file From f2bd57c5e6915a7f63f495aed0fb8641b64b32ba Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Wed, 16 Feb 2022 02:32:29 +1100 Subject: [PATCH 4/8] NRG sensor rewrite. --- tasmota/tasmota_template.h | 6 -- tasmota/xnrg_22_bl6523.ino | 162 +++++++++++-------------------------- 2 files changed, 49 insertions(+), 119 deletions(-) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index fc57e9825..3c2ab3902 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -172,7 +172,6 @@ enum UserSelectablePins { GPIO_MCP2515_CS, // MCP2515 Chip Select GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface - GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2) GPIO_BL0942_RX, // BL0942 Serial interface GPIO_HM330X_SET, // HM330X SET pin (sleep when low) @@ -395,7 +394,6 @@ const char kSensorNames[] PROGMEM = D_SENSOR_MCP2515_CS "|" D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|" D_SENSOR_VINDRIKTNING_RX "|" - D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|" D_SENSOR_BL0939_RX "|" D_SENSOR_BL0942_RX "|" D_SENSOR_HM330X_SET "|" @@ -820,10 +818,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_VINDRIKTNING AGPIO(GPIO_VINDRIKTNING_RX), #endif -#ifdef USE_BL6523 - AGPIO(GPIO_BL6523_TX), - AGPIO(GPIO_BL6523_RX), -#endif #ifdef USE_HM330X AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) #endif diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino index 98b39780f..28d7e2f0c 100644 --- a/tasmota/xnrg_22_bl6523.ino +++ b/tasmota/xnrg_22_bl6523.ino @@ -36,7 +36,8 @@ * BL6523 GND -> ESP GND * * To build add the below to user_config_override.h - * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸ + * #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} @@ -57,6 +58,8 @@ #define BL6523_REG_POWF 0x08 #define BL6523_REG_WATTHR 0x0C +#define SINGLE_PHASE 0 + /* No idea how to derive human readable units from the byte stream. For now dividing the 24-bit values with below constants seems to yield something sane that matches whatever displayed in the screen of my 240v model. Probably it would be possible @@ -72,13 +75,6 @@ TasmotaSerial *Bl6523TxSerial; struct BL6523 { - uint32_t amps = 0; - uint32_t volts = 0; - uint32_t freq = 0; - uint32_t watts = 0; - uint32_t powf = 0; - uint32_t watthr = 0; - uint8_t type = 1; uint8_t valid = 0; uint8_t got_data_stone = 0; @@ -87,6 +83,8 @@ struct BL6523 bool Bl6523ReadData(void) { + uint32_t powf_word = 0, powf_buf = 0; + float powf = 0.0f; if (!Bl6523RxSerial->available()) { @@ -163,35 +161,39 @@ RX: 35 0C TX: 00 00 00 F3 (WATT_HR) switch(rx_buffer[1]) { case BL6523_REG_AMPS : - Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<0; + Energy.current[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_AMPS; // 1.260 A break; case BL6523_REG_VOLTS : - Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<1; + Energy.voltage[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_VOLTS; // 230.2 V break; case BL6523_REG_FREQ : - Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<2; + Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_FREQ; // 50.0 Hz break; case BL6523_REG_WATTS : - Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<3; + Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_WATTS; // -196.3 W break; case BL6523_REG_POWF : - Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<4; + /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。) + Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5 + */ + powf = 0.0f; + 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_word = powf_word & (0x7fffff >> (1+i)); + } + powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set + Energy.power_factor[SINGLE_PHASE] = powf; break; case BL6523_REG_WATTHR : - Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); - Bl6523.got_data_stone |= 1<<5; + Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_WATTHR; // 6.216 kWh => used in EnergyUpdateTotal() break; default : break; } - -AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr); - + Energy.data_valid[SINGLE_PHASE] = 0; + EnergyUpdateTotal(); if (!Bl6523.discovery_triggered) { TasmotaGlobal.discovery_counter = 1; // force TasDiscovery() @@ -221,9 +223,8 @@ void Bl6523Update(void) void Bl6523Init(void) { - Bl6523.type = 0; - if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX))) - { + + Bl6523.type = 0; Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1); Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1); if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD))) @@ -237,86 +238,29 @@ void Bl6523Init(void) ClaimSerial(); } Bl6523.type = 1; + Energy.phase_count = 1; AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " )); } - } + else + { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Failure! " )); + TasmotaGlobal.energy_driver = ENERGY_NONE; + } + } -#ifdef USE_WEBSERVER -const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = , {e} = -const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = , {e} = -#endif // USE_WEBSERVER - -void Bl6523Show(bool json) +void Bl6523DrvInit(void) { - uint32_t powf_word = 0; - float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0.0f; - char amps_str[12], volts_str[12], freq_str[12]; - char watts_str[12], powf_str[12], watthr_str[12]; - - if (Bl6523.valid) - { - - amps = (float)Bl6523.amps / BL6523_DIV_AMPS; - volts = (float)Bl6523.volts / BL6523_DIV_VOLTS; - freq = (float)Bl6523.freq / BL6523_DIV_FREQ; - watts = (float)Bl6523.watts / BL6523_DIV_WATTS; - - /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。) - Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5 - */ - powf = 0.0f; - powf_word = (Bl6523.powf >> 23) ? ~(Bl6523.powf & 0x7fffff) : Bl6523.powf & 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_word = powf_word & (0x7fffff >> (1+i)); - } - powf = (Bl6523.powf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set - - watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR; - - ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s); - ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts); - ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq); - ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts); - ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf); - ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr); - - if (json) - { - ResponseAppend_P(PSTR(",\"BL6523\":{")); - ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str); - ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str); - ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str); - ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str); - ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str); - ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str); - ResponseJsonEnd(); -#ifdef USE_DOMOTICZ - if (0 == TasmotaGlobal.tele_period) - { - DomoticzSensor(DZ_CURRENT, amps_str); // Amps - DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage - DomoticzSensor(DZ_COUNT, freq_str); // Frequency - DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts - DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor - DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour - } -#endif // USE_DOMOTICZ -#ifdef USE_WEBSERVER - } - else - { - WSContentSend_PD(HTTP_BL6523_SNM); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str); - WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str); -#endif // USE_WEBSERVER - } + if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Success " )); + TasmotaGlobal.energy_driver = XNRG_22; } + else + { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Failure! " )); + TasmotaGlobal.energy_driver = ENERGY_NONE; + } + } /*********************************************************************************************\ @@ -327,27 +271,19 @@ bool Xnrg22(uint8_t function) { bool result = false; -if ( FUNC_INIT == function ) -{ - Bl6523Init(); -} -else if ( Bl6523.type ) - { switch (function) { case FUNC_EVERY_250_MSECOND: Bl6523Update(); break; - case FUNC_JSON_APPEND: - Bl6523Show(1); + case FUNC_INIT: + Bl6523Init(); break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - Bl6523Show(0); + case FUNC_PRE_INIT: + Bl6523DrvInit(); break; -#endif // USE_WEBSERVER } - } + return result; } From a5e840ff5e36bb3200906edccb2470c284f16bb5 Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Wed, 16 Feb 2022 03:04:28 +1100 Subject: [PATCH 5/8] Trim Log messages. --- tasmota/xnrg_22_bl6523.ino | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino index 28d7e2f0c..a2d09d0bb 100644 --- a/tasmota/xnrg_22_bl6523.ino +++ b/tasmota/xnrg_22_bl6523.ino @@ -88,7 +88,7 @@ bool Bl6523ReadData(void) if (!Bl6523RxSerial->available()) { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " )); + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:No Rx Data available" )); return false; } @@ -99,7 +99,7 @@ bool Bl6523ReadData(void) if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE) { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " )); + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Rx less than expected" )); return false; } @@ -134,7 +134,7 @@ bool Bl6523ReadData(void) crc = ~crc; // Invert the byte if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1]) { - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE)); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE)); Bl6523TxSerial->flush(); Bl6523RxSerial->flush(); return false; @@ -239,11 +239,11 @@ void Bl6523Init(void) } Bl6523.type = 1; Energy.phase_count = 1; - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " )); + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Success" )); } else { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Failure! " )); + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" )); TasmotaGlobal.energy_driver = ENERGY_NONE; } @@ -252,12 +252,12 @@ void Bl6523Init(void) void Bl6523DrvInit(void) { if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Success " )); + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Success" )); TasmotaGlobal.energy_driver = XNRG_22; } else { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Failure! " )); + AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" )); TasmotaGlobal.energy_driver = ENERGY_NONE; } From 97ceb7d6ae9f74a9737c1beee999e296b9ecb062 Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Thu, 17 Feb 2022 00:01:27 +1100 Subject: [PATCH 6/8] Add support for Settings for calibration constants --- tasmota/xnrg_22_bl6523.ino | 91 +++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino index a2d09d0bb..458568dcc 100644 --- a/tasmota/xnrg_22_bl6523.ino +++ b/tasmota/xnrg_22_bl6523.ino @@ -64,11 +64,17 @@ For now dividing the 24-bit values with below constants seems to yield something sane that matches whatever displayed in the screen of my 240v model. Probably it would be possible to extract these values from the write register commands (0xCA).*/ -#define BL6523_DIV_AMPS 297899.4f -#define BL6523_DIV_VOLTS 13304.0f -#define BL6523_DIV_FREQ 3907.0f -#define BL6523_DIV_WATTS 707.0f -#define BL6523_DIV_WATTHR 674.0f +//#define BL6523_DIV_AMPS 297899.4f +//#define BL6523_DIV_VOLTS 13304.0f +//#define BL6523_DIV_FREQ 3907.0f +//#define BL6523_DIV_WATTS 707.0f +//#define BL6523_DIV_WATTHR 674.0f + +#define BL6523_IREF 297899 +#define BL6523_UREF 13304 +#define BL6523_FREF 3907 +#define BL6523_PREF 707 +#define BL6523_PWHRREF_D 33 // Substract this from BL6523_PREF to get WattHr Div. TasmotaSerial *Bl6523RxSerial; TasmotaSerial *Bl6523TxSerial; @@ -161,16 +167,16 @@ RX: 35 0C TX: 00 00 00 F3 (WATT_HR) switch(rx_buffer[1]) { case BL6523_REG_AMPS : - Energy.current[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_AMPS; // 1.260 A + Energy.current[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_current_calibration; // 1.260 A break; case BL6523_REG_VOLTS : - Energy.voltage[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_VOLTS; // 230.2 V + Energy.voltage[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_voltage_calibration; // 230.2 V break; case BL6523_REG_FREQ : - Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_FREQ; // 50.0 Hz + Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_frequency_calibration; // 50.0 Hz break; case BL6523_REG_WATTS : - Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_WATTS; // -196.3 W + 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; case BL6523_REG_POWF : /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。) @@ -187,7 +193,7 @@ switch(rx_buffer[1]) { Energy.power_factor[SINGLE_PHASE] = powf; break; case BL6523_REG_WATTHR : - Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_WATTHR; // 6.216 kWh => used in EnergyUpdateTotal() + 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; @@ -249,11 +255,73 @@ void Bl6523Init(void) } +bool Bl6523Command(void) { + bool serviced = true; + + int32_t value = (int32_t)(CharToFloat(XdrvMailbox.data) * 1000); // 1.234 = 1234, -1.234 = -1234 + uint32_t abs_value = abs(value) / 10; // 1.23 = 123, -1.23 = 123 + + if ((CMND_POWERCAL == Energy.command_code) || (CMND_VOLTAGECAL == Energy.command_code) || (CMND_CURRENTCAL == Energy.command_code)) { + // Service in xdrv_03_energy.ino + } + 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; + } + } + } + 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; + } + } + } + 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; + } + } + } + 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; + } + } + } + else if (CMND_ENERGYCONFIG == Energy.command_code) { + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Config index %d, payload %d, value %d, data '%s'"), + XdrvMailbox.index, XdrvMailbox.payload, value, XdrvMailbox.data ? XdrvMailbox.data : "null" ); + + // EnergyConfig1 to 3 = Set Energy.current[channel] in A like 0.417 for 417mA + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index < 4)) { + //Bl6523.current[XdrvMailbox.index -1] = value; + } + // EnergyConfig4 to 6 = Set Energy.active_power[channel] in W like 100 for 100W + if ((XdrvMailbox.index > 3) && (XdrvMailbox.index < 7)) { + //Bl6523.power[XdrvMailbox.index -4] = value; + } + } + else serviced = false; // Unknown command + + return serviced; +} + void Bl6523DrvInit(void) { if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) { AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Success" )); TasmotaGlobal.energy_driver = XNRG_22; + if (HLW_PREF_PULSE == Settings->energy_power_calibration) { + Settings->energy_frequency_calibration = BL6523_FREF; + Settings->energy_voltage_calibration = BL6523_UREF; + Settings->energy_current_calibration = BL6523_IREF; + Settings->energy_power_calibration = BL6523_PREF; + } + } else { @@ -276,6 +344,9 @@ bool Xnrg22(uint8_t function) case FUNC_EVERY_250_MSECOND: Bl6523Update(); break; + case FUNC_COMMAND: + result = Bl6523Command(); + break; case FUNC_INIT: Bl6523Init(); break; From 42e259bad05dc49fee2efe53f445f727f4b93fae Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Thu, 17 Feb 2022 00:33:11 +1100 Subject: [PATCH 7/8] Abort after waiting for 1s and changed to delay() --- tasmota/xnrg_22_bl6523.ino | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino index 458568dcc..6d58459f2 100644 --- a/tasmota/xnrg_22_bl6523.ino +++ b/tasmota/xnrg_22_bl6523.ino @@ -59,16 +59,7 @@ #define BL6523_REG_WATTHR 0x0C #define SINGLE_PHASE 0 - -/* No idea how to derive human readable units from the byte stream. -For now dividing the 24-bit values with below constants seems to yield something sane -that matches whatever displayed in the screen of my 240v model. Probably it would be possible -to extract these values from the write register commands (0xCA).*/ -//#define BL6523_DIV_AMPS 297899.4f -//#define BL6523_DIV_VOLTS 13304.0f -//#define BL6523_DIV_FREQ 3907.0f -//#define BL6523_DIV_WATTS 707.0f -//#define BL6523_DIV_WATTHR 674.0f +#define RX_WAIT 100 #define BL6523_IREF 297899 #define BL6523_UREF 13304 @@ -89,7 +80,7 @@ struct BL6523 bool Bl6523ReadData(void) { - uint32_t powf_word = 0, powf_buf = 0; + uint32_t powf_word = 0, powf_buf = 0, i = 0; float powf = 0.0f; if (!Bl6523RxSerial->available()) @@ -115,11 +106,14 @@ bool Bl6523ReadData(void) AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE); + i=0; while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE) { // sleep till TX buffer is full - unsigned long timeout = millis() + 10; - while (millis() < timeout) {} + delay(10); + if ( i++ > RX_WAIT ){ + abort(); + } } From ef3fb678a41b444d29c20689547c9f5bbc6f2227 Mon Sep 17 00:00:00 2001 From: jeevasdev Date: Thu, 17 Feb 2022 00:42:22 +1100 Subject: [PATCH 8/8] break when the case breaks :) --- tasmota/xnrg_22_bl6523.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino index 6d58459f2..b25d5bc68 100644 --- a/tasmota/xnrg_22_bl6523.ino +++ b/tasmota/xnrg_22_bl6523.ino @@ -112,7 +112,7 @@ bool Bl6523ReadData(void) // sleep till TX buffer is full delay(10); if ( i++ > RX_WAIT ){ - abort(); + break; } }