To connect an HMI screen to an Arduino based PLC, use Modbus: Modbus TCP over Ethernet or Modbus RTU over RS-485. In this example a Kinco G100E HMI is a Modbus TCP slave (IP 192.168.0.5, port 502, station 1) and an M-Duino 21+ is the master: with the Industrial Shields Modbus library it writes coil 0 to the HMI bit LB 0 and holding register 0 to the HMI word LW 0, once per second.
HMI touch screens are the usual operator interface on a machine: buttons, lamps and values that the PLC reads and writes. This guide sets up a Kinco screen in Kinco DTools, wires it to the PLC over Ethernet and adapts two examples of the Industrial Shields Modbus library. A video at the end shows the whole setup.
- Step 1Wire and powerHMI at 24 Vdc, PLC at 12-24 Vdc, Ethernet cable between them
- Step 2HMI as Modbus slaveNetwork Device Setting: Modbus TCP Slave, port 502, station 1
- Step 3HMI screenA Bit State Lamp on LB 0, a value on LW 0
- Step 4PLC as masterWrite coil 0 and register 0 with the Modbus library
What do you need?
| Item | Used in this example |
|---|---|
| PLC | M-Duino 21+: Arduino Mega 2560 inside, Ethernet, 13 inputs and 8 outputs |
| HMI | Kinco G100E: 10.1 inch, 1024 x 600, Ethernet, serial ports COM0 (RS-232, RS-485, RS-422), COM1 (RS-485, RS-422) and COM2 (RS-232) |
| HMI software | Kinco DTools (V3.5.1 in the screenshots), from the Kinco website |
| PLC software | Arduino IDE with the Industrial Shields boards and the Industrial Shields Modbus library (version 1.1.0 when this guide was updated) |
| Wiring | 24 Vdc supply for the HMI, 12-24 Vdc supply for the PLC, an Ethernet cable, a USB cable for the PLC and a USB cable for the HMI |
The roles are fixed by the HMI configuration: the HMI is the Modbus TCP slave (server) and waits for requests on port 502; the PLC is the master (client) and sends them. Many HMIs can also work the other way round, as masters that poll a PLC slave; see Modbus TCP slave with an Arduino based PLC for that case.
How do you wire and power the HMI and the PLC?
- Power the HMI with a 24 Vdc supply and the PLC with its 12-24 Vdc supply (12 Vdc in this example).
- Connect the PLC and the HMI with an Ethernet cable, directly or through a switch. Both must be in the same subnet: 192.168.0.4 for the PLC and 192.168.0.5 for the HMI in this example.
- Connect the PC to the PLC with a USB cable to upload the program, and to the HMI with a USB cable to download the screen project.
Step 1: create the HMI project in Kinco DTools
Open Kinco DTools and create a new project. In the New Project dialog, choose the HMI Model (G100E here); the dialog shows its hardware information (Figure 1). Press Next, skip the following dialog and press Finish. A block for the screen, HMI0, appears in the center of the project (Figure 2).


Step 2: configure the HMI as a Modbus TCP slave
Double-click the HMI block, or right-click it and choose Attribute. In the HMI tab, press Network Device Setting (Figure 3), press Add and set the new device as in Figure 4:
| Field | Value |
|---|---|
| Device Type | HMI |
| Device No. | HMI0 |
| IP Address | 192.168.0.5 |
| Port Num | 502 |
| Comm Protocol | Modbus TCP Slave |
| Station NO. | 1 |


In Figure 3 the Network 0 field still shows the default address 192.168.0.100. Whatever address the HMI finally uses, the PLC program must point to that same address (192.168.0.5 in this example).
Step 3: add the screen elements
Right-click the HMI block and choose Edit to open the screen. The Graph element window on the left lists the elements you can add.
- For a bit, drag a Bit State Lamp to the screen and set Addr Type: LB and Address: 0. Keep the other default values. For more bits, use the next addresses (LB 1, LB 2...). In the bit state options you choose how the element behaves; this example uses toggle.
- For a value, use an element with the LW address type (word), and increase the word length if you need more than 16 bits.
Compile with Tools > Compile. If there are no errors, download the project with Tools > Download: set the communication type to USB port and press Download.

Step 4: program the PLC as Modbus TCP master
Install the Industrial Shields boards in the Arduino IDE, download the Modbus library from GitHub as a ZIP file and add it with Sketch > Include Library > Add .ZIP Library. Restart the IDE if the examples do not appear.

