AIR724模块Modbus网关,实现MODBUS 和 MQTT、HTTP任意透传,对接OneNET、Aliyun、EMQTT
今天介绍重点功能,Modbus转MQTT网关。Modbus及DL645十分常用,但是现在主流通信协议已经是MQTT,实现modbus和mqtt双向映射非常有用。
固件和代码请查看Gitee, 对物联网技术感兴趣请加入我们交流群,欢迎各种技术交流,免费白嫖 QQ群: 830407941
对我们产品感兴趣请查看淘宝,免费定制项目:
DEVELOPLINK ______ Air724核心板
网关架构
功能设计
配置页面
DTU作为网关设备,实现Modbus RTU数据包和Json字串的映射,主要特征为:
- 支持的Modbus功能码:01,02,03,04,05,06,16
- 支持的Modbus数据类型:Short,Long, Float, BCD, Coils
- 支持的字节顺序:ABCD CDAB BADC DCBA
- 定义通用参数: 串口号、串口超时
- 以设备为单位定义采集指令,包含:采集周期,采集指令
- 以寄存器为单位定义映射字段,字段在不同设备之间需要保持唯一
- 上传通道功能: 按设计周期定时采集数据,校验CRC和超时,读取成功后转换为对应字段,按照设计的立即上传还是缓存上传上报数据
- 下行通道功能:接收下发的Json数据后,查询对应字段配置的设备ID和寄存器格式,组包后发送给设备
功能特点
- 自由设置采集指令,及对应Json字段
- 支持多个设备的混合组包,不同设备组成同一个Json
- 支持多种寄存器格式,包含Short,Long,Float及字节顺序,和Modbus Slave软件一致
- 无比强大钩子函数,结合远程脚本,可以实现任何设备的读取,数据计算、转换,任意格式的数据组包,直接对接任意云平台
使用实战
基本使用-连接到EMQTT Server
- 准备:
- 串口1通过485连接到Modbus Slave
- Modbus Slave设备ID为1,设置寄存器长度10
配置如图
- EMQ Mqtt连接配置
没什么好说的,测试服务器
- Modbus配置
定义设备ID1采集指令, 4个数据字段,采集周期10秒: 01030001000A
寄存器1类型short -> temp
寄存器4类型long -> humi
寄存器6类型float -> volt
寄存器8类型float -> current
先写入配置,开始通讯测试
4. 上行通道实验结果
打开Modbus slave 可以看到数据流:
000020-Rx:01 03 00 01 00 0A 94 0D
000021-Tx:01 03 14 56 78 12 34 56 78 56 78 12 34 43 7F A8 31 C1 23 33 33 00 00 98 77
打开Luatools查看log,可以看到组好的MQTT数据Json
[I]-[modbus full pub] {"humi":305419896,"temp":22136,"current":-10.199,"volt":255.656}
检查结果,和slave端设置一致,查看mqtt服务器端是否收到数据:
和预期一致。
5.下行通道实验结果
DTU订阅主题为:/device/sub/867435053902185
接下来组包数据,我们将数据 修改为{"humi":1552,"temp":100,"current":-110.5,"volt":512.6}
将此json发布到主题。
观察DTU端log信息:
[2020-11-21 14:55:18.557] [I]-[订阅的消息:] /device/sub/867435053902185
[2020-11-21 14:55:18.557] [I]-[modbus sub1] {"humi":1552,"temp":100,"current":-110.5,"volt":512.6}
[2020-11-21 14:55:18.557] [I]-[modbus sub2] 0110000400020400000610 11
[2020-11-21 14:55:18.582] [I]-[modbus sub2] 010600010064 6
[2020-11-21 14:55:18.582] [I]-[modbus sub2] 01100008000204C2DD0000 11
[2020-11-21 14:55:18.582] [I]-[modbus sub2] 0110000600020444002666 11
可以看到收到对应信息,并且按照字段组成了4条写指令,随后自动发往设备,接下来检查slave端数据。
可以看到寄存器1, 4, 6, 8 更新为配置的格式和值,可以看到实验结果和预期一致。
高级使用-对接OneNet
- 准备
Modbus延续上面的配置,Onenet采用新版物联网套件。OneNet配置为自动注册,详情参看连接教程。配置完DTU重启就自动连接平台了,而且自动订阅了对应主题。
OneNet和EMQ的区别是上传的数据必须要按照OneJson格式上传,比如
{
"id": 123,
"dp": {
"temperatrue": [{
"v": 30,
}],
"power": [{
"v": 4.5,
}]
}
}
DTU默认转换后的数据为Json,需要转换成的OneJson格式才能被平台识别。接下来在远程脚本里面通过Modbus钩子函数来构造我们自定义的数据包。
2. 自定义数据
新建脚本,输入以下代码:
require "log"
require "default"
require "modbus"
-- 这一句非常重要
module("remotedbg", package.seeall)
-- 下行数据的钩子
local function msgSubHook(data, uid)
log.info("modbus sub1", data.temp)
-- 下行数据我们把“temp” 改变一下
if data.temp then
data.temp = data.temp / 10
log.info("modbus sub2", data.temp)
return data
else
return nil
end
end
-- 上行消息的钩子,在这里构造onejson
-- cid: 网络通道
-- msg: 数据内容,table
local function msgPubHook(msg)
-- 包装上行数据
local buff = {id= 123, dp= {}}
for key, value in pairs(msg) do
buff.dp[key] = {{v=value}}
end
-- 转json上传
buff = json.encode(buff)
log.info("modbus pub msg", buff)
return buff
end
-- 设置钩子
modbus.setPubHook(msgPubHook)
modbus.setSubHook(msgSubHook)
DTU启动后可以看到上报的数据为
{"id":123,"dp":{"humi":[{"v":1552}],"temp":[{"v":100}],"current":[{"v":-110.499}],"volt":[{"v":512.599}]}}
查看onenet后台,可以看到数据已经上传
测试下发数据,对设备下发指令
{"id":123,"dp":{"humi":[{"v":1552}],"temp":[{"v":100}],"current":[{"v":-110.499}],"volt":[{"v":512.599}]}}
代码里面我们将下发的temp
数据缩小了10倍,查看log,符合预期
[2020-11-23 10:46:33.728] [I]-[modbus sub0] {"humi":2500,"temp":127,"current":-20.5,"volt":12.6}
[2020-11-23 10:46:33.728] [I]-[modbus sub1] table: 0x80d468d0
[2020-11-23 10:46:33.728] [I]-[modbus sub1] 12.7
[2020-11-23 10:46:33.728] [I]-[modbus sub2] 01100004000204C4090000 11
[2020-11-23 10:46:33.753] [I]-[modbus sub2] 01060001000C 6
[2020-11-23 10:46:33.753] [I]-[modbus sub2] 011000080002040000C1A4 11
[2020-11-23 10:46:33.753] [I]-[modbus sub2] 0110000600020449419A99 11
查看结果,temp被缩小10倍从127变为12,符合预期
结论: 对接到onenet成功,对接到其他平台同理
对物联网技术感兴趣请加入我们交流群,欢迎各种技术交流,
QQ群: 830407941
对我们产品感兴趣请查看淘宝,免费定制项目:
DEVELOPLINK
Air724核心板