How to use Modbus TCP Slave library with a PLC controller Arduino
20 March, 2020 by
How to use Modbus TCP Slave library with a PLC controller Arduino
Bernat Garcia

Previous reading

Modbus RTU Master library for industrial automation

Read the post >>

To be able to follow easily the explanation of our Modbus TCP libraries for industrial PLC Arduino, first of all, it would be interesting to have a look at the Modbus RTU post to understand better the characteristics and configurations of this type of communication on industrial Arduino devices.

How to use Modbus TCP Slave library with a PLC controller Arduino


On this blog, we will introduce you to our libraries to be able to implement the Modbus TCP/IP Slave mode when working with programmable logic controllers. Basically, it works in the same way as the Modbus RTU with some exceptions.

  • TCP - Transmission Control Protocol. 

  • IP - Internet Protocol. 

This is a Modbus variant used for communications over TCP/IP networks on industrial controllers for Arduino automation, connecting over port 502. It does not require a checksum calculation, as lower layers already provide checksum protection.

Technical details

Modbus TCP encapsulates Modbus RTU request and response data packets in a TCP packet transmitted over standard Ethernet networks. The unit number is still included and its interpretation varies by application - the unit or slave address is not the primary means of addressing in TCP. The most important address here is the IP address. As we said before, the standard port for Modbus TCP is 502, but the port number can often be reassigned if you wish.

The checksum field normally found at the end of an RTU packet is omitted from the TCP packet. Checksum and error handling are handled by Ethernet in the case of Modbus TCP. 

The TCP version of Modbus follows the OSI Network Reference Model. Modbus TCP defines the presentation and application layers in the OSI model. This type of transmission makes the definition of master and slave less obvious because Ethernet allows peer-to-peer communication. The meaning of client and server are better-known entities in Ethernet-based networking. In this context, the slave becomes the server and the master becomes the client. There can be more than one client obtaining data from the server. In other words, we can say that this means there can be multiple masters as well as multiple slaves. Instead of defining master and slave on a physical device by device basis, the designer will have to create logical associations between master and slave to define the roles.


Modbus TCP Slave with Arduino IDE

The Modbus TCP Slave module implements the Modbus TCP Slave functionality.

#include <ModbusTCPSlave.h>

ModbusTCPSlave slave;

The default TCP port is the 502 but you can change it with:

// Set the TCP listening port to 510 instead of 502
ModbusTCPSlave slave(510);

To map the coils, discrete inputs, holding registers and input registers addresses with the desired variables values, the module uses four variables arrays:

bool coils[NUM_COILS];
bool discreteInputs[NUM_DISCRETE_INPUTS];
uint16_t holdingRegistesr[NUM_HOLDING_REGISTERS];
uint16_t inputRegisters[NUM_INPUT_REGISTERS];

The lengths of these arrays depend on the application and the register's usages. Obviously, the names of the arrays also depend on your preferences.

To associate the registers arrays with the library, it is possible to use their functions in the setup:

slave.setCoils(coils, NUM_COILS);
slave.setDiscreteInputs(discreteInputs, NUM_DISCRETE_INPUTS);
slave.setHoldingRegisters(holdingRegisters, NUM_HOLDING_REGISTERS);
slave.setInputRegisters(inputRegisters, NUM_INPUT_REGISTERS);

It is not required to have all kinds of registers mapping to work, only the ones used by the application.

To start Modbus TCP server, call the  begin function after the registers mapping. It is also possible to call the  begin function before the registers mapping. Remember to begin the Ethernet before the Modbus TCP Slave object in the setup.

// Init the Ethernet
Ethernet.begin(mac, ip);

// Init the ModbusTCPSlave object

At this time the Modbus TCP server is running and the only important thing to do is to update the Modbus TCP Slave object often in the lllll function, and treat the registers mapping values to update variables, inputs and outputs.

// Update discrete inputs and input registers values
discreteInputs[0] = digitalRead(I0_7);
inputRegisters[0] = analogRead(I0_0);
// ...

// Update the ModbusTCPSlave object

// Update coils and holding registers
digitalWrite(Q0_0, coils[0]);
// ...

Check other posts about Modbus

Modbus TCP Master with Industrial Arduino based PLCs 

Read the post >>

Modbus RTU Master library for industrial automation

Read the post >>

How to connect Arduino based PLC's using Modbus TCP/IP

Read the post >>

Communicating by MODBUS RTU through an RS485 serial interface (Seneca Z-D-in Module)

Read the post >>

How to use Modbus TCP Slave library with a PLC controller Arduino
Bernat Garcia
20 March, 2020
Share this post

Looking for your ideal PLC?

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.

Industrial PLC comparison >>

Do you want more information?

Just fill the form!

Tell me more!