Select your M-Duino Arduino PLC model and port, and open File > Examples > Modbus > ModbusTCPMasterWriteSingleCoil. Change the configuration block at the top to the addresses of this setup:
// Modbus master IP (the M-Duino)
#define ETHERNET_MASTER_IP IPAddress(192, 168, 0, 4);
// Modbus slave IP (the Kinco HMI)
#define ETHERNET_SLAVE_IP IPAddress(192, 168, 0, 5);
// Modbus slave port
#define ETHERNET_SLAVE_PORT 502
// Modbus address of the slave (Station NO.)
#define MODBUS_SLAVE_ADDRESS 1
// Coil address to write (LB 0 in the HMI)
#define MODBUS_COIL_TO_WRITE 0
// Milliseconds between requests
#define MS_BETWEEN_REQUESTS 1000
The example opens a TCP connection to the HMI, reconnects if it drops, and every 1,000 ms sends a Write Single Coil request (function code 05) that toggles coil 0. The Bit State Lamp on LB 0 changes state each second.
static void sendModbusRequest(void) {
static bool coilValue;
if (master.writeSingleCoil(slaveEth, MODBUS_SLAVE_ADDRESS, MODBUS_COIL_TO_WRITE, coilValue)) {
coilValue = !coilValue;
}
else {
// For some reason, the request could not be completed.
Serial.println("Request to write a coil failed");
}
}
To send a value, open ModbusTCPMasterWriteSingleRegister and change the same lines (the register address is MODBUS_HOLDING_REGISTER_TO_WRITE, 0). It sends a Write Single Register request (function code 06) that alternates the value of register 0, the HMI word LW 0, between 0 and 1000:
if (master.writeSingleRegister(slaveEth, MODBUS_SLAVE_ADDRESS, MODBUS_HOLDING_REGISTER_TO_WRITE, registerValue)) {
registerValue = registerValue == 0 ? 1000 : 0;
}
Upload the program to the PLC. We compiled both examples with these changes for the M-Duino 21+ (ATmega2560) with version 1.1.0 of the library; test them with your own HMI before you use them in a machine.
| PLC request | Modbus function | Address | HMI element |
|---|---|---|---|
writeSingleCoil | 05, Write Single Coil | Coil 0 | Bit State Lamp, LB 0 |
writeSingleRegister | 06, Write Single Register | Holding register 0 | Word element, LW 0 |
More about the master library and its read functions in Modbus TCP master with Arduino and ESP32 based PLCs.
Video: Kinco HMI and M-Duino Arduino PLC over Modbus TCP
The video shows the HMI configuration and the communication between the PLC and the screen, step by step.
Troubleshooting
- The serial monitor prints "The first connection attempt failed": check the Ethernet cable, that the PLC and the HMI are in the same subnet, and that the IP in the sketch is the one the HMI really uses.
- The connection works but nothing changes on the screen: check that the station number in the sketch (
MODBUS_SLAVE_ADDRESS) and in DTools is the same, and that the element uses LB 0 or LW 0. - The response contains an error: the HMI answered with a Modbus exception; check the address type and the address of the element.
FAQ about connecting an HMI to an Arduino based PLC
Can I connect the HMI over RS-485 instead of Ethernet?
Yes, with Modbus RTU, if the HMI has an RS-485 port (the G100E has it on COM0 and COM1). The PLC then uses the RTU master examples of the same library. See Modbus RTU with Arduino and ESP32 based PLCs.
Does it work with other HMI brands?
Yes, with any HMI that supports Modbus TCP or Modbus RTU. Only the configuration tool changes; the PLC side is the same.
Should the HMI be the master or the slave?
Both work. With the HMI as slave, as here, the PLC decides when to write. With the HMI as master, the HMI polls the PLC, which runs a Modbus slave; that is the usual choice when the screen must read many PLC values.
Can the PLC read values from the HMI?
Yes. The library has read functions for coils and holding registers; use them to read buttons (LB) or setpoints (LW) written by the operator.
Which Modbus protocol should I choose for a plant?
Modbus TCP between PLCs, HMIs and SCADA, Modbus RTU on the field bus. The guide to Modbus RTU, Modbus TCP and OPC UA explains where each one fits.
Take it further
Operator screens around a PLC in real use: a belt with a Panel PC, a fermentation cellar with a panel PC and a touchscreen with status LEDs.
Case study
The PLC sets the speed. The inverter moves the belt.
An M-Duino 42+ runs the speed loop with analog signals for speed and current, and a Panel PC gives the operator functions.
Read the case study
Simulator
Keep every fermentation tank between its limits
An M-Duino 42+ reads a probe in each of four tanks and opens the cooling jacket valve of the tank that goes above its maximum, with a panel PC to acknowledge the alerts.
Open the simulator
PLC Solution Library
MQTT-driven status LEDs for a touchscreen machine HMI
A Node-RED dashboard on a TouchBerry Pi where a LED follows an MQTT topic and a button publishes orders back to the broker.
See the example
An HMI and a PLC from the same catalog. The TouchBerry Pi is a Raspberry Pi panel PC with Node-RED dashboards and a few I/O of its own, and it talks Modbus TCP with M-Duino Arduino PLC, ESP32 PLC and Raspberry PLC.