#### 6.1.3 Communication between OpenPLC Runtime and Node-RED Middleware  
The communication takes place first between OpenPLC and Factory I/O (Figure 9). The communication is provided using the Modbus protocol because OpenPLC does not support more modern protocols (e.g., OPC UA). In this case, OpenPLC behaves as a Modbus server and Factory I/O behaves as a Modbus client. Since we want to send the data to the cloud or provide it to other clients using the OPC UA server, we need an intermediary in the form of Node-RED. Thus, Node-RED is not needed for production control itself, but we use it for the possibility of sharing data for the OPC UA server and to the cloud. We communicate from Node-RED to Microsoft Azure cloud and back using the MQTT communication protocol. In order to properly connect the OpenPLC runtime with Node-RED, it is necessary to understand how the Modbus protocol works and what is a server and what is a client in our case. OpenPLC can even work as a server and a client at the same time, which we will not actively use. Modbus offers four types of transmitted data. Figure 8: Remover. Figure 6: Retroreflective sensor and reflector. Figure 7: Emitter. * **Discrete Input**--A single bit (BOOL) that is used for binary input (e.g., from sensors). In our case, these are addresses of type %IX. It can only be written by the Modbus server;
* **Coil--A single bit (BOOL), which is mostly used for binary output. In our case it is addresses of type %QX. It can be written not only by the server but also by the client;
* **Input Register**--A 16-bit read-only register. It is kind of like Discrete Input, except it is not BOOL, but it is a 16-bit INT that can be unsigned or signed;
* **Holding Register**--A 16-bit register designed for both read and write. It is kind of like Coil, except it is not a BOOL, but it is a 16-bit INT that can be unsigned or signed. As mentioned, OpenPLC can act as both a Modbus client and a Modbus server. In these modes it works simultaneously, but a different address is reserved for each. For the OpenPLC server mode we are using, it has the following addresses (see Table 1). Next, you need to set the Factory I/O on the Modbus client. We set the localhost where we are running OpenPLC, which is 127.0.0.1. Next, we need to set the digital inputs to be used on Coils. It would be more logical to use Inputs, but since Modbus client can only write to Coils, we have to use Coils for the inputs. And last we need to set up I/O Points and there we set the inputs and outputs according to how much space we need. In Factory I/O, the input and output variables need to be assigned correctly to the Factory I/O components (Figure 10). The addresses must be identical to those in OpenPLC. The control program from OpenPLC editor needs to be loaded into OpenPLC runtime and run. Figure 11 shows how values are read from the OpenPLC runtime and how OpenPLC connects to Node-RED using Modbus protocol. The ability to communicate via Modbus can be obtained by installing the _node-red-contrib-modbus 5.14.1_ library. \begin{table}
\begin{tabular}{c c c c c c c} \hline \hline \multirow{2}{*}{**Modbus Table**} & \multirow{2}{*}{**Usage**} & **PLC** & **Modbus** & **Data** & **Range** & **Access** \\  & & **Address** & **Data Address** & **Size** & **Range** & **Access** \\ \hline
**Discrete Output** & Digital & \%QX0.0–\%QX99.7 & 0–799 & 1 bit & 0 or 1 & RW \\
**Coils** & Inputs & \%IX0.0–\%IX09.7 & 0–799 & 1 bit & 0 or 1 & R \\
**Analog Input** & Analog & \%IW0–\%IW1023 & 0–1023 & 16 bits & 0–65,535 & R \\
**Registers** & Input & \%QW0–\%QW1023 & 0–1023 & 16 bits & 0–65,535 & RW \\
**Analog Output** & Analog & \%QW0–\%QW1023 & 0–1023 & 16 bits & 0–65,535 & RW \\ \hline \hline \end{tabular}
\end{table} 
Table 1: Modbus server variables in OpenPLC engine [30]. Figure 9: Sequence diagram for the first case study. We read **inputs (from sensors)** via the node called **Modbus Read-%QX0.0-7** and read **outputs (actuators)** via **Modbus Read- %QX0.7+** node. We start with inputs from address 0, i.e., %QX0.0.