Using Modbus with Node-RED

In manufacturing companies there is often a small set of production data, currently only available to an equipment operator through the HMI, which would be enormously valuable to a greater audience if there were some way to easily display and share it.

Node-RED, along with Modbus and Dashboard modules, can easily create a web-based dashboard, shareable with a weblink and viewable on any web browser on the network. Imagine the advantages of digital signage in the breakroom spurring healthy competition or a manager being able to check daily totals and live process values from the phone in their pocket.

What is Modbus

Modbus is a serial protocol that is often found in the industrial world to allow devices to communicate. Originally developed by Schneider Electric, it is an open protocol and has been adopted by brands across the industry. Simply Modbus is a terrific resource to learn more about how the communication is structured. The beauty of Node-RED’s low-code environment is that a user only has to understand Modbus at the highest level to be able to implement it.

The transport layer for Modbus can be either TCP over the Internet or RTU over RS-485/422/232. There is a client-server relationship among devices where the clients read and write data which is stored by server using a numerical address. There are four types of these addresses, 1) Output Coil and 2) Discrete Input addresses, which hold 1-bit data, and 3) Input Register and 4) Holding Register addresses, which hold 16-bit data. Typically a PLC will be the Server and an HMI will be the client, reading and writing to the memory in the PLC, in order to give an operator control over machinery.

What is an HMI

An HMI, or human machine interface, is a piece of software that allows an operator to use a machine. An HMI development environment typically allows programmers to choose among an array of digital assets to visualize the machine on the screen and create an intuitive interface to control the machine. The HMI software may also offload some of the high-level logic from the PLC, however, the time-critical lower-level logic should stay on the PLC. Node-RED can take this a step further, you may use it to create a simple HMI, but its real strength comes from its internet based heritage, and its ability to help share data from the PLC to the cloud.

Let’s look at the details of how you would use Node-RED for HMI and Modbus to build an HMI with Node-RED to connect Modbus data to a dashboard accessible from any web browser.

Installation of the Modbus package

The most popular package used for connecting Modbus devices is node-red-contrib-modbus; it has a wide range of configuration options and is well-documented in many blogs. On its own, this Modbus package just provides the means of communicating the 1-bit and 16-bit data. In doing so, your flow will be able to write 1-bit and 16-bit data to the PLC and read 1-bit and 16-bit data, which will arrive in an array. So, just like with other protocols (MQTT, HTTP, etc) fully integrating Modbus into your flow requires data manipulation and a well-thought-out schema for how this data will be packed into your msg objects. For example, below a payload of [false,false,false] comes in from a “Modbus Read” node, but how do you turn that into useful information? Maybe, you want to work with all alarms as a group, use a “Change” node to create a payload that is an object holding the related keys, with a topic that lets us know that these are all “alarms.”

Configuring the Modbus node

Note: for an even more comprehensive node to parse this data, check out node-red-contrib-buffer-parser by Flowforge’s own, Steve McLaughlin. To install, first click on the hamburger menu in the upper right of the Node-RED editor and then click on “Manage palette.”

Accessing the palette manager

Next, click on the “Install” tab, search for “modbus” in the search bar, and click on the “install” button next to node-red-contrib-modbus. As you can see there are many other custom nodes, but this one is a great jumping off point. It's always good to try other options too, and see what the community has to offer.

Installing the custom node

Finally, click on the “Install” button in the pop-up.

Installing the custom node

Success, your new set of nodes are ready to use.

The new nodes are now in the palette

Similarly, install one more package @flowfuse/node-red-dashboard. This package contains a set of widgets we will use to build a dashboard for visualizing data. For more information visit Node-RED Dashboard 2.0 Official website.

Bulding Modbus server

When using Modbus for communication, it is necessary to have a Modbus server, which acts as a middleman. In our case we are building that server on the Node-RED instance running on PLC running a motor turning a belt with a belt scale.

Configuring the Modbus server node

Add the Modbus server node and configure it as shown in the above image. This node is set to handle up to 1000 coils, discrete inputs, holding registers, and input registers. This means the server can manage up to 1000 binary states for control, monitor 1000 binary states, store up to 1000 read/write data points, and monitor 1000 read-only data points. Setting these parameters to 1000 allows the server to handle a broad range of devices and data points within your Modbus network, ensuring flexibility and scalability.

