Modbus RTU Client RS-485 Library not working

Hi Sir, I am Planning for the two arduino controller. On one side, Modbus RTU Client with RS-485 communicates with the Modbus RTU Slave with RS-485 on the other controller. My Modbus RTU Slave code is working with Master Modscan32. Here is the code for the Modbus RTU slave code:

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

const int numCoils = 10;
const int numDiscreteInputs = 10;
const int numHoldingRegisters = 10;
const int numInputRegisters = 10;
const int id=1;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("Modbus RTU Server Kitchen Sink");

  // start the Modbus RTU server, with (slave) id 42
  if (!ModbusRTUServer.begin(id, 9600)) {
    Serial.println("Failed to start Modbus RTU Server!");
    while (1);
  }

  // configure coils at address 0x00
  ModbusRTUServer.configureCoils(0x00, numCoils);

  // configure discrete inputs at address 0x00
  ModbusRTUServer.configureDiscreteInputs(0x00, numDiscreteInputs);

  // configure holding registers at address 0x00
  ModbusRTUServer.configureHoldingRegisters(0x00, numHoldingRegisters);

  // configure input registers at address 0x00
  ModbusRTUServer.configureInputRegisters(0x00, numInputRegisters);
}

void loop() {
  // poll for Modbus RTU requests
  ModbusRTUServer.poll();
}

I need the code for Modbus RTU Client RS-485 to communicate with the above Modbus RTU Slave RS-485. Kindly provide any example code for Modbus RTU Client for RS-485. I found some example. It is not connecting with Slave Modsim32 application. Kindly help on it.

Maybe what you need is the ModbusMaster library.

Hi sir, Thanks for the reply. will check the same.

@markd833 Sir. I have used the ModbusRTUSlave Library from the link:GitHub - arduino-libraries/ArduinoModbus

Here is the Example code:

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

const int numCoils = 10;
const int numDiscreteInputs = 10;
const int numHoldingRegisters = 10;
const int numInputRegisters = 10;
const int id=1;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("Modbus RTU Server Kitchen Sink");

  // start the Modbus RTU server, with (slave) id 42
  if (!ModbusRTUServer.begin(id, 9600)) {
    Serial.println("Failed to start Modbus RTU Server!");
    while (1);
  }

  // configure coils at address 0x00
  ModbusRTUServer.configureCoils(0x00, numCoils);

  // configure discrete inputs at address 0x00
  ModbusRTUServer.configureDiscreteInputs(0x00, numDiscreteInputs);

  // configure holding registers at address 0x00
  ModbusRTUServer.configureHoldingRegisters(0x00, numHoldingRegisters);

  // configure input registers at address 0x00
  ModbusRTUServer.configureInputRegisters(0x00, numInputRegisters);
}

void loop() {
  // poll for Modbus RTU requests
  ModbusRTUServer.poll();
}

after the ModbusRTU Server.Poll() syntax execution. I have to do:

I have to identify whether the Frame received from the Master is Function code -->read(03) or Multiplewrite(10).

If the Frame received is read (03)--> I have to read the holding register and move to the temporary variable
If the Frame received is MultipleWrite --> I have to write into that holding register and also to the EEPROM location.

So How to differentiate the Function code received is read(03) or multiple write function(16). Kindly help on this ModbusRTUSlave library.

It will be in there somewhere. However, the library you are using is meant for the MKR series of boards.

I think it is defined within the ArduinoRS485 library, in RS485.h by the looks of it.

#ifdef __AVR__
#define RS485_DEFAULT_DE_PIN 2
#define RS485_DEFAULT_RE_PIN -1
#elif ARDUINO_NANO_RP2040_CONNECT
#define RS485_DEFAULT_DE_PIN A1
#define RS485_DEFAULT_RE_PIN A0
#elif ARDUINO_SAMD_ZERO
#define RS485_DEFAULT_DE_PIN A4
#define RS485_DEFAULT_RE_PIN A5
#else
#ifndef RS485_DEFAULT_DE_PIN
#define RS485_DEFAULT_DE_PIN A6
#define RS485_DEFAULT_RE_PIN A5
#endif
#endif

Hi Sir, Thanks for the reply. From the Data you have sent, I understand that the below Hardware to be assigned to work for my Mega board.

#ifndef RS485_DEFAULT_DE_PIN
#define RS485_DEFAULT_DE_PIN A6
#define RS485_DEFAULT_RE_PIN A5
#endif

I have to use the mega board Pin A6 (PF6 port pin for Driver Enable pin ) and Pin A5 (PF5 Port pin for Receive Enable Pin) to work the mega for this library Modbus RTU Slave and Master. Library:GitHub - arduino-libraries/ArduinoModbus

I have shorted the DE and RE Pin and using as Single Port Pin to control the RS-485 Driver IC.
DE Pin shorted with RE Pin -- High -- To transmit the Data
DE Pin shorted with RE Pin -- Low - To receive the Data.

I have to add this DE Pin control in the library Example link:
1.ModbusRTUClientKitchenSink Example
2.ModbusRTUServerKitchenSink Example

am I right Sir?

Mega board1 (TX & RX Pin,DE Pin) --> IC Max 485 (RS-485 Driver) --> IC Max 485( RS-485 Driver) --> Mega board2 (TX & RX Pin,DE Pin).

if there is any other Modbus RTU Slave /Master with RS-485 Driver Example to use. Kindly suggest, This will be helpful to me.

I'm guessing here as i've not used that library, but if you connect both RE and DE together (to save an i/o pin), then you could connect the pair to either the A5 or the A6 pin.

The library shouldn't need to be modified as you would be using an existing configuration.

However, you would need to check which serial port the library uses. I seem to recall that it is defined at the end of RS485.cpp

#ifdef RS485_SERIAL_PORT
RS485Class RS485(RS485_SERIAL_PORT, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
#else
RS485Class RS485(SERIAL_PORT_HARDWARE, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
#endif

Hi Sir, Thanks for the reply. I am using the Atmega 2560 Serial2 Pins that is, RX2 --> PH0 Port Pin (12th Pin). TX 2 --> PH1 Port Pin (13th Pin).
I think, the library uses the USB serial Port.
Libraries are read only. How to change this Serial Port 2 in Mega for my RS-485 communication. Kindly let us know.
If you have any Modbus RTU Client Library using RS-485, Please do share. It will be helpful to me.

#ifdef RS485_SERIAL_PORT
RS485Class RS485(RS485_SERIAL_PORT, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
#else
RS485Class RS485(SERIAL_PORT_HARDWARE, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
#endif

I think, and I may be recalling this incorrectly, you need to actually edit the RS485.cpp source code file and remove the lines at the end of the file that I showed in post #8 so that the end of the file has the 1 line something like:

RS485Class RS485(SERIAL_PORT_HARDWARE1, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);

You should also have a read of the following discussion:

NOTE: if you edit the ArduinoRS485 file RS485.cpp, then your changes will be lost/replaced if that library is updated in the future.

There is another library that I found some time ago that I think allowed an UNO to become a Modbus server and that was quite easy to understand. If I find it again, I will post a link here.

EDIT: Found it. The library is:

However, it looks like the author has updated it since I used it at v1.0.5 and I don't think it will do what you want using the latest version of code. :worried: