ModbusPal模拟器使用说明
一、 工具介绍
ModbusPal是一个开源工具,用于模拟和测试 Modbus 设备和网络。它允许用户创建虚拟的 Modbus 从站(Slave),并配置这些从站的寄存器和通信参数,从而方便地测试 Modbus 主站(Master)的通信和操作。
ModbusPal主要有以下优势:
- 可以通过脚本方式快速部署模拟器,且支持TCP端口的自定义
- 从站寄存器值可通过模拟函数随机生成
- 开源免费
本文主要介绍如何部署ModbusPal模拟器及自行定制的方式。同时也会介绍如何在Node-Red上读取ModbusPal模拟生成的数据。
二、 工具源码及二次开发说明
ModbusPal的工具源码可从https://sourceforge.net/p/modbuspal/code/HEAD/tree/获取。需要说明的是,开源发布的最新版本是1.6c。但本文介绍的ModbusPal是在1.6c的基础上经过二次开发生成的。
之所以需要进行二次开发,主要是因为ModbusPal支持配置同一IP同一端口下配置多个Slave。但据此生成的配置文件在ModbusPal重启后会无法导入。相关调用栈如下:
6月 12, 2024 2:59:04 下午 modbuspal.main.ModbusPalPane$20 run
严重: null
java.lang.NullPointerException: Cannot invoke "modbuspal.slave.ModbusSlaveAddress.getIpAddress()" because "id" is null
at modbuspal.main.ModbusPalProject2.getMatchingSlaveAddress(ModbusPalProject2.java:178)
at modbuspal.main.ModbusPalProject2.getModbusSlave(ModbusPalProject2.java:204)
at modbuspal.main.ModbusPalProject2.getModbusSlave(ModbusPalProject2.java:270)
at modbuspal.main.ModbusPalProject.addModbusSlave(ModbusPalProject.java:1275)
at modbuspal.main.ModbusPalProject.loadSlaves(ModbusPalProject.java:377)
at modbuspal.main.ModbusPalProject.<init>(ModbusPalProject.java:155)
at modbuspal.main.ModbusPalProject.load(ModbusPalProject.java:100)
at modbuspal.main.ModbusPalPane.loadProject(ModbusPalPane.java:1355)
at modbuspal.main.ModbusPalPane$20.run(ModbusPalPane.java:1949)
at java.base/java.lang.Thread.run(Thread.java:1583)
为解决以上问题,对ModbusPal进行了二次开发,相关PATCH如下:
diff --git a/src/modbuspal/main/ModbusPalProject.java b/src/modbuspal/main/ModbusPalProject.java
index 2dcfdb8..35d1b17 100644
--- a/src/modbuspal/main/ModbusPalProject.java
+++ b/src/modbuspal/main/ModbusPalProject.java
@@ -488,8 +488,18 @@ implements ModbusPalXML
slaveAddress = XMLTools.getAttribute(ModbusPalXML.XML_SLAVE_ID_ATTRIBUTE, parentSlave);
try
{
- ModbusSlaveAddress msa = new ModbusSlaveAddress( InetAddress.getByName( slaveAddress ) );
- slave = getModbusSlave(msa);
+ ModbusSlaveAddress msa;
+ int openParenIndex = slaveAddress.indexOf('(');
+ if (openParenIndex == -1) {
+ msa = new ModbusSlaveAddress( InetAddress.getByName( slaveAddress ) );
+ } else {
+ String ipaddress = slaveAddress.substring(0, openParenIndex);
+ msa = new ModbusSlaveAddress( InetAddress.getByName(ipaddress));
+ int closeParenIndex = slaveAddress.indexOf(')');
+ String rtu_id = slaveAddress.substring(openParenIndex + 1, closeParenIndex);
+ msa.setRtuAddress(Integer.parseInt(rtu_id));
+ }
+ slave = getModbusSlave(msa);
}
catch (UnknownHostException exception)
{
diff --git a/src/modbuspal/slave/ModbusSlave.java b/src/modbuspal/slave/ModbusSlave.java
index 927f76e..91680e5 100644
--- a/src/modbuspal/slave/ModbusSlave.java
+++ b/src/modbuspal/slave/ModbusSlave.java
@@ -635,7 +635,16 @@ implements ModbusPalXML, ModbusConst
String id = XMLTools.getAttribute(XML_SLAVE_ID_ATTRIBUTE, node);
try
{
- slaveId = new ModbusSlaveAddress( InetAddress.getByName( id ) );
+ int openParenIndex = id.indexOf('(');
+ if (openParenIndex == -1) {
+ slaveId = new ModbusSlaveAddress( InetAddress.getByName( id ) );
+ } else {
+ String ipaddress = id.substring(0, openParenIndex);
+ slaveId = new ModbusSlaveAddress( InetAddress.getByName(ipaddress));
+ int closeParenIndex = id.indexOf(')');
+ String rtu_id = id.substring(openParenIndex + 1, closeParenIndex);
+ slaveId.setRtuAddress(Integer.parseInt(rtu_id));
+ }
}
catch (UnknownHostException exception)
{
三、 ModbusPal基本使用
1. 软件依赖
1.1 OpenJDK
ModbusPal是使用Java开发,其形态为一个JAR(Java Archive)包。因此要运行ModbusPal,需要安装JDK环境。在Windows上安装JDK环境可使用微软官方提供的JDK安装包,见:https://www.microsoft.com/openjdk。
1.2 RXTX
RXTX是一个开源的Java库,用于通过串行和并行端口进行通信。它提供了对串行通信的访问,使得Java应用程序能够读取和写入串口数据。ModbusPal使用该库进行串口通信。因此在安装JDK后,需要将rxtx相关的库文件拷贝到JDK目录下。假设安装的Microsoft OpenJDK的安装路径为C:\Program Files\Microsoft\jdk-21.0.3.9-hotspot,那么需要将rxtxParallel.dll和rxtxSerial.dll两个文件拷贝到C:\Program Files\Microsoft\jdk-21.0.3.9-hotspot\bin目录下。
需要注意的是,rxtxParallel.dll和rxtxSerial.dll 这两个文件在windows上有x86和x64平台之分。还需要根据使用的windows平台选择合适的代码库文件。
2. 软件启动
ModbusPal的启动指令比较简单,主要有两种情况:
- 无配置文件启动:
java -jar ModbusPal.jar
- 使用配置文件启动:
java -jar ModbusPal.jar -loadFile=”<配置文件地址>”
3. 软件界面
软件的初始界面如下:
从上图可以看到,软件上主要分为五个区域:Link settings、Project、Tools、Modbus Slave、Automation。下面简单介绍界面这五个区域的作用:
3.1 Link settings
该区域我们主要关注”TCP/IP“页面的配置。”Serial”和“Replay”页面不在讨论范围,有兴趣的同事可以自行摸索。
在该区域中主要使用的功能有:
- 配置端口号(默认为502)
- 运行模拟器(Run按钮)
- 运行状态显示
上图中灰色图像即为模拟器运行状态指示。共有三种情况:
- 与Modbus Master的通信断开,图像会显示为默认灰色。
- 与Modbus Master通信建立,但存在通信异常(如地址错误等),图像会显示为红色。
- 与Modbus Master通信建立且通信正常,图像为显示为绿色。
3.2 Project
该区域我们主要关注”load”按钮和“Save”按钮。前者是导入ModbusPal的配置文件,后者是将当前在ModbusPal上的配置保存为配置文件。配置文件的后缀为xmpp。
3.3 Tools
该区域我们主要关注”Console”按钮。该按钮显示Java运行日志,常用于问题定位。
3.4 Automation
该区域主要用于配置自动生成器,即用于寄存器的数据生成。生成器有三类:线性、随机、正弦波。以配置线性生成器为例,点击 “Add”按钮添加一个生成器。我们可以在出现的生成器上修改生成器名字,如下:
点击生成器右侧的眼睛图标,会出现生成器的配置界面,我们可以根据实际情况对生成器的配置进行修改。如下图所示,我们创建一个线性生成器,然后配置最小值为1,最大值为3600,生成周期为3600秒:
其它两类生成器的配置逻辑接近,此处不再赘述。
3.5 Modbus Slave
该区域主要用于配置Slave节点,假设Master设备的IP地址为192.168.1.1,我们需要创建10个字节,Slave ID从1到10。那么点击该区域的“Add”按钮之后,会弹出一个Slave配置界面,我们可以输入“192.168.1.1(1-10)”,如下:
点击上面区域的“Add”按钮之后,将会在Modbus Slave区域生成10个从设备,如下:
我们可以点击某个设备右侧的眼睛按钮,弹出寄存器配置界面,如下:
在该界面中,我们可以点击 “Add”按钮创建寄存器,如下创建地址40001 ~ 40010共10个寄存器:
点击“Add”按钮之后,我们可以看到这个节点在Holding Registers中有10个寄存器,每个寄存器的默认值为0:
我们可以手动给这些寄存器配置不同的值,也可以将某个寄存器的值与生成器绑定。比如若需要将40001和前面创建的生成器绑定,则可以选择40001这个寄存器,然后点击 “Bind”按钮,弹出绑定界面:
绑定之后,当我们启动生成器时,可以在该界面看到寄存器的值一直在变化,如下:
4 示例:配置ModbusPal并通过Node-Red获取Modbus数据
我们通过一个简单的例子来熟悉ModbusPal的使用。
- 在PC(IP:192.168.1.10)上配置一个Modbus Slave节点,Master IP地址为192.168.1.1,Slave ID为1,寄存器配置为Holding Registers,地址为40001 ~ 40010,其中40001地址的值配置为2,TCP端口配置为502。如下:
- 点击Run启动模拟器
- 在设备侧(IP:192.168.1.1)启动Node-Red服务,并配置Node-Red节点。需要注意的是,如果Node-Red没有安装modbus相关节点,需要在节点管理中安装node-red-contrib-modbus,如下:
- Node-Red中Modbus Client节点配置如下:
- Node-Red中Modbus-Read节点配置如下。此处需要注意的是,ModbusPal中的寄存器地址是以1为起始,而Node-Red中是以0为起始,所以寄存器起始地址要写为40000
- 添加一个Modbus Response节点用于显示信息。部署之后效果如下:
完整的Node-Red Json可见附件flows.json
四、 批量部署ModbusPal模拟器
本节主要介绍如何使用已有的配置文件批量部署ModbusPal模拟器。
- 以前面示例中ModbusPal的配置为例,我们配置后将其保存为配置文件,命名为template.xmpp。
- 修改template.xmpp,生成模板文件。template.xmpp文件内容如下:
- 我们需要将其修改为模板文件,将端口502替换为{port},将IP地址192.168.1.1替换为{device_ip},将节点名D1替换为{device_name}。替换后的文件如下:
- 使用windows powershell运行脚本run.ps1,根据模板文件生成批量配置文件。run.ps1脚本可见如下文件。
需要注意的是:
- 该脚本还需要两个参数:Master端的IP地址,需要部署的模拟器数量。
- template.xmpp需要和脚本放置在同一目录下。