Sending data to Modbus server

To send data to the Modbus server, add two write nodes to the workspace. Double click on each node to configure them. Click on the pencil icon next to the "Server" field to add the Modbus server details. Once the server is added into one write node, it will be available for the other write node as well.

We have added two write nodes because we will be sending following simulated data to the server. One write node will handle coil data and the other will handle register data.

Example data from Modbus

For the first write node, set the quantity to 5 since we will be sending five types of coil data (isEStopReleased, isMotorSwitchedOn, isMotorRunning, isTailSwitchPulsing, isMaterialOnBelt ). For the second write node, set the quantity to 4 since we will be sending four types of register data( MotorAmps, motorHourMeter, beltTonsPerHour, and beltTotalTons ).

Configuring the Modbus send output coils write node

Configuring the Modbus send output coils write node

After configuring the nodes, add an inject node and set the msg.payload to "true" as a boolean for the coil data and set repeat to the "20 seconds" of interval. Then, add a join node to combine the messages into an array and connect the wires towards the write node configured for coil data.

Configuring the join node combine output coil data

Similarly, add another inject node and set the msg.payload to random() * 200 as a JSONata expression for the register data and set repeat to the "20 seconds" of interval. Use a join node to combine the 4 messages into an array and connect the wires towards the write node configured for register data.

Configuring the join node combine output coil data

Finally, you can add Modbus response nodes to see the data sent over modbus server.

Reading data from Modbus server

Now we will read that simulated that is getting sent on modbus server. All of this data is related so it has been grouped by consecutive numbers to make acquiring the data simpler. You can also group data by the rate you expect to be polling for it, so that your Modbus nodes don’t have to make several calls to collect the data. In the Modbus protocol the client specifies a start address and a number of subsequent addresses to read, and the server responds with all of this data at once. Creating groups allows much more efficient communication.

This PLC uses the coil/register numbering convention with output coils in the 0nnnnn format and the holding registers in the 4nnnnn format. Our Modbus nodes in Node-RED use a data address numbering convention which is zero-based, so we will have to remember to subtract 1 from the coils and registers.

Two “Modbus Read” nodes will work to capture these two types of data, coils and registers. Drag them into the flow and double click on one to start configuring them. First we will have to specify our Modbus Server, so click on the pencil icon to “add new.” In the next “Modbus Read” node we configure, we can just select our newly added server from the drop-down menu.

Adding a Modbus server

Let’s assume that your PLC is connected to your local area network and we will be communicating over TCP. Enter in the IP address of the PLC, the rest of the configuration can be left as-is. 502 is the default port for Modbus and generally the Unit-Id is 1, sometimes 0, sometimes ignored. The “Queues” and “Optionals” can stay as-is as well.

Setting the protocol and IP address

Click On “Add” and you will see your new server selected in the drop-down menu. Now let’s set this “Modbus Read” node to read our Coils once every second.

Setting how often data is read in the first Modbus read node

Similarly, set up the other “Modbus Read” node to read the holding registers. Click on the “Done” Button. Why the Modbus standard uses FC 3 to read the 4nnnnn registers and why there is both a zero-based and one-based convention is just a painful reality when using Modbus.

Setting how often data is read in the second Modbus read node

You can add some “Modbus Response” nodes to the “Modbus Read” nodes and click “Deploy” in order to see the data coming through, right in the editor.

Checking the data is arriving OK

Simple visualization

Finally, let’s create a dashboard of this incoming data using node-red-dashboard.

Example dashboard showing the data

“Change” nodes are an easy way to split apart the arrays of coils and registers into discrete messages.

Splitting up the data using change nodes

The msg.payload is set to the entry at the correct index of the incoming msg.payload array, and the msg.fontColor is set using conditional formatting of “green” and “red”, for true and false, respectively.

Image showing change node config for retrieving and setting data from an array read from Modbus.

The output coil data is displayed on the dashboard using a text widget. When the value is false, the color will be red; otherwise, it will be green, indicating the active status.

Configuring the change node

Image showing added style to the tempalate widget

Final flow is given below:

The way that we set up this example worked well for the small sample size and quickly getting content on the dashboard, but as you work through your own needs, think about the data structures that will be the most conducive to efficiently working with your data.