I am trying to read the holding registers on a Solax Inverter using Arduino UNO and a MAX485 transceiver. The Arduino program uses the Modbusmaster library.
I can read an Open Modsim slave's holding registers setup on a PC and connecting to it via a USB RS485 plug so the Arduino connections and hardware are all working.
I can read the inverter holding registers using a PC/USB RS485 plug and QmodMaster software so I have the right addresses configured.
I think the problem is that the format of the Modbus query from Arduino to the inverter does not conform with the format the Inverter is looking for.
Here is the code I am using and the inverter holding registers start at 0x400 (1024)
#include<ModbusMaster.h>
#include<SoftwareSerial.h>
// define send and receive enable pins for MAX485
#define MAX485_DE 3
#define MAX485_RE 2
//create software serial port to communicate with MAX485
SoftwareSerial modbus_serial (10,11);// Rx 10, Tx 11
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE, 0);
digitalWrite(MAX485_DE, 0);
}
void setup() {
Serial.begin(9600);
modbus_serial.begin(9600);
pinMode(MAX485_RE, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE, 0);
digitalWrite(MAX485_DE, 0);
//My slave uses 9600 baud
delay(10);
Serial.println("starting arduino: ");
Serial.println("setting up Serial ");
Serial.println("setting up RS485 port ");
// slave id
node.begin(1, modbus_serial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop() {
uint16_t result;
//slave address and length
result = node.readHoldingRegisters(0x400,16);// address registers from 1024
Serial.print(result);
Serial.print("\n");
if (result == node.ku8MBSuccess)
{
Serial.print("Powgen : ");
Serial.println(node.getResponseBuffer(12));
Serial.print("Mains Frequency : ");
Serial.println(node.getResponseBuffer(13));
Serial.print("Mains Voltage : ");
Serial.println(node.getResponseBuffer(14));
}
Serial.print("\n");
delay(1000);
}
Here is the query format that the inverter is looking for.

Here is the query that the Qmodmaster sends to the inverter and gets a succesful response.
00 00 00 00 00 06 01 03 04 00 00 10
Here is the query that the Arduino sends to the inverter and gets the 0x02 illegal data address code returned.
01 03 04 00 00 10 45 36
To test this I would like to modify the code to send the query in the format that Qmodmaster sends but my programming knowledge is limited.
If someone could point me in the right direction I would be very grateful. Thank you.