Using Modbus on Arduino Mega with OpenPLC

July 8, 2024 by
Boot & Work Corp. S.L., Arnau Tena

First steps

In this bog we assume you've already somewhat familiarized yourself with OpenPLC, but if that's not the case, you can find all the information you need to get started in this other blog:

First steps with OpenPLC and Arduino Mega

Setting up the ladder diagram

To help you learn how Modbus works with OpenPLC, the Arduino will act as a slave and generate two signals that will be sent through Modbus to a master. The master will be able to stop this process. Like in the previous blog, we'll be using the Blink example as a template for our test, you can find it in "File > Tutorials and Examples > 2: Blink".

Now, on the variables table create two new variables, named "blink_led_off" and "global", set them both to "BOOL" type and set the initial value of "global" to 1. The "global" variable will be used to stop the entire process.


Then, use the variable tool to place the "blink_led_off" as an output, and connect it to the right of the negated "blink_led" contact.

And then use the contact tool to place the "general" variable just before the "blink_led" coil.


If you compile and debug the instance, you should see how "blink_led_off" always takes the negated value of "blink_led".

Modbus addressing

Now that the ladder diagram is working as intended, it's time to understand how OpenPLC manages the Modbus addressing. When Modbus is enabled in the "Transfer Program to PLC" menu, the required functionallity to update the coils and registers will be automatically added to the compiled code.

OpenPLC will assign Modbus addresses in a sequential way to every input and output of the board. In the case of the Arduino Mega, the digital output pins are assigned to the IEC 61131-3 addresses %QX0.0 - %QX2.7, which are assigned to the Modbus coil addresses 0 - 23. 

We will assigning coil addresses to our viariables, which allow both reading and writing. Set the location of "blink_led" to %QX1.0, "blink_led_off" to %QX1.1 and "global" to %QX0.7. You can easily convert IEC 61131-3 to Modbus coil addresses by multiplying the first number by 8 and adding the second number to it, so %QX1.1 would be 8*1+1=9. The end result will be:

  • "global": %QX0.7 -> coil 7.
  • "blink_led": %QX1.0 -> coil 8.
  • "blink_led_off": %QX1.1 -> coil 9.

You can learn more about the way OpenPLC manages Modbus addresses here:

Modbus addressing

Like we did in the previous blog, we can use the Arduino Mega's in-built LED to visualize the changes taking place in our code. If you want to use it, add a new variable named "ledMega", set it to "UINT" type, location %QW11, and add these blocks:

Modbus testing

As a slave, the Arduino Mega needs to serve a master. We will use a master simulator on a computer and connect it to the Arduino through USB.

First we have to upload the code to the Arduino board. In the "Transfer Program to PLC" menu, scroll down to the "Communications" tab and enable the Modbus RTU option. We will be using these parameters:


Then go back to the "Transfer" tab and upload the code. If you decided to add the LED functionallity, you should already see the LED blinking every haf a second.

Now download the Radzio master simulator:

Radzio! Modbus Master Simulator

First we have to configure the connection settings. With Radzio opened, go to "Connection > Settings" and set it up like this:

Now go to "Setup > Data definition" and set the scan rate to 100ms.

Create a new page by clicking on "File > New". Set the "Device ID" to 1 and the length to 10.


Now everything should be ready to communicate with the Arduino board. Click on "Connection > Connect" to start communicating with the board. You should see the coils 8 and 9 changing values every 500ms while the coil 7 is constantly at 1.

If you double click on the value of the coil 7, you can set it to Off. This will set the "global" variable to 0 and stop the entire process, so the coils 8 and 9 should stop changing values. This will also turn off the in-built LED if you decided to implement it.

Make sure to disconnect Modbus on Radzio before uploading any new code to the PLC, or you'll encounter errors in OpenPLC Editor.

With this, you'll have achieved successfull Modbus communication with an Arduino Mega through OpenPLC.

Next blog:

OpenPLC on M-Duino 42+

​Search in our Blog

Boot & Work Corp. S.L., Arnau Tena July 8, 2024
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 >>>