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

Arduino PLCs automate anything. Learn how to do it with Modbus TCP and an Arduino PLC industrial
March 20, 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 automation, 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 automationdevices.

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


In this post, 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 slaveless 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.

Software for Programmable Logic Controller PLC

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 502but 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]);
// ...

​Search in our Blog

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

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.

Industrial PLC comparison >>>