I have an ESP32 that I would like to use to read MODBUS data from a digital controller via a MAX485.
I am using the Basic example from the ModbusRtu.h library and am receiving data back from the controller. The data received is however not correct. (Checked against the settings on the device as well as via PC)
If I send the following to the controller : 0103039300017463
Address : 01
Function : 03
Read Register : 0393
Num Elements Read : 0001
Checksum : 7463
I expect to receive : 01030202A6395E
Address : 01
Function : 03
Not too sure about this : 02
HEX Value of Register : 02A6
Checksum : 395E
I am receiving : 010301fffd01541c
The address and function values are correct however the rest of the response makes no sense ![]()
Is there and easier way to send and receive a large number of queries to a MODBUS device by using the HEX sequences directly?
Below is the code I am using
#include <ModbusRtu.h>
uint16_t au16data[16]; //!< data array for modbus network sharing
uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* port : serial port
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus master(0,Serial,23); // this is master and RS-232 or USB-FTDI
/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram[23];
unsigned long u32wait;
void setup() {
// telegram 0: read registers
telegram[0].u8id = 1; // slave address
telegram[0].u8fct = 3; // function code (this one is registers read)
telegram[0].u16RegAdd = 393; // start address in slave
telegram[0].u16CoilsNo = 1; // number of elements (coils or registers) to read
telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino
// telegram 1: write a single register
//telegram[1].u8id = 1; // slave address
//telegram[1].u8fct = 6; // function code (this one is write a single register)
//telegram[1].u16RegAdd = 4; // start address in slave
//telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read
//telegram[1].au16reg = au16data+4; // pointer to a memory array in the Arduino
Serial.begin( 9600 ); // baud-rate at 9600
master.start();
master.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
u32wait = millis() + 1000;
u8state = u8query = 0;
}
void loop() {
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // wait state
break;
case 1:
master.query( telegram[u8query] ); // send query (only once)
u8state++;
u8query++;
if (u8query > 2) u8query = 0;
break;
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 1000;
}
break;
}
au16data[4] = analogRead( 0 );
}