mirror of https://github.com/arendst/Tasmota.git
6.2.1.17 Changes and Adds
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)
This commit is contained in:
parent
b2ca987195
commit
0ab43909c3
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "TasmotaModbus",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"keywords": [
|
||||
"serial", "io", "TasmotaModbus"
|
||||
],
|
|
@ -1,5 +1,5 @@
|
|||
name=TasmotaModbus
|
||||
version=1.0.0
|
||||
version=1.1.0
|
||||
author=Theo Arends
|
||||
maintainer=Theo Arends <theo@arends.com>
|
||||
sentence=Basic modbus wrapper for TasmotaSerial for ESP8266.
|
|
@ -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();
|
|
@ -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
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "TasmotaSerial",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"keywords": [
|
||||
"serial", "io", "TasmotaSerial"
|
||||
],
|
|
@ -1,5 +1,5 @@
|
|||
name=TasmotaSerial
|
||||
version=2.0.0
|
||||
version=2.1.0
|
||||
author=Theo Arends
|
||||
maintainer=Theo Arends <theo@arends.com>
|
||||
sentence=Implementation of software serial with hardware serial fallback for ESP8266.
|
|
@ -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) {
|
|
@ -33,12 +33,15 @@
|
|||
#define TM_SERIAL_USE_IRAM // Enable to use iram (+368 bytes)
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <Stream.h>
|
||||
|
||||
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;
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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 -----------------
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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.h>
|
||||
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
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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.h>
|
||||
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
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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.h>
|
||||
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
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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","","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
|
|
Loading…
Reference in New Issue