diff --git a/lib/TasmotaModbus-1.0.0/README.md b/lib/TasmotaModbus-1.1.0/README.md similarity index 100% rename from lib/TasmotaModbus-1.0.0/README.md rename to lib/TasmotaModbus-1.1.0/README.md diff --git a/lib/TasmotaModbus-1.0.0/examples/modbustest/modbustest.ino b/lib/TasmotaModbus-1.1.0/examples/modbustest/modbustest.ino similarity index 100% rename from lib/TasmotaModbus-1.0.0/examples/modbustest/modbustest.ino rename to lib/TasmotaModbus-1.1.0/examples/modbustest/modbustest.ino diff --git a/lib/TasmotaModbus-1.0.0/keywords.txt b/lib/TasmotaModbus-1.1.0/keywords.txt similarity index 100% rename from lib/TasmotaModbus-1.0.0/keywords.txt rename to lib/TasmotaModbus-1.1.0/keywords.txt diff --git a/lib/TasmotaModbus-1.0.0/library.json b/lib/TasmotaModbus-1.1.0/library.json similarity index 93% rename from lib/TasmotaModbus-1.0.0/library.json rename to lib/TasmotaModbus-1.1.0/library.json index 06028d38b..d983bec32 100644 --- a/lib/TasmotaModbus-1.0.0/library.json +++ b/lib/TasmotaModbus-1.1.0/library.json @@ -1,6 +1,6 @@ { "name": "TasmotaModbus", - "version": "1.0.0", + "version": "1.1.0", "keywords": [ "serial", "io", "TasmotaModbus" ], diff --git a/lib/TasmotaModbus-1.0.0/library.properties b/lib/TasmotaModbus-1.1.0/library.properties similarity index 93% rename from lib/TasmotaModbus-1.0.0/library.properties rename to lib/TasmotaModbus-1.1.0/library.properties index f7bcfcd1a..bb42fb372 100644 --- a/lib/TasmotaModbus-1.0.0/library.properties +++ b/lib/TasmotaModbus-1.1.0/library.properties @@ -1,5 +1,5 @@ name=TasmotaModbus -version=1.0.0 +version=1.1.0 author=Theo Arends maintainer=Theo Arends sentence=Basic modbus wrapper for TasmotaSerial for ESP8266. diff --git a/lib/TasmotaModbus-1.0.0/src/TasmotaModbus.cpp b/lib/TasmotaModbus-1.1.0/src/TasmotaModbus.cpp similarity index 83% rename from lib/TasmotaModbus-1.0.0/src/TasmotaModbus.cpp rename to lib/TasmotaModbus-1.1.0/src/TasmotaModbus.cpp index d242d83a7..0be2c9de3 100644 --- a/lib/TasmotaModbus-1.0.0/src/TasmotaModbus.cpp +++ b/lib/TasmotaModbus-1.1.0/src/TasmotaModbus.cpp @@ -21,10 +21,7 @@ TasmotaModbus::TasmotaModbus(int receive_pin, int transmit_pin) : TasmotaSerial(receive_pin, transmit_pin, 1) { -} - -TasmotaModbus::~TasmotaModbus() -{ + mb_address = 0; } uint16_t CalculateCRC(uint8_t *frame, uint8_t num) @@ -46,11 +43,11 @@ uint16_t CalculateCRC(uint8_t *frame, uint8_t num) return crc; } -int TasmotaModbus::Begin(long speed) +int TasmotaModbus::Begin(long speed, int stop_bits) { int result = 0; - if (begin(speed)) { + if (begin(speed, stop_bits)) { result = 1; if (hardwareSerial()) { result = 2; } } @@ -61,7 +58,9 @@ void TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint16_t { uint8_t frame[8]; - frame[0] = device_address; // 0xFE default device address or dedicated like 0x01 + mb_address = device_address; // Save address for receipt check + + frame[0] = mb_address; // 0xFE default device address or dedicated like 0x01 frame[1] = function_code; frame[2] = (uint8_t)(start_address >> 8); frame[3] = (uint8_t)(start_address); @@ -85,10 +84,17 @@ uint8_t TasmotaModbus::ReceiveBuffer(uint8_t *buffer, uint8_t register_count) uint8_t len = 0; uint32_t last = millis(); while ((available() > 0) && (len < (register_count *2) + 5) && (millis() - last < 10)) { - buffer[len++] = (uint8_t)read(); - if (3 == len) { - if (buffer[1] & 0x80) { // fe 84 02 f2 f1 - return buffer[2]; // 1 = Illegal Function, 2 = Illegal Address, 3 = Illegal Data, 4 = Slave Error + uint8_t data = (uint8_t)read(); + if (!len) { // Skip leading data as provided by hardware serial + if (mb_address == data) { + buffer[len++] = data; + } + } else { + buffer[len++] = data; + if (3 == len) { + if (buffer[1] & 0x80) { // 01 84 02 f2 f1 + return buffer[2]; // 1 = Illegal Function, 2 = Illegal Address, 3 = Illegal Data, 4 = Slave Error + } } } last = millis(); diff --git a/lib/TasmotaModbus-1.0.0/src/TasmotaModbus.h b/lib/TasmotaModbus-1.1.0/src/TasmotaModbus.h similarity index 92% rename from lib/TasmotaModbus-1.0.0/src/TasmotaModbus.h rename to lib/TasmotaModbus-1.1.0/src/TasmotaModbus.h index 664a66b42..5176aa89e 100644 --- a/lib/TasmotaModbus-1.0.0/src/TasmotaModbus.h +++ b/lib/TasmotaModbus-1.1.0/src/TasmotaModbus.h @@ -28,9 +28,9 @@ class TasmotaModbus : public TasmotaSerial { public: TasmotaModbus(int receive_pin, int transmit_pin); - ~TasmotaModbus(); + virtual ~TasmotaModbus() {} - int Begin(long speed = TM_MODBUS_BAUDRATE); + int Begin(long speed = TM_MODBUS_BAUDRATE, int stop_bits = 1); void Send(uint8_t device_address, uint8_t function_code, uint16_t start_address, uint16_t register_count); @@ -49,6 +49,9 @@ class TasmotaModbus : public TasmotaSerial { uint8_t ReceiveBuffer(uint8_t *buffer, uint8_t register_count); uint8_t Receive16BitRegister(uint16_t *value); uint8_t Receive32BitRegister(float *value); + + private: + uint8_t mb_address; }; #endif // TasmotaModbus_h diff --git a/lib/TasmotaSerial-2.0.0/README.md b/lib/TasmotaSerial-2.1.0/README.md similarity index 100% rename from lib/TasmotaSerial-2.0.0/README.md rename to lib/TasmotaSerial-2.1.0/README.md diff --git a/lib/TasmotaSerial-2.0.0/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-2.1.0/examples/swsertest/swsertest.ino similarity index 100% rename from lib/TasmotaSerial-2.0.0/examples/swsertest/swsertest.ino rename to lib/TasmotaSerial-2.1.0/examples/swsertest/swsertest.ino diff --git a/lib/TasmotaSerial-2.0.0/keywords.txt b/lib/TasmotaSerial-2.1.0/keywords.txt similarity index 100% rename from lib/TasmotaSerial-2.0.0/keywords.txt rename to lib/TasmotaSerial-2.1.0/keywords.txt diff --git a/lib/TasmotaSerial-2.0.0/library.json b/lib/TasmotaSerial-2.1.0/library.json similarity index 94% rename from lib/TasmotaSerial-2.0.0/library.json rename to lib/TasmotaSerial-2.1.0/library.json index 00a2a9e0f..59d06ad5f 100644 --- a/lib/TasmotaSerial-2.0.0/library.json +++ b/lib/TasmotaSerial-2.1.0/library.json @@ -1,6 +1,6 @@ { "name": "TasmotaSerial", - "version": "2.0.0", + "version": "2.1.0", "keywords": [ "serial", "io", "TasmotaSerial" ], diff --git a/lib/TasmotaSerial-2.0.0/library.properties b/lib/TasmotaSerial-2.1.0/library.properties similarity index 94% rename from lib/TasmotaSerial-2.0.0/library.properties rename to lib/TasmotaSerial-2.1.0/library.properties index b250399b9..93f4a1d39 100644 --- a/lib/TasmotaSerial-2.0.0/library.properties +++ b/lib/TasmotaSerial-2.1.0/library.properties @@ -1,5 +1,5 @@ name=TasmotaSerial -version=2.0.0 +version=2.1.0 author=Theo Arends maintainer=Theo Arends sentence=Implementation of software serial with hardware serial fallback for ESP8266. diff --git a/lib/TasmotaSerial-2.0.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-2.1.0/src/TasmotaSerial.cpp similarity index 91% rename from lib/TasmotaSerial-2.0.0/src/TasmotaSerial.cpp rename to lib/TasmotaSerial-2.1.0/src/TasmotaSerial.cpp index cbd2a3523..d9fc29e6f 100644 --- a/lib/TasmotaSerial-2.0.0/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-2.1.0/src/TasmotaSerial.cpp @@ -80,6 +80,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, bool hardware_fa { m_valid = false; m_hardserial = 0; + m_stop_bits = 1; if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) { return; } @@ -106,15 +107,33 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, bool hardware_fa m_valid = true; } +TasmotaSerial::~TasmotaSerial() +{ + if (!m_hardserial) { + if (m_rx_pin > -1) { + detachInterrupt(m_rx_pin); + tms_obj_list[m_rx_pin] = NULL; + if (m_buffer) { + free(m_buffer); + } + } + } +} + bool TasmotaSerial::isValidGPIOpin(int pin) { return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15); } -bool TasmotaSerial::begin(long speed) { +bool TasmotaSerial::begin(long speed, int stop_bits) { + m_stop_bits = ((stop_bits -1) &1) +1; if (m_hardserial) { Serial.flush(); - Serial.begin(speed, SERIAL_8N1); + if (2 == m_stop_bits) { + Serial.begin(speed, SERIAL_8N2); + } else { + Serial.begin(speed, SERIAL_8N1); + } } else { // Use getCycleCount() loop to get as exact timing as possible m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed; @@ -195,9 +214,11 @@ size_t TasmotaSerial::write(uint8_t b) TM_SERIAL_WAIT; b >>= 1; } - // Stop bit - digitalWrite(m_tx_pin, HIGH); - TM_SERIAL_WAIT; + // Stop bit(s) + for (int i = 0; i < m_stop_bits; i++) { + digitalWrite(m_tx_pin, HIGH); + TM_SERIAL_WAIT; + } if (m_high_speed) sei(); return 1; } @@ -220,8 +241,12 @@ void TasmotaSerial::rxRead() rec >>= 1; if (digitalRead(m_rx_pin)) rec |= 0x80; } - // Stop bit + // Stop bit(s) TM_SERIAL_WAIT; + if (2 == m_stop_bits) { + digitalRead(m_rx_pin); + TM_SERIAL_WAIT; + } // Store the received value in the buffer unless we have an overflow int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE; if (next != (int)m_out_pos) { diff --git a/lib/TasmotaSerial-2.0.0/src/TasmotaSerial.h b/lib/TasmotaSerial-2.1.0/src/TasmotaSerial.h similarity index 95% rename from lib/TasmotaSerial-2.0.0/src/TasmotaSerial.h rename to lib/TasmotaSerial-2.1.0/src/TasmotaSerial.h index d4c993368..e40c34ee8 100644 --- a/lib/TasmotaSerial-2.0.0/src/TasmotaSerial.h +++ b/lib/TasmotaSerial-2.1.0/src/TasmotaSerial.h @@ -33,12 +33,15 @@ #define TM_SERIAL_USE_IRAM // Enable to use iram (+368 bytes) #endif +#include #include class TasmotaSerial : public Stream { public: TasmotaSerial(int receive_pin, int transmit_pin, bool hardware_fallback = false); - bool begin(long speed); + virtual ~TasmotaSerial(); + + bool begin(long speed, int stop_bits = 1); bool begin(); bool hardwareSerial(); int peek(); @@ -62,6 +65,7 @@ class TasmotaSerial : public Stream { bool m_high_speed; int m_rx_pin; int m_tx_pin; + int m_stop_bits; unsigned long m_bit_time; unsigned int m_in_pos; unsigned int m_out_pos; diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index e7ce596bf..36de9f29c 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,10 @@ -/* 6.2.1.16 20181015 +/* 6.2.1.17 20181017 + * Enable updated non-blocking PubSubClient as default MQTT client + * Update TasmotaModbus and TasmotaSerial libraries for support of serial 8N2 communication + * Add support for Pzem-003/017 DC Energy monitoring module (#3694) + * Change support for Pzem-014/016 AC Energy monitoring module (#3694) + * + * 6.2.1.16 20181015 * Add TasmotaModbus library for very basic modbus wrapper for TasmotaSerial * Change xsns_17_senseair.ino to use TasmotaModbus library * Fix xnrg_05_pzem2.ino for PZEM-014/016 support using TasmotaModbus library (#3694) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index a7d3fca7d..c485b79ff 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 2886b130f..ab548ad70 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 299e8207a..19cbff44b 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRRecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 2f320211d..c0873dd07 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index ad3762f8d..eed796889 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index b57985803..cf34dbce9 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IR RX" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 7e1098bed..b70cbbb8b 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "RécptIR" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index c6aec9681..736ea89aa 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 857cfec12..b33e4cc41 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRvevő" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 6b922cb4d..e819c8558 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index eb938970d..eef55f90a 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 0b6a07e7d..a99b9e972 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index f4c556ed9..fa8caec36 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHz Rx" #define D_SENSOR_MHZ_TX "MHz Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAIR Rx" #define D_SENSOR_SAIR_TX "SAIR Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index f79f7a14c..ae2ee4316 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index 4cea913e6..61c2c2f08 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index b24a355d8..1f542af3b 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 93b5f32cd..1b075a4b6 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 42a381f18..63f687f3e 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 92193f483..89222d077 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -482,8 +482,10 @@ #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_PZEM_RX "PZEM Rx" -#define D_SENSOR_PZEM_TX "PZEM Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" #define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SPI_CS "SPI CS" diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 627110ca3..3db21b48f 100755 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -136,7 +136,8 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor #undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor #undef USE_PZEM004T // Disable PZEM004T energy sensor -#undef USE_PZEM2 // Disable PZEM003,014,016,017 Energy monitor +#undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor +#undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor #undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 359466884..b7d591801 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -86,8 +86,8 @@ enum UserSelectablePins { GPIO_LED4_INV, GPIO_MHZ_TXD, // MH-Z19 Serial interface GPIO_MHZ_RXD, // MH-Z19 Serial interface - GPIO_PZEM_TX, // PZEM004T Serial interface - GPIO_PZEM_RX, // PZEM004T Serial interface + GPIO_PZEM0XX_TX, // PZEM0XX Serial interface + GPIO_PZEM004_RX, // PZEM004T Serial interface GPIO_SAIR_TX, // SenseAir Serial interface GPIO_SAIR_RX, // SenseAir Serial interface GPIO_SPI_CS, // SPI Chip Select @@ -122,8 +122,8 @@ enum UserSelectablePins { GPIO_CNTR2_NP, GPIO_CNTR3_NP, GPIO_CNTR4_NP, - GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface - GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface + GPIO_PZEM016_RX, // PZEM-014,016 Serial Modbus interface + GPIO_PZEM017_RX, // PZEM-003,017 Serial Modbus interface GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface GPIO_HX711_SCK, // HX711 Load Cell clock @@ -168,7 +168,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_LED "1|" D_SENSOR_LED "2|" D_SENSOR_LED "3|" D_SENSOR_LED "4|" D_SENSOR_LED "1i|" D_SENSOR_LED "2i|" D_SENSOR_LED "3i|" D_SENSOR_LED "4i|" D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|" - D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" + D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|" D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1_RX "|" @@ -180,7 +180,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_SWITCH "1n|" D_SENSOR_SWITCH "2n|" D_SENSOR_SWITCH "3n|" D_SENSOR_SWITCH "4n|" D_SENSOR_SWITCH "5n|" D_SENSOR_SWITCH "6n|" D_SENSOR_SWITCH "7n|" D_SENSOR_SWITCH "8n|" D_SENSOR_BUTTON "1n|" D_SENSOR_BUTTON "2n|" D_SENSOR_BUTTON "3n|" D_SENSOR_BUTTON "4n|" D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|" - D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" + D_SENSOR_PZEM016_RX "|" D_SENSOR_PZEM017_RX "|" D_SENSOR_DFR562 "|" D_SENSOR_SDS0X1_TX "|" D_SENSOR_HX711_SCK "|" D_SENSOR_HX711_DAT; @@ -354,10 +354,10 @@ const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = { GPIO_SAIR_RX, // SenseAir Serial interface GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface - GPIO_PZEM_TX, // PZEM004T Serial interface - GPIO_PZEM_RX, // PZEM004T Serial interface - GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface - GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface + GPIO_PZEM0XX_TX, // PZEM0XX Serial interface + GPIO_PZEM004_RX, // PZEM004T Serial interface + GPIO_PZEM016_RX, // PZEM-014,016 Serial Modbus interface + GPIO_PZEM017_RX, // PZEM-003,017 Serial Modbus interface GPIO_SDM120_TX, // SDM120 Serial interface GPIO_SDM120_RX, // SDM120 Serial interface GPIO_SDM630_TX, // SDM630 Serial interface diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 5c81a8b16..1ee95769f 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020110 +#define VERSION 0x06020111 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support.ino b/sonoff/support.ino index aa50e9cf2..a18de8667 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -647,14 +647,22 @@ boolean GetUsedInModule(byte val, uint8_t *arr) if (GPIO_MHZ_TXD == val) { return true; } if (GPIO_MHZ_RXD == val) { return true; } #endif + + int pzem = 3; #ifndef USE_PZEM004T - if (GPIO_PZEM_TX == val) { return true; } - if (GPIO_PZEM_RX == val) { return true; } + pzem--; + if (GPIO_PZEM004_RX == val) { return true; } #endif -#ifndef USE_PZEM2 - if (GPIO_PZEM2_TX == val) { return true; } - if (GPIO_PZEM2_RX == val) { return true; } +#ifndef USE_PZEM_AC + pzem--; + if (GPIO_PZEM016_RX == val) { return true; } #endif +#ifndef USE_PZEM_DC + pzem--; + if (GPIO_PZEM017_RX == val) { return true; } +#endif + if (!pzem && (GPIO_PZEM0XX_TX == val)) { return true; } + #ifndef USE_SENSEAIR if (GPIO_SAIR_TX == val) { return true; } if (GPIO_SAIR_RX == val) { return true; } @@ -1166,14 +1174,17 @@ void GetFeatures() #ifdef USE_MCP39F501 feature_sns2 |= 0x00000100; // xnrg_04_mcp39f501.ino #endif -#ifdef USE_PZEM2 - feature_sns2 |= 0x00000200; // xnrg_05_pzem2.ino +#ifdef USE_PZEM_AC + feature_sns2 |= 0x00000200; // xnrg_05_pzem_ac.ino #endif #ifdef USE_DS3231 feature_sns2 |= 0x00000400; // xsns_33_ds3231.ino #endif #ifdef USE_HX711 - feature_sns2 |= 0x00000400; // xsns_34_hx711.ino + feature_sns2 |= 0x00000800; // xsns_34_hx711.ino +#endif +#ifdef USE_PZEM_DC + feature_sns2 |= 0x00001000; // xnrg_06_pzem_dc.ino #endif } diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 1cd393017..1d66a92c4 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -220,11 +220,11 @@ * Select ONE of possible MQTT library types below \*-------------------------------------------------------------------------------------------*/ // Default MQTT driver for both non-TLS and TLS connections. Latest library version (20181016) does not block network if MQTT server is unavailable. -//#define MQTT_LIBRARY_TYPE MQTT_PUBSUBCLIENT // Use PubSubClient library +#define MQTT_LIBRARY_TYPE MQTT_PUBSUBCLIENT // Use PubSubClient library // Alternative MQTT driver does not block network when MQTT server is unavailable. No TLS support //#define MQTT_LIBRARY_TYPE MQTT_TASMOTAMQTT // Use TasmotaMqtt library (+4k4 (core 2.3.0), +14k4 (core 2.4.2 lwip2) code, +4k mem) - non-TLS only // Alternative MQTT driver does not block network when MQTT server is unavailable. TLS should work but needs to be tested. -#define MQTT_LIBRARY_TYPE MQTT_ARDUINOMQTT // Use arduino-mqtt (lwmqtt) library (+3k3 code, +2k mem) +//#define MQTT_LIBRARY_TYPE MQTT_ARDUINOMQTT // Use arduino-mqtt (lwmqtt) library (+3k3 code, +2k mem) // -- MQTT ---------------------------------------- #define MQTT_TELE_RETAIN 0 // Tele messages may send retain flag (0 = off, 1 = on) @@ -356,7 +356,8 @@ // Power monitoring sensors ----------------------- #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) -#define USE_PZEM2 // Add support for PZEM003,014,016,017 Energy monitor (+1k1 code) +#define USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code) +#define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) #define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) // -- Low level interface devices ----------------- diff --git a/sonoff/xnrg_03_pzem004t.ino b/sonoff/xnrg_03_pzem004t.ino index 3dfbc3879..dae285b01 100644 --- a/sonoff/xnrg_03_pzem004t.ino +++ b/sonoff/xnrg_03_pzem004t.ino @@ -25,7 +25,7 @@ * Source: Victor Ferrer https://github.com/vicfergar/Sonoff-MQTT-OTA-Arduino * Based on: PZEM004T library https://github.com/olehs/PZEM004T * - * Hardware Serial will be selected if GPIO1 = [PZEM Rx] and [GPIO3 = PZEM Tx] + * Hardware Serial will be selected if GPIO1 = [63 PZEM004 Rx] and GPIO3 = [62 PZEM0XX Tx] \*********************************************************************************************/ #define XNRG_03 3 @@ -203,7 +203,7 @@ void PzemEvery200ms() void PzemSnsInit() { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions - PzemSerial = new TasmotaSerial(pin[GPIO_PZEM_RX], pin[GPIO_PZEM_TX], 1); + PzemSerial = new TasmotaSerial(pin[GPIO_PZEM004_RX], pin[GPIO_PZEM0XX_TX], 1); if (PzemSerial->begin(9600)) { if (PzemSerial->hardwareSerial()) { ClaimSerial(); } } else { @@ -214,7 +214,7 @@ void PzemSnsInit() void PzemDrvInit() { if (!energy_flg) { - if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX] < 99)) { // Any device with a Pzem004T + if ((pin[GPIO_PZEM004_RX] < 99) && (pin[GPIO_PZEM0XX_TX] < 99)) { // Any device with a Pzem004T energy_flg = XNRG_03; } } diff --git a/sonoff/xnrg_05_pzem2.ino b/sonoff/xnrg_05_pzem2.ino deleted file mode 100644 index 2c9b35b50..000000000 --- a/sonoff/xnrg_05_pzem2.ino +++ /dev/null @@ -1,162 +0,0 @@ -/* - xnrg_06_pzem2.ino - PZEM-003,017 and PZEM-014,016 Modbus energy sensor support for Sonoff-Tasmota - - Copyright (C) 2018 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_ENERGY_SENSOR -#ifdef USE_PZEM2 -/*********************************************************************************************\ - * PZEM-003 - DC 300V 10A Energy - * PZEM-014 - AC 220V 10A Energy - * PZEM-016 - AC 220V 100A Energy - * PZEM-017 - DC 300V 50A - 300A Energy - * - * Based on: - * PZEM-003,017 docs Https://pan.baidu.com/s/1V9bDWj3RK2u6_fbBJ3GtqQ password rq37 - * PZEM-014,016 docs https://pan.baidu.com/s/1B0MdMgURyjtO1oQa2lavKw password ytkv - * - * Hardware Serial will be selected if GPIO1 = [99 PZEM Rx] and GPIO3 = [98 PZEM Tx] -\*********************************************************************************************/ - -#define XNRG_05 5 - -#define PZEM2_MODBUS_SPEED 9600 -#define PZEM2_DEVICE_ADDRESS 0x01 // PZEM default address -#define PZEM2_READ_RESULT 0x04 // Command Read result - -#define PZEM2_TYPES_003_017 8 // Result 8 x 16 bit register count -#define PZEM2_TYPES_014_016 10 // Result 10 x 16 bit register count - -#include -TasmotaModbus *Pzem2Modbus; - -uint8_t pzem2_type = PZEM2_TYPES_014_016; -uint8_t pzem2_sendRetry = 0; - -void Pzem2EverySecond() -{ - bool data_ready = Pzem2Modbus->ReceiveReady(); - - if (data_ready) { - uint8_t buffer[26]; - - uint8_t error = Pzem2Modbus->ReceiveBuffer(buffer, pzem2_type); - AddLogSerial(LOG_LEVEL_DEBUG_MORE, buffer, (buffer[2]) ? buffer[2] +5 : sizeof(buffer)); - - if (error) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "PZEM2 response error %d"), error); - AddLog(LOG_LEVEL_DEBUG); -// if (9 == error) { -/* - if (PZEM2_TYPES_014_016 == pzem2_type) { - pzem2_type = PZEM2_TYPES_003_017; - } else { - pzem2_type = PZEM2_TYPES_014_016; - } -*/ -// } - } else { - float energy = 0; - - if (PZEM2_TYPES_003_017 == pzem2_type) { - energy_type_dc = true; - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - // 01 04 10 27 10 00 64 03 E8 00 00 00 00 00 00 00 00 00 00 HH LL = PZEM-017 - // Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc-- - energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V - energy_current = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A - energy_active_power = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W - energy = (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh - if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any - energy_kWhtoday += (energy - energy_start) * 100; - energy_start = energy; - EnergyUpdateToday(); - } - else if (PZEM2_TYPES_014_016 == pzem2_type) { // PZEM-014,016 - energy_type_dc = false; - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - // 01 04 14 08 D1 00 6C 00 00 00 F4 00 00 00 26 00 00 01 F4 00 64 00 00 51 34 = PZEM-014 - // Id Cc Sz Volt- Current---- Power------ Energy----- Frequ PFact Alarm Crc-- - energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 6553.0 V - energy_current = (float)((buffer[7] << 24) + (buffer[8] << 16) + (buffer[5] << 8) + buffer[6]) / 1000.0; // 4294967.000 A - energy_active_power = (float)((buffer[11] << 24) + (buffer[12] << 16) + (buffer[9] << 8) + buffer[10]) / 10.0; // 429496729.0 W - energy_frequency = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz - energy_power_factor = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00 - energy = (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh - if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any - energy_kWhtoday += (energy - energy_start) * 100; - energy_start = energy; - EnergyUpdateToday(); - } - } - } - - if (0 == pzem2_sendRetry || data_ready) { - pzem2_sendRetry = 5; - Pzem2Modbus->Send(PZEM2_DEVICE_ADDRESS, PZEM2_READ_RESULT, 0, pzem2_type); - } - else { - pzem2_sendRetry--; - } -} - -void Pzem2SnsInit() -{ - Pzem2Modbus = new TasmotaModbus(pin[GPIO_PZEM2_RX], pin[GPIO_PZEM2_TX]); - uint8_t result = Pzem2Modbus->Begin(PZEM2_MODBUS_SPEED); - if (result) { - if (2 == result) { ClaimSerial(); } - } else { - energy_flg = ENERGY_NONE; - } -} - -void Pzem2DrvInit() -{ - if (!energy_flg) { - if ((pin[GPIO_PZEM2_RX] < 99) && (pin[GPIO_PZEM2_TX] < 99)) { // Any device with a Pzem-003,014,016,017 - energy_flg = XNRG_05; - } - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -int Xnrg05(byte function) -{ - int result = 0; - - if (FUNC_PRE_INIT == function) { - Pzem2DrvInit(); - } - else if (XNRG_05 == energy_flg) { - switch (function) { - case FUNC_INIT: - Pzem2SnsInit(); - break; - case FUNC_EVERY_SECOND: - Pzem2EverySecond(); - break; - } - } - return result; -} - -#endif // USE_PZEM2 -#endif // USE_ENERGY_SENSOR diff --git a/sonoff/xnrg_05_pzem_ac.ino b/sonoff/xnrg_05_pzem_ac.ino new file mode 100644 index 000000000..ca2262bb5 --- /dev/null +++ b/sonoff/xnrg_05_pzem_ac.ino @@ -0,0 +1,126 @@ +/* + xnrg_05_pzem_ac.ino - PZEM-014,016 Modbus AC energy sensor support for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ENERGY_SENSOR +#ifdef USE_PZEM_AC +/*********************************************************************************************\ + * PZEM-014 - AC 220V 10A Energy + * PZEM-016 - AC 220V 100A Energy + * + * Based on: + * PZEM-014,016 docs https://pan.baidu.com/s/1B0MdMgURyjtO1oQa2lavKw password ytkv + * + * Hardware Serial will be selected if GPIO1 = [98 PZEM016 Rx] and GPIO3 = [62 PZEM0XX Tx] +\*********************************************************************************************/ + +#define XNRG_05 5 + +#define PZEM_AC_DEVICE_ADDRESS 0x01 // PZEM default address + +#include +TasmotaModbus *PzemAcModbus; + +void PzemAcEverySecond() +{ + static uint8_t send_retry = 0; + + bool data_ready = PzemAcModbus->ReceiveReady(); + + if (data_ready) { + uint8_t buffer[26]; + + uint8_t error = PzemAcModbus->ReceiveBuffer(buffer, 10); + AddLogSerial(LOG_LEVEL_DEBUG_MORE, buffer, (buffer[2]) ? buffer[2] +5 : sizeof(buffer)); + + if (error) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "PzemAc response error %d"), error); + AddLog(LOG_LEVEL_DEBUG); + } else { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 + // 01 04 14 08 D1 00 6C 00 00 00 F4 00 00 00 26 00 00 01 F4 00 64 00 00 51 34 + // Id Cc Sz Volt- Current---- Power------ Energy----- Frequ PFact Alarm Crc-- + energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 6553.0 V + energy_current = (float)((buffer[7] << 24) + (buffer[8] << 16) + (buffer[5] << 8) + buffer[6]) / 1000.0; // 4294967.000 A + energy_active_power = (float)((buffer[11] << 24) + (buffer[12] << 16) + (buffer[9] << 8) + buffer[10]) / 10.0; // 429496729.0 W + energy_frequency = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz + energy_power_factor = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00 + float energy = (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh + + if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any + energy_kWhtoday += (energy - energy_start) * 100; + energy_start = energy; + EnergyUpdateToday(); + } + } + + if (0 == send_retry || data_ready) { + send_retry = 5; + PzemAcModbus->Send(PZEM_AC_DEVICE_ADDRESS, 0x04, 0, 10); + } + else { + send_retry--; + } +} + +void PzemAcSnsInit() +{ + PzemAcModbus = new TasmotaModbus(pin[GPIO_PZEM016_RX], pin[GPIO_PZEM0XX_TX]); + uint8_t result = PzemAcModbus->Begin(9600); + if (result) { + if (2 == result) { ClaimSerial(); } + } else { + energy_flg = ENERGY_NONE; + } +} + +void PzemAcDrvInit() +{ + if (!energy_flg) { + if ((pin[GPIO_PZEM016_RX] < 99) && (pin[GPIO_PZEM0XX_TX] < 99)) { + energy_flg = XNRG_05; + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +int Xnrg05(byte function) +{ + int result = 0; + + if (FUNC_PRE_INIT == function) { + PzemAcDrvInit(); + } + else if (XNRG_05 == energy_flg) { + switch (function) { + case FUNC_INIT: + PzemAcSnsInit(); + break; + case FUNC_EVERY_SECOND: + PzemAcEverySecond(); + break; + } + } + return result; +} + +#endif // USE_PZEM_AC +#endif // USE_ENERGY_SENSOR diff --git a/sonoff/xnrg_06_pzem_dc.ino b/sonoff/xnrg_06_pzem_dc.ino new file mode 100644 index 000000000..b7a693bef --- /dev/null +++ b/sonoff/xnrg_06_pzem_dc.ino @@ -0,0 +1,125 @@ +/* + xnrg_06_pzem_dc.ino - PZEM-003,017 Modbus DC energy sensor support for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ENERGY_SENSOR +#ifdef USE_PZEM_DC +/*********************************************************************************************\ + * PZEM-003 - DC 300V 10A Energy + * PZEM-017 - DC 300V 50A - 300A Energy + * + * Based on: + * PZEM-003,017 docs Https://pan.baidu.com/s/1V9bDWj3RK2u6_fbBJ3GtqQ password rq37 + * + * Hardware Serial will be selected if GPIO1 = [99 PZEM017 Rx] and GPIO3 = [62 PZEM0XX Tx] +\*********************************************************************************************/ + +#define XNRG_06 6 + +#define PZEM_DC_DEVICE_ADDRESS 0x01 // PZEM default address + +#include +TasmotaModbus *PzemDcModbus; + +void PzemDcEverySecond() +{ + static uint8_t send_retry = 0; + + bool data_ready = PzemDcModbus->ReceiveReady(); + + if (data_ready) { + uint8_t buffer[22]; + + uint8_t error = PzemDcModbus->ReceiveBuffer(buffer, 8); + AddLogSerial(LOG_LEVEL_DEBUG_MORE, buffer, (buffer[2]) ? buffer[2] +5 : sizeof(buffer)); + + if (error) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "PzemDc response error %d"), error); + AddLog(LOG_LEVEL_DEBUG); + } else { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + // 01 04 10 05 40 00 0A 00 0D 00 00 00 02 00 00 00 00 00 00 D6 29 + // Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc-- + energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V + energy_current = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A + energy_active_power = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W + float energy = (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh + + if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any + energy_kWhtoday += (energy - energy_start) * 100; + energy_start = energy; + EnergyUpdateToday(); + } + } + + if (0 == send_retry || data_ready) { + send_retry = 5; + PzemDcModbus->Send(PZEM_DC_DEVICE_ADDRESS, 0x04, 0, 8); + } + else { + send_retry--; + } +} + +void PzemDcSnsInit() +{ + PzemDcModbus = new TasmotaModbus(pin[GPIO_PZEM017_RX], pin[GPIO_PZEM0XX_TX]); + uint8_t result = PzemDcModbus->Begin(9600, 2); // Uses two stop bits!! + if (result) { + if (2 == result) { ClaimSerial(); } + energy_type_dc = true; + } else { + energy_flg = ENERGY_NONE; + } +} + +void PzemDcDrvInit() +{ + if (!energy_flg) { + if ((pin[GPIO_PZEM017_RX] < 99) && (pin[GPIO_PZEM0XX_TX] < 99)) { + energy_flg = XNRG_06; + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +int Xnrg06(byte function) +{ + int result = 0; + + if (FUNC_PRE_INIT == function) { + PzemDcDrvInit(); + } + else if (XNRG_06 == energy_flg) { + switch (function) { + case FUNC_INIT: + PzemDcSnsInit(); + break; + case FUNC_EVERY_SECOND: + PzemDcEverySecond(); + break; + } + } + return result; +} + +#endif // USE_PZEM_DC +#endif // USE_ENERGY_SENSOR diff --git a/sonoff/xnrg_interface.ino b/sonoff/xnrg_interface.ino index d9726ac05..9af865f26 100644 --- a/sonoff/xnrg_interface.ino +++ b/sonoff/xnrg_interface.ino @@ -39,7 +39,15 @@ int (* const xnrg_func_ptr[])(byte) PROGMEM = { // Energy driver Function Poin #endif #ifdef XNRG_06 - &Xnrg06 + &Xnrg06, +#endif + +#ifdef XNRG_07 + &Xnrg07, +#endif + +#ifdef XNRG_08 + &Xnrg08 #endif }; diff --git a/tools/decode-status.py b/tools/decode-status.py index 4fe1c285b..e9da483b3 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -127,8 +127,8 @@ a_features = [[ ],[ "USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050", "USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766", - "USE_MCP39F501","USE_PZEM2","USE_DS3231","USE_HX711", - "","","","", + "USE_MCP39F501","USE_PZEM_AC","USE_DS3231","USE_HX711", + "USE_PZEM_DC","","","", "","","","", "","","","", "","","","",