Fox-Edge的ModBus的通用解码器,它只需要配置配置ModBus的模板文件,就可以进行ModBus报文协议的数据解析。
如果你的ModBus设备的命令比较简单,那么可以不使用模板,而是直接配置操作参数的方式,进行设备操作。
考虑到很多开发者手头上并没有MODBUS物理设备,可以先使用MODBUS设备模拟器进行新手上路。
等你能够对MODBUS设备模拟器进行操作之后,你可以将MODBUS模拟器替换为你手头上的MODBUS物理设备,就可以直接通信了。
推荐工具:
ModBus设备模拟器:ModbusSlave
ModBus客户端工具:ModbusPoll
你可以在下载和安装这两个工具之后,使用ModbusSlave模拟一个TCP的MODBUS设备,然后使用ModbusPoll工具使用TCP方式去连接这ModbusSlave。
这时候,你会看到ModbusPoll会循环读取ModbusSlave的表格数据,你在ModbusPoll上修改表格数据,它也会被配置到ModbusSlave中去。
很多开发者一开始没有接触过MODBUS,对MODBUS缺失概念,然后会摸不着头脑。
在MODBUS中,是一种类似内存地址的通信协议,它的数据放在连续的内存地址当中,只不过它的内存地址,在MODBUS中叫做寄存器。
我们的计算机每一个内存地址存放的是8位的数据,而MODBUS寄存器存放的是一个16位的数据。
设备厂商,通常会把MODBUS设备的数据放到一个个的寄存器中,你想对MODBUS设备进行操作的时候,就是读取寄存器数据和写入寄存器数据。
你对MODBUS设备的操作,就是读取和写入寄存器。
那么跟着对应的就是,每一个MODBUS设备的生产厂商,他们都会提供一个地址表,告诉你它在哪个寄存器上是如何存储内存数据的。
你对MODBUS设备的操作,就是根据设备厂商提供给你的那一份表,按整数、浮点数、定点数、布尔值,读取和写入数据到寄存器。
Fox-Edge提供了一个通过模板进行配置,就能快速操作MODBUS设备的办法。
假设,你的MODBUS设备是TCP连接,那么先从 组件仓库>服务模块 页面中安装 tcp-client 通道服务,用于跟MODBUS设备建立通信连接。
然后,你从 组件仓库>动态解码 安装 MODBUS 解码器,用于跟MODBUS设备通信需要的编码和解码
可以参考下列文件的格式,自己配置配置一个模板文件,那么可以让解码器装载这些模板文件,就可以自动解析数据
fox-edge
├─template
│ ├─modbus
│ │ └─1.0.0
│ │ └─101.CETUPS_Read System Measures Table.csv
│ │ └─100.CETUPS_Read Alarms And Events Table.csv
│ │ └─103.CETUPS_Input Status Table.csv
│ │ └─102.CETUPS_Coil Status Table.csv
| value_name | value_index | bit_index | bit_length | value_type | magnification | determine | remark |
|---|---|---|---|---|---|---|---|
| 对象名称 | modbus地址 | 该地址bit位 | 占用多少个bit | 数据类型 | 放大倍数 | 判定方式 | 备注 |
说明:ModBus解码器会根据这张表,对设备进行读取数据后,进行解析成方便用户理解的数据对象
1、value_index
也就是modbus中的地址偏移量。对于一个modbus偏移量来说,它的大小为16位的空间
2、bit_index和bit_length
有些设备厂家为了节省空间,会将一批告警状态数据保存在设备的某个ModBus地址偏移量当中。对于这种用一个16位地址
保存一批状态数据的设备,可以采用bit_index和bit_length自动分拆成一批对象
3、value_type
modbus设备的16位数据,可以被设备厂家们用来保存bool、int、float等数据格式,解码器会对这16位数据进行相应的解析
4、magnification
有些设备厂家,为了保存非常大数值的数据,会采用定点数的方式,在16位mosbus地址空间上,约定放大了一定的倍数保存。
5、determine
对于bool类型的数值,什么时候是true,什么时候是false,厂商们通常会有特定的数值约定,可以通过判定方式判定具体的bool数值
说明:
具体内容,可以参考101.CETUPS_Read System Measures Table.csv文件内容
在本地计算机上,安装好下面两个MODBUS工具,用于模拟MODBUS设备的客户端
ModBus设备模拟器:ModbusSlave
ModBus客户端工具:ModbusPoll
根据默认配置,你可以在ModbusPoll上,连接到ModbusSlave,并读取到ModbusSlave上的表格数据。
而且,你在ModbusPoll上的表格修改数据,也会被发送到ModbusSlave上修改。
你测试这对MODBUS模拟器工具通过后,就可以在Fox-Edge跟它ModbusSlave进行连接了
在Fox-Edge上的 组件仓库>服务模块 选择安装TCP或者Serial通道服务。
在Fox-Edge上的 组件仓库>动态界面 选择安装MODBUS解码器
在Fox-Edge上的 通道管理>通道列表 添加一个TCP或者Serial的通道
如果是TCP参数,它的格式范例如下:
{
"host": "192.168.1.8",
"port": 502
}
其中,host/port是你的MODBUS设备的服务地址,目前是ModbusSlave这个设备模拟器的服务地址,由于ModbusSlave安装在你的计算机上,那么它就是你笔记本的IP。
如果是Serial参数,它的格式范例如下:
{
"baudRate": 9600,
"databits": 8,
"parity": "N",
"serialName": "ttyUSB2",
"stopbits": 1
}
如果你安装了 本地组件/设备模板 ,那么你可以直接生成默认的通道配置参数
在Fox-Edge上的 通道管理>设备列表 添加一个MODBUS设备,指明该设备使用的是前面创建的通道
并在参数配置中,填写MODBUS的地址和协议模式
如果是TCP参数,它的格式范例如下:
{
"devAddr": 1,
"modbusMode": "TCP"
}
同样,如果你是串口,那么你的工作模式应该填为RTU
{
"devAddr": 1,
"modbusMode": "RTU"
}
如果你安装了 本地组件/设备模板 ,那么你可以直接生成默认的设备配置参数
在Fox-Edge上的 任务管理>通道操作任务 添加一个连通性测试任务,用于测试跟MODBUS设备是否连接上了。
你可以在ModbusSlave或者ModbusPoll的通信日志页面,取一条有效的通信报文,作为验证报文。
例如你是TCP通信,你在ModbusSlave的通信日志页面,复制一条通信数据内容如下:
"1B 51 00 00 00 06 01 03 00 00 00 0A"
这时候,你可以把该内容填写到模板参数中
这时候,你选择该任务后,点击页面中的发送按钮,你可以看到ModbusSlave给你返回了一段报文:
{
"type": "tcp-client",
"uuid": "25364b96-06a5-49d0-bbe2-534e0abc6dd4",
"name": "测试通道-MODBUS",
"mode": "exchange",
"send": "1B 51 00 00 00 06 01 03 00 00 00 0A",
"recv": "1b5100000017010314006f029a00000000000000000000000000000000",
"timeout": 2000,
"msg": "",
"code": 200
}
recv有数据,这时候说明你的通道连接,跟ModbusSlave是正常的,它能够应答你的Fox-Edge上的HEX报文请求。
在Fox-Edge上的 任务管理>设备操作任务 MODBUS设备操作任务,比如 Read Holding Register 的操作任务。
参数说明:
{
"devAddr": 1,---------------------------设备地址
"modbusMode": "TCP",--------------------MODBUS的工作模式:TCP/RTU
"modelList": [--------------------------告知MODBUS解码器,数据如何编码/解码
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "0号寄存器",
"value_index": "0",
"value_name": "温度",
"value_type": "int"
},
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",--------放大/缩小倍数:默认1,也就是x1
"remark": "1号寄存器",
"value_index": "1",----------寄存器的地址,是1
"value_name": "湿度",--------这个数据对象的名称:湿度
"value_type": "int"----------寄存器数据的格式是int
}
],
"regAddr": 0,--------------------------告知解码器,从0号寄存器开始,连续读取2个寄存器
"regCnt": 2
}
范例:
{
"devAddr": 1,
"modbusMode": "TCP",
"modelList": [
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "0号寄存器",
"value_index": "0",
"value_name": "温度",
"value_type": "int"
},
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "1号寄存器",
"value_index": "1",
"value_name": "湿度",
"value_type": "int"
}
],
"regAddr": 0,
"regCnt": 2
}
这时候,你选择该任务后,点击页面中的发送按钮,你可以看到ModbusSlave给你返回了一段报文:
[
{
"uuid": "8b843b8a-d6e9-4444-8a7f-a938ae9d251b",
"operateMode": "exchange",
"operateName": "Read Holding Register",
"manufacturer": "广州灵狐技术有限公司",
"deviceType": "MODBUS",
"deviceName": "测试设备:MODBUS",
"param": {
"devAddr": 1,
"modbusMode": "TCP",
"modelList": [
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "0号寄存器",
"value_index": "0",
"value_name": "温度",
"value_type": "int"
},
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "1号寄存器",
"value_index": "1",
"value_name": "湿度",
"value_type": "int"
}
],
"regAddr": 0,
"regCnt": 2
},
"timeout": 2000,
"record": true,
"data": {
"commStatus": {
"commFailedCount": 0,
"commFailedTime": 0,
"commSuccessTime": 1753800297247-------通信成功了,操作成功的时间
},
"value": {
"status": {
"温度": 111,---------------------可以看到数据被读取到,并解析为温度111读
"湿度": 42
}
}
},
"msg": "",
"code": 200---------------------------------------操作成功
}
]
上面的返回,说明你对MODBUS设备已经正常访问了
通过上面的操作,你可以简单的访问MODBUS设备了,但是MODBUS的设备,它往往是比较多的寄存器的。
所以,Fox-Edge提供了设备模板的方案,在上面的基础上进行简化配置。
用户可以先下载CSV模板
将厂商提供的MODBUS数据定义表,按CSV文件的固定格式写入CSV文件中
将CSV文件的内容,复制到线上网站 https://wejson.cn/csv2json/ 将CSV格式转换为JSON格式。
实际上,这个CSV模板转为JSON后,对应的就是前面的JSON格式的modelList的参数
"modelList": [
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "0号寄存器",
"value_index": "0",
"value_name": "温度",
"value_type": "int"
},
{
"bit_index": "0",
"bit_length": "16",
"determine": "",
"magnification": "1",
"remark": "1号寄存器",
"value_index": "1",
"value_name": "湿度",
"value_type": "int"
}
]
回到Fox-Edge的 本地组件/动态模板 中,创建一个动态模板,指明为MODBUS引擎,然后网站上转换的JSON格式模板内容,贴入配置参数中。
记住这个名称,例如你会在模板中看到:广州灵狐技术有限公司|测试MODBUS设备|保持寄存器地址表
那么,后面你就可以反复使用这个模板,应用到其他Fox-Edge项目中。
在Fox-Edge上的 任务管理>设备操作任务 MODBUS设备操作任务,比如 Read Holding Register 的操作任务。
使用模板进行操作设备,将前面的modelList换成modelName
{
"devAddr": 1,
"modbusMode": "TCP",
"modelName": "广州灵狐技术有限公司|测试MODBUS设备|保持寄存器地址表",
"regAddr": 0,
"regCnt": 2
}
通过动态模板modelName,你可以简化大量的配置,而通过动态模板modelList,你可以逐个验证每个寄存器的配置。
在Fox-Edge上的 任务管理>设备监控任务 添加一个设备监控任务,用于自动采集MODBUS设备的数据。
你将前面在 任务管理>设备操作任务 验证过的一个个手动操作任务,将内容复杂到 任务管理>设备监控任务 之中。
然后,设备监控任务会根据你的任务编排,周期性的采集数据。
最后,将采样到的数据,发送给持久化服务中,保存到redis和mysql数据库中,那么后面其他服务就可以消费这些数据了。
"1B 51 00 00 00 06 01 03 00 00 00 0A"
这时候,你可以把该内容填写到模板参数中
这时候,你选择该任务后,点击页面中的发送按钮,你可以看到ModbusSlave给你返回了一段报文:
{
"type": "tcp-client",
"uuid": "25364b96-06a5-49d0-bbe2-534e0abc6dd4",
"name": "测试通道-MODBUS",
"mode": "exchange",
"send": "1B 51 00 00 00 06 01 03 00 00 00 0A",
"recv": "1b5100000017010314006f029a00000000000000000000000000000000",
"timeout": 2000,
"msg": "",
"code": 200
}
recv有数据,这时候说明你的通道连接,跟ModbusSlave是正常的,它能够应答你的Fox-Edge上的HEX报文请求。