Hi, I try to use modbus master/slave but it seem that it fail to read the modbus. There is only one time that it succeed to read the modbus.
this is my coding
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
////////////Blynk Virtual Pin Assignment
#define vPIN_VOLTAGE_1 V11
#define vPIN_CURRENT_USAGE_1 V12
#define vPIN_ACTIVE_POWER_1 V13
#define vPIN_ACTIVE_ENERGY_1 V14
#define vPIN_FREQUENCY_1 V15
#define vPIN_POWER_FACTOR_1 V16
#define vPIN_OVER_POWER_ALARM_1 V17
#define vPIN_VOLTAGE_2 V21
#define vPIN_CURRENT_USAGE_2 V22
#define vPIN_ACTIVE_POWER_2 V23
#define vPIN_ACTIVE_ENERGY_2 V24
#define vPIN_FREQUENCY_2 V25
#define vPIN_POWER_FACTOR_2 V26
#define vPIN_OVER_POWER_ALARM_2 V27
////////////Blynk Virtual Pin Assignment End
/////////SET PIN
#include <SoftwareSerial.h> // ( NODEMCU ESP8266 )
SoftwareSerial pzemSerial(D5, D6); // (RX,TX) NodeMCU connect to (TX,RX) of PZEM
////////
static uint8_t pzemSlave1Addr = 0x01;
static uint8_t pzemSlave2Addr = 0x02;
ModbusMaster node1;
ModbusMaster node2;
BlynkTimer timer;
double voltage_usage_1 = 0;
double current_usage_1 = 0;
double active_power_1 = 0;
double active_energy_1 = 0;
double frequency_1 = 0;
double power_factor_1 = 0;
double over_power_alarm_1 = 0;
double voltage_usage_2 = 0;
double current_usage_2 = 0;
double active_power_2 = 0;
double active_energy_2 = 0;
double frequency_2 = 0;
double power_factor_2 = 0;
double over_power_alarm_2 = 0;
#define BLYNK_AUTH_TOKEN "" //Enter your blynk auth token
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = ""; //Enter your WIFi name
char pass[] = ""; //Enter your WIFI password
void setup() {
Serial.begin(115200);
WiFi.setSleepMode(WIFI_NONE_SLEEP);
pzemSerial.begin(9600);
//// start Modbus/RS-485 serial communication
node1.begin(pzemSlave1Addr, pzemSerial);
node2.begin(pzemSlave2Addr, pzemSerial);
//changeAddress(0x01, 0x03); //uncomment to set pzem address. You can press reset button on nodemcu if this function is not called
//resetEnergy(0x01);
Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
timer.setInterval(10000L, sendtoBlynk); // send values blynk server every 10 sec
//delay(1000);
}
void sendtoBlynk() {
Blynk.virtualWrite(vPIN_VOLTAGE_1, voltage_usage_1);
Blynk.virtualWrite(vPIN_CURRENT_USAGE_1, current_usage_1);
Blynk.virtualWrite(vPIN_ACTIVE_POWER_1, active_power_1);
Blynk.virtualWrite(vPIN_ACTIVE_ENERGY_1, active_energy_1);
Blynk.virtualWrite(vPIN_FREQUENCY_1, frequency_1);
Blynk.virtualWrite(vPIN_POWER_FACTOR_1, power_factor_1);
Blynk.virtualWrite(vPIN_OVER_POWER_ALARM_1, over_power_alarm_1);
Blynk.virtualWrite(vPIN_VOLTAGE_2, voltage_usage_2);
Blynk.virtualWrite(vPIN_CURRENT_USAGE_2, current_usage_2);
Blynk.virtualWrite(vPIN_ACTIVE_POWER_2, active_power_2);
Blynk.virtualWrite(vPIN_ACTIVE_ENERGY_2, active_energy_2);
Blynk.virtualWrite(vPIN_FREQUENCY_2, frequency_2);
Blynk.virtualWrite(vPIN_POWER_FACTOR_2, power_factor_2);
Blynk.virtualWrite(vPIN_OVER_POWER_ALARM_2, over_power_alarm_2);
}
void pzemdevice1()
{
// PZEM Device 1 data fetching
Serial.println("====================================================");
Serial.println("Now checking Modbus 1");
uint8_t result1;
ESP.wdtDisable(); //disable watchdog during modbus read or else ESP crashes when no slave connected
result1 = node1.readInputRegisters(0x0000, 10);
ESP.wdtEnable(1); //enable watchdog during modbus read
if (result1 == node1.ku8MBSuccess)
{
voltage_usage_1 = (node1.getResponseBuffer(0x00) / 10.0f);
current_usage_1 = (node1.getResponseBuffer(0x01) / 1000.000f);
active_power_1 = (node1.getResponseBuffer(0x03) / 10.0f);
active_energy_1 = (node1.getResponseBuffer(0x05) / 1000.0f);
frequency_1 = (node1.getResponseBuffer(0x07) / 10.0f);
power_factor_1 = (node1.getResponseBuffer(0x08) / 100.0f);
over_power_alarm_1 = (node1.getResponseBuffer(0x09));
Serial.println("Modbus 1 Data");
Serial.print("VOLTAGE: "); Serial.println(voltage_usage_1); // V
Serial.print("CURRENT_USAGE: "); Serial.println(current_usage_1, 3); // A
Serial.print("ACTIVE_POWER: "); Serial.println(active_power_1); // W
Serial.print("ACTIVE_ENERGY: "); Serial.println(active_energy_1, 3); // kWh
Serial.print("FREQUENCY: "); Serial.println(frequency_1); // Hz
Serial.print("POWER_FACTOR: "); Serial.println(power_factor_1);
Serial.print("OVER_POWER_ALARM: "); Serial.println(over_power_alarm_1, 0);
Serial.println("====================================================");
}
else {
Serial.println("Failed to read modbus 1");
}
}
void pzemdevice2()
{
// PZEM Device 2 data fetching
Serial.println("====================================================");
Serial.println("Now checking Modbus 2");
uint8_t result2;
ESP.wdtDisable();
result2 = node2.readInputRegisters(0x0000, 10);
ESP.wdtEnable(1);
if (result2 == node2.ku8MBSuccess)
{
voltage_usage_2 = (node2.getResponseBuffer(0x00) / 10.0f);
current_usage_2 = (node2.getResponseBuffer(0x01) / 1000.000f);
active_power_2 = (node2.getResponseBuffer(0x03) / 10.0f);
active_energy_2 = (node2.getResponseBuffer(0x05) / 1000.0f);
frequency_2 = (node2.getResponseBuffer(0x07) / 10.0f);
power_factor_2 = (node2.getResponseBuffer(0x08) / 100.0f);
over_power_alarm_2 = (node2.getResponseBuffer(0x09));
Serial.println("Modbus 2 Data");
Serial.print("VOLTAGE: "); Serial.println(voltage_usage_2); // V
Serial.print("CURRENT_USAGE: "); Serial.println(current_usage_2, 3); // A
Serial.print("ACTIVE_POWER: "); Serial.println(active_power_2); // W
Serial.print("ACTIVE_ENERGY: "); Serial.println(active_energy_2, 3); // kWh
Serial.print("FREQUENCY: "); Serial.println(frequency_2); // Hz
Serial.print("POWER_FACTOR: "); Serial.println(power_factor_2);
Serial.print("OVER_POWER_ALARM: "); Serial.println(over_power_alarm_2, 0);
Serial.println("====================================================");
}
else {
Serial.println("Failed to read modbus 2");
//delay(6000);
}
}
void resetEnergy(uint8_t slaveAddr) {
//The command to reset the slave's energy is (total 4 bytes):
//Slave address + 0x42 + CRC check high byte + CRC check low byte.
uint16_t u16CRC = 0xFFFF;
static uint8_t resetCommand = 0x42;
u16CRC = crc16_update(u16CRC, slaveAddr);
u16CRC = crc16_update(u16CRC, resetCommand);
Serial.println("Resetting Energy");
pzemSerial.write(slaveAddr);
pzemSerial.write(resetCommand);
pzemSerial.write(lowByte(u16CRC));
pzemSerial.write(highByte(u16CRC));
delay(1000);
}
//function to change/assign pzem address
void changeAddress(uint8_t OldslaveAddr, uint8_t NewslaveAddr)
{
static uint8_t SlaveParameter = 0x06;
static uint16_t registerAddress = 0x0002; // Register address to be changed
uint16_t u16CRC = 0xFFFF;
u16CRC = crc16_update(u16CRC, OldslaveAddr);
u16CRC = crc16_update(u16CRC, SlaveParameter);
u16CRC = crc16_update(u16CRC, highByte(registerAddress));
u16CRC = crc16_update(u16CRC, lowByte(registerAddress));
u16CRC = crc16_update(u16CRC, highByte(NewslaveAddr));
u16CRC = crc16_update(u16CRC, lowByte(NewslaveAddr));
Serial.println("Changing Slave Address");
pzemSerial.write(OldslaveAddr);
pzemSerial.write(SlaveParameter);
pzemSerial.write(highByte(registerAddress));
pzemSerial.write(lowByte(registerAddress));
pzemSerial.write(highByte(NewslaveAddr));
pzemSerial.write(lowByte(NewslaveAddr));
pzemSerial.write(lowByte(u16CRC));
pzemSerial.write(highByte(u16CRC));
delay(1000);
}
void loop() {
Blynk.run();
timer.run();
pzemdevice1();
pzemdevice2();
delay(1000);
}
I refer the coding from here "GitHub - pkarun/Blynk-PZEM-004T-v3.0-Multiple-device: Blynk ESP8266 (NodeMCU) Program to connect multiple PZEM 004T v3.0 Power Meter."
This is the result displayed on the serial monitor. Only that one time it gives value/
Please help me to understand why this happen and how can I solve it.