I am using the following code to read multiple register values from a meter. Issue is sometimes I get the correct response and sometimes it return invalid slave id. I am using a bluepill with a xy-107 rs485 module.
#include <ModbusMaster.h>
uint16_t registerList[] = {78, 16, 82, 146, 338, 1560};
#define Slave_ID 4
// instantiate ModbusMaster object
ModbusMaster node;
void setup()
{
// Modbus communication runs at 9600 baud
Serial1.begin(9600);
Serial.begin(9600);
// Modbus slave ID 1
node.begin(Slave_ID, Serial1);
node.clearResponseBuffer();
node.clearTransmitBuffer();
}
void loop()
{
Serial.println(sizeof(registerList));
for (int i = 0; i < sizeof(registerList) / 2; i++) {
node.clearResponseBuffer();
node.clearTransmitBuffer();
Serial.println(i);
Serial.println(registerList[i]);
uint8_t result = node.readInputRegisters(registerList[i], 2);
// uint8_t result = node.readInputRegisters(0x152, 2);
Serial.println(result);
if (getResultMsg(result))
{
union
{
uint32_t x;
float f;
} u;
u.x = (((unsigned long)node.getResponseBuffer(0) << 16) | node.getResponseBuffer(1));
float z = u.f;
//val[i] = z;
Serial.println(z);
}
delay(2000);
}
Serial.println("********************************************************");
delay(5000);
}
bool getResultMsg(uint8_t result)
{
String tmpstr2;
switch (result) {
case node.ku8MBSuccess:
return true;
break;
case node.ku8MBIllegalFunction:
tmpstr2 = "Illegal Function";
break;
case node.ku8MBIllegalDataAddress:
tmpstr2 = "Illegal Data Address";
break;
case node.ku8MBIllegalDataValue:
tmpstr2 = "Illegal Data Value";
break;
case node.ku8MBSlaveDeviceFailure:
tmpstr2 = "Slave Device Failure";
break;
case node.ku8MBInvalidSlaveID:
tmpstr2 = "Invalid Slave ID";
break;
case node.ku8MBInvalidFunction:
tmpstr2 = "Invalid Function";
break;
case node.ku8MBResponseTimedOut:
tmpstr2 = "Response Timed Out";
break;
case node.ku8MBInvalidCRC:
tmpstr2 = "Invalid CRC";
break;
default:
tmpstr2 = "Unknown error: " + String(result);
break;
}
Serial.println(tmpstr2);
return false;
}