Modbus TCP Master with Industrial Arduino PLCs
Communication using master-slave technique with Arduino Modbus TCP
25 March, 2020 by
Modbus TCP Master with Industrial Arduino PLCs
Bernat Garcia

Introduction of Modbus TCP Master with industrial Arduino - based PLCs


The Modbus protocol was developed in 1979 by Modicon for industrial automation systems and programmable logic controllers with an Ethernet connection. It is used to transfer discrete/analog I/O information and register data between industrial control and monitoring devices.

M-Duino Modbus TCP

Modbus devices communicate using a master-slave (client-server) technique in which only one device (the master/client) can initiate transactions (called queries). The other devices (Arduino Modbus TCP server example slaves/servers) respond by supplying the requested data to the master, or by taking the action requested in the query.

A slave is any peripheral device (I/O transducer valve, network drive, or other measuring devices) that processes information and sends its output to the master using Modbus.

The Acromag I/O Modules from slave/server devices, while a typical master device is a host computer running appropriate application software. Other devices may function as both clients (masters) and servers (slaves).


In order to work with the Modbus TCP, you will need any of our PLC controllers for industrial automation:

Industrial Shields controllers based on Arduino automation:

Requirements for Modbus TCP Master with industrial Arduino - based PLCs

Modbus TCP/IP protocol

Construction of Modbus TCP data packet 

Modbus TCP/IP uses TCP/IP and Ethernet to carry the data of the Modbus message structure between compatible devices. That is, Modbus TCP/IP combines a physical network (Ethernet), with a networking standard (TCP/IP), and a standard method of representing data (Modbus as the application protocol). Essentially, the Modbus TCP/IP message is simply a Modbus communication encapsulated in an Ethernet TCP/IP wrapper.

Hardware - Modbus TCP Master with industrial Arduino-based PLCs


Configuration of the switches

Most of the inputs and the outputs are connected to the internal PLC Arduino, but in few cases, the user can choose between a special peripheral configuration of a GPIO by changing the position of the Dip Switches.

Each switch can select only one of the two possible configurations at the same time, the right position (ON) or the left one (OFF). 

In this case, the position of the switches is not important, because communication is always available.

Software - Modbus TCP Master Library

This Arduino Modbus TCP library is only available for Industrial Shields' industrial PLC, but they can be modified by any user, so they can be used in other Arduino devices.

The Arduino Modbus TCP/IP Library contains the functions to read and write slave values:

readCoils(client, slave_address, address, quantity);
readDiscreteInputs(client, slave_address, address, quantity);
readHoldingRegisters(client, slave_address, address, quantity);
readInputRegisters(client, slave_address, address, quantity);
writeSingleCoil(client, slave_address, address, value);
writeSingleRegister(client, slave_address, address, value);
writeMultipleCoils(client, slave_address, address, values, quantity);
writeMultipleRegisters(client, slave_address, address, values, quantity);


  • arduino modbus tcp client¬†¬†is the EthernetClient connected to the slave.
  • slave_address¬†is the Modbus RTU slave address.
  • address¬†is the coil, digital input, holding register or input register address. Usually this address is the coil, digital input, holding register or input register number minus 1: the holding register number¬†40009¬†has the address¬†8.
  • quantity¬†is the number of coils, digital inputs, holding registers or input registers to read/write.
  • value¬†is the given value of the coil or holding registers on a write operation. Depending on the function the data type changes. A coil is represented by a¬†bool¬†value and a holding register is represented by a¬†uint16_t¬†value.

On a multiple read/write function the address argument is the first element address. On a multiple write function the values argument is an array of values to write.

It is important to notice that these functions are non-blocking, so they do not return the read value. They return true or false depending on the current module state. If there is a pending Modbus request or the client is not connected, they return false.

  • There is the¬†available()¬†function to check for responses from the slave.

  • The¬†ModbusResponse¬†implements some functions to get the response information:


  • Modbus TCP Master Input registers reader code:

   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <>.

#include <Ethernet.h>            // This is the client;
#include <ModbusTCPMaster.h>     // This is the master;

// Ethernet configuration values
uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
uint8_t ip[] = { 10, 10, 10, 3 };
uint8_t slaveIp[] = { 10, 10, 10, 4 };
uint16_t slavePort = 502;

// Define the ModbusTCPMaster object
ModbusTCPMaster master;

// Ethernet client object used to connect to the slave
EthernetClient slave;

uint32_t lastSentTime = 0UL;

void setup() {

  // Begin Ethernet
  Ethernet.begin(mac, ip);

  // NOTE: it is not necessary to start the modbus master object

void loop() {
  // Connect to slave if not connected
  // The ethernet connection is managed by the application, not by the library
  // In this case the connection is opened once
  if (!slave.connected()) {

    slave.connect(slaveIp, slavePort);

  // Send a request every 1000ms if connected to slave
  if (slave.connected()) {
    if (millis() - lastSentTime > 1000) {
      // Send a Read Input Registers request to the slave with address 31
      // It requests for 6 registers starting at address 0
      // IMPORTANT: all read and write functions start a Modbus transmission, but they are not
      // blocking, so you can continue the program while the Modbus functions work. To check for
      // available responses, call master.available() function often.
      if (!master.readInputRegisters(slave, 31, 0, 6)) {
        // Failure treatment

      lastSentTime = millis();

    // Check available responses often
    if (master.isWaitingResponse()) {
      ModbusResponse response = master.available();
      if (response) {
        if (response.hasError()) {
          // Response failure treatment. You can use response.getErrorCode()
          // to get the error code.
        } else {
          // Get the input registers values from the response
          Serial.print("Input registers values: ");
          for (int i = 0; i < 6; ++i) {


Arduino RS485 working as a Modbus RTU

Modbus is a standard way to connect different devices for Industrial uses. As shown in this post you can connect through Modbus TCP protocol using Arduino Ethernet shields or working with Arduino as a PLC but there are other ways to use the Modbus protocol. You can also use Modbus RTU using the RS485 shield for Arduino.

Take into consideration if you need to work using Arduino for Industrial automation or industrial use you can also use the same code used on an Arduino Uno board connected to any MAX485 Arduino shield using an Arduino industrial grade controller made from Industrial Shields. 

Programmable Logic Controllers

Open Source based solutions for automation, monitoring and control

PLC Based on Arduino, Raspberry Pi and ESP 32

Modbus TCP Master with Industrial Arduino PLCs
Bernat Garcia
25 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!