Setting up Modbus on a Raspberry Pi PLC with CODESYS

How to configure Modbus TCP and Modbus RTU on an Industrial Shields Raspberry Pi PLC using CODESYS V3.5 — device tree setup, register mapping, and a practical master/slave example.
June 19, 2026 by
Setting up Modbus on a Raspberry Pi PLC with CODESYS
Joan F. Aubets - Industrial Shields

This guide assumes you have already completed the initial CODESYS setup described in Setting up CODESYS for Raspberry Pi PLC in industrial automation: CODESYS V3.5 SP19 installed on your PC, the CODESYS Control for Raspberry Pi runtime running on the PLC, and a working connection between the two.

You will also need the CODESYS Modbus package installed in CODESYS. If it is not already available, download it from the CODESYS Store and install it via Tools → Package Manager.

Modbus TCP master

This configuration sets up the Raspberry Pi PLC as a Modbus TCP Master — the device that initiates communication and reads or writes data from one or more slaves on the network.

1. Add the Modbus TCP Master to the device tree

In the Devices panel, right-click on Ethernet (the network adapter of your Raspberry PLC) and select Add Device. In the device catalogue, navigate to Fieldbuses → Modbus → Modbus TCP Master and add it.

2. Configure the master

Double-click the Modbus TCP Master device to open its properties. The default settings (port 502, auto-reconnect enabled) work for most applications. Enable Auto-reconnect to handle temporary network interruptions automatically.

3. Add a Modbus TCP Slave

Right-click the Modbus TCP Master and select Add Device → Modbus TCP Slave. In the slave properties, configure:

  • IP address: the IP address of the slave device
  • Port: 502 (default)
  • Unit Identifier (Slave ID): typically 1, unless your device specifies otherwise

4. Configure the channel (register mapping)

Under the Modbus TCP Slave, double-click Modbus TCP Slave I/O Mapping to define which registers to read or write. Add channels using Add Channel and configure:

  • Function code: FC3 (Read Holding Registers) to read, FC16 (Write Multiple Registers) to write
  • Offset: starting register address on the slave device
  • Length: number of registers to read or write

Each channel maps to a variable in your CODESYS project. Assign the variable names in the I/O Mapping tab.

5. Declare the variables in your PLC program

In your PLC_PRG or a POU, declare the variables you have mapped. Example for reading 4 holding registers from a slave:

VAR
    rTemperature    : REAL;
    rPressure       : REAL;
    rFlowRate       : REAL;
    rLevel          : REAL;
END_VAR

After compiling and deploying, CODESYS will poll the slave at every scan cycle and update the mapped variables automatically.

Modbus TCP slave

This configuration sets up the Raspberry Pi PLC as a Modbus TCP Slave — it exposes a set of registers that an external master (SCADA, HMI, another PLC) can read or write.

1. Add the Modbus TCP Slave to the device tree

Right-click on Ethernet in the Devices panel and select Add Device → Modbus TCP Slave.

2. Configure the slave

In the slave properties, set:

  • Port: 502 (default)
  • Unit Identifier: 1 (or as required by your master)

3. Define the register table

In the Modbus TCP Slave I/O Mapping, define which variables in your project will be accessible to the external master. Map your project variables to the corresponding register areas (Holding Registers, Input Registers, Coils, or Discrete Inputs).

Any variable mapped here will be readable or writable by an external Modbus TCP master at the configured register addresses.

Modbus RTU master

Modbus RTU runs over the RS-485 port of the Raspberry Pi PLC. Use this configuration when communicating with field devices such as sensors, drives, or meters connected via RS-485.

1. Identify the serial port

On Industrial Shields Raspberry Pi PLCs, the RS-485 port appears in CODESYS as a COM Port device. It is typically /dev/ttySC0 or /dev/ttySC2 depending on the PLC model. Check your model's user guide to confirm which port corresponds to the RS-485 interface.

2. Add the COM port to the device tree

In the Devices panel, right-click on your Raspberry Pi device and select Add Device → COM Port. Set the port to the RS-485 device path identified above.

3. Add the Modbus COM Master

Right-click the COM Port and select Add Device → Modbus COM Master. In the master properties, configure:

  • Baud rate: match the slave device (typically 9600 or 19200)
  • Parity: None, Even, or Odd — match the slave
  • Stop bits: 1 or 2 — match the slave

4. Add Modbus COM Slave devices

Right-click the Modbus COM Master and add one Modbus COM Slave per physical device on the RS-485 bus. In each slave's properties, set:

  • Slave Address: the device's Modbus address (1–247)

Then configure channels and I/O mapping the same way as the TCP slave described above.

Modbus RTU slave

To configure the Raspberry Pi PLC as a Modbus RTU Slave (responding to an external master over RS-485):

Right-click the COM Port and select Add Device → Modbus COM Slave. Set the Slave Address to the address your master will use to identify this device. Map your project variables to the register table in the I/O Mapping tab.

Practical example: reading a Modbus RTU sensor

A common use case is reading data from an industrial sensor — for example, a Modbus RTU temperature and humidity transmitter connected via RS-485.

Typical configuration steps:

  1. Check the sensor's datasheet for: slave address, baud rate, parity, and register map (which register holds temperature, which holds humidity).
  2. Configure the COM Master with the sensor's serial parameters.
  3. Add a Modbus COM Slave with the sensor's address.
  4. Add one channel per value: FC3 on the register address specified in the datasheet, length 1 (one 16-bit register per value, or 2 if the sensor uses 32-bit floats).
  5. Map the channels to REAL or INT variables in your project.
  6. In PLC_PRG, use the variables directly — CODESYS updates them on every scan.

Example variable usage in Structured Text:

IF rTemperature > 75.0 THEN
    bOverheatAlarm := TRUE;
END_IF

Troubleshooting

Slave not responding (Modbus TCP): verify that the slave is reachable by pinging its IP from the Raspberry Pi. Check that no firewall is blocking port 502.

Slave not responding (Modbus RTU): verify the RS-485 wiring (A+ to A+, B- to B-). Confirm baud rate and parity match between master and slave. Check that you are using the correct serial port for your PLC model.

Variables not updating: confirm that the CODESYS runtime is running on the PLC (not just logged in). Check the Messages panel for device errors. Verify that the scan task cycle time is not too fast for the Modbus poll rate.

Register values incorrect: double-check the register address offset in the channel configuration. Some devices use 0-based addressing, others 1-based — refer to the slave's documentation.

Related posts

Explore the full Raspberry Pi PLC range at industrialshields.com

​Search in our Blog

Setting up Modbus on a Raspberry Pi PLC with CODESYS
Joan F. Aubets - Industrial Shields June 19, 2026
Share this post
Tags

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.

PLC Comparison