Objective: Configure a RevPi as a Modbus slave using CODESYS in order to reliably communicate with Modbus-TCP- and Modbus-RTU-based industrial devices simultaneously. The application copies the first 10 holding registers into the 10 input registers of both slaves.

This tutorial applies to the following base modules:

A preconfigured example project using RevPi Connect/+/S as the base module is available in a GitLab repository. It can be adapted to the base modules listed above.

Prerequisites #

Devices #

RevPi base module with RS485 interface

✓ Modbus TCP slave

✓ Modbus RTU slave

Note

Make sure the slaves are configured with unique IDs and consistent communication settings.

Hardware Installation #

✓ The RevPi base module is connected to the network.

✓ The RevPi base module is connected to the power supply.

Software Installation #

✓ CODESYS Development System (CODESYS) is installed on your PC.

✓ CODESYS runtime is installed in the CODESYS Development System.

✓ RevPi I/O driver is installed in the CODESYS Development System.

✓ CODESYS is connected to the RevPi.

✓ CODESYS runtime is installed on the RevPi.

See the documentation on Setting up the System.

1. Creating a Project in CODESYS #

▷ Open CODESYS on your PC.

▷ Open the example project ModbusTCP-RTU-Slave from the GitLab repository.

▷ If necessary, adjust the RevPi base module in the device tree to match your actual device.

The device tree in CODESYS is configured as follows:

  • Modbus TCP Slave receives requests from a Modbus TCP Master via Ethernet and provides holding registers and input registers.

  • Modbus RTU Slave communicates with a Modbus RTU Master via the RS485 serial interface and also provides holding registers and input registers.

  • POU_Modbus processes the application logic to copy data between the holding registers and input registers.

CODESYS Device Tree Overview

2. Configuring the Serial Modbus RTU Interface #

For RevPi devices with an RS485 interface

▷ Open the configuration file CODESYSControl_User.cfg using:

sudo nano /etc/codesyscontrol/CODESYSControl_User.cfg

▷ Add the following line to define the naming scheme for the serial ports:

[SysCom]
Linux.Devicefile=/dev/ttyRS485-

This allows CODESYS to identify the RS485 interfaces in the Linux system and communicate via Modbus RTU.

▷ In CODESYS, open the MODBUS_COM device.

▷ On the General tab, assign the COM ports according to the number of RS485 interfaces as follows:

  • /dev/ttyRS485-0 → COM Port 1

  • /dev/ttyRS485-1 → COM Port 2

  • /dev/ttyRS485-x → COM Port x+1

Up to RevPi Bullseye (04/2024)

Older images only provide the directory /dev/ttyRS485.

▷ Create a symbolic link to access the same physical RS485 port and communicate with the Modbus slave:

ls -la /dev/ttyRS485-0

▷ If the error message No such file or directory is displayed, create the symbolic link with:

sudo ln -s /dev/ttyRS485 /dev/ttyRS485-0

▷ Reboot the system.

Using a USB-to-RS485 Converter

If an additional USB-to-RS485 converter is connected, the correct COM port must be identified.

▷ Add the following line to the file /etc/codesyscontrol/CODESYSControl_User.cfg:

[SysCom]
Linux.Devicefile=/dev/ttyRS485-

The USB device number is automatically assigned by the system when the USB-to-RS485 converter is connected.

▷ Determine the device number with:

ls /dev/ttyUSB*

❯ This displays devices such as /dev/ttyUSB0, /dev/ttyUSB1.

▷ Create a symbolic link for the USB-to-RS485 converter to the next available /dev/ttyRS485-x device file:

sudo ln -s /dev/ttyUSBx /dev/ttyRS485-y

x is the USB device number assigned by the system.

y is the next higher RS485 port number that is not used by an integrated port.

Example:

If your device has an integrated port /dev/ttyRS485-0 and your USB converter is /dev/ttyUSB0, use:

sudo ln -s /dev/ttyUSB0 /dev/ttyRS485-1

3. Configuring the Modbus RTU Slave and Modbus TCP Slave #

Configuring the Modbus RTU Slave

▷ Map the holding registers and input registers to the variables in POU_Modbus so you can read and write the Modbus data in your application.

Configuring the Modbus RTU Slave

4. Simulating the Modbus TCP Master and Modbus RTU Master #

▷ Use the application QModMaster for simulation.

Modbus Functions #

Write Multiple Registers writes data to the holding registers of the Modbus TCP/RTU slave running on the RevPi.

Configuring Modbus RTU Master

Read Holding Registers reads data from the holding registers of the Modbus TCP/RTU slave.

Configuring Modbus RTU Master

Configuring the Modbus TCP Unit ID #

In Modbus TCP, the Unit ID fulfills the same logical role as the Slave ID in Modbus RTU. It is especially relevant when a Modbus TCP gateway addresses multiple downstream devices or when a single device such as the RevPi is addressed directly.

▷ Use Unit ID 255 or the Modbus TCP slave running on the RevPi to address the device (gateway) directly.

Note

Special case when using QModMaster:

QModMaster uses Unit ID 0 instead of Unit ID 255 to address the gateway itself.

▷ Therefore, use Unit ID 0 in QModMaster when communicating with the Modbus TCP slave on the RevPi.

Configuring the Modbus RTU Master
Configuring the Modbus RTU Master

Further Resources #