用几行Lua代码实现Modbus RS485和LoRa透传

用几行Lua代码实现Modbus RS485和LoRa透传

<目录>

用几行Lua代码实现Modbus RS485和LoRa透传
前言
Part1 透传描述
(1)Lora网络角色定义:
(2)下行通道透传说明(Modbus查询):
(3)上行通道透传说明(Modbus响应):
Part2 源代码和硬件


前言

Modbus RS485和LoRa透传的实现可以用 Lua 语言编程低代码实现,FlexLua 的可编程 DTU01 万能采集器同时具备 RS485接口和LoRa接口,所以用它再结合几行 Lua 代码即可实现透传。因为该采集器内置 Lua 编译器,开发者只需要将本文提供的代码文件烧录进该采集器即可运行。

844b2405bdcae660e9456b8666dec4d3.jpeg

Part1 透传描述

大致流程是:云端通过网关下发 Modbus Hex 字节流查询消息,Lora 子节点通过网关向云端返回 Modbus Hex 字节流响应消息。

dec211bcdfee478615bdf1b476c04d45.jpeg

(1)Lora网络角色定义:

  • 《DTU02万能网关》 作为 Lora 中心点
  • 《DTU01万能采集器》 作为 Lora 子节点

(2)下行通道透传说明(Modbus查询):

下行HEX数据格式举例说明(01 02 55 AA 02 01 01 01 03 00 00 00 02 C4 0B):

361ccb70a7667ba3a9e90785893af5ed.jpeg

RS485通信参数信息说明:例如当 5 -7 字节为 02 01 01时,表示需要 Lora子节点将其 RS485 接口设置为:波特率=9600,无校验,1位停止位。关于如何配置该值请参考《软件使用指导书(RS485LORAPASSIVE_HEX)》文档。

通信过程描述:

云端通过 以太网 下发一包 Hex 字节流消息,DTU02 Lora 中心点网关收到该消息后从该消息的前两个字节解析出需要转发的 Lora子节点地址,然后根据该地址通过Lora无线传输将后面的字节全部转发给对应的 DTU01 Lora 子节点,DTU01 Lora 子节点收到这些数据后,便可以通过RS485 Modbus读取相应传感器/仪器/设备的数据,并将数据原封不动返回给DTU02 Lora 中心点网关,具体流程举例如下:

--step1: 云端下发数据:01 02 55 AA 02 01 01 01 03 00 00 00 02 C4 0B,其中01 02 = 258,表示目标是地址=258的Lora子节点
--step2: 地址=258的Lora子节点将收到:55 AA 02 01 01 01 03 00 00 00 02 C4 0B
--step3: 55 AA 是固定值,02 01 01表示需要Lora子节点配置其RS485接口以<9600 N 1>参数通信
--step4: 随后Lora子节点将Modbus数据01 03 00 00 00 02 C4 0B通过RS485发送给相应的RS485设备以读取传感器/仪器/设备的s数据

云端 -> 以太网 -> Lora中心点网关 -> Lora子节点 -> RS485 Modbus。

(3)上行通道透传说明(Modbus响应):

上行HEX数据格式举例说明(01 02 01 03 04 01 E6 FF 9F 1B A0):

e5eb990a5faec7c863c99df5b2c3d3c7.jpeg

通信过程描述:

由上面的内容可知,DTU01 Lora 子节点通过RS485 Modbus读取到相应传感器/仪器/设备的Modbus响应数据后,会将该数据原封不动转发给DTU02 Lora 中心点网关,然后Lora中心点网关在该数据的基础上在前端插入两个字节的Lora子地址后,便将该数据通过以太网接口转发给云端,具体流程举例如下:

--step1: Lora 子节点通过RS485 Modbus获取到: 01 03 04 01 E6 FF 9F 1B A0 (Modbus响应数据)
--step2: 然后再将该数据原封不动发送给Lora中心点网关
--step3: Lora中心点网关在该数据的基础上在前端插入两个字节的Lora子地址(比如258)得到:01 02 01 03 04 01 E6 FF 9F 1B A0
--step4: 随后Lora中心点网关将01 02 01 03 04 01 E6 FF 9F 1B A0通过以太网接口发送给云端

RS485 Modbus -> Lora子节点 -> Lora中心点网关 -> 以太网 -> 云端。



Part2 源代码和硬件


----------------------配置信息----------------------
--Part1:Lora通信配置
--本机Lora子节点地址(范围:1-65535),用户可设置
LoraAddr = 1
--Lora通信信道(范围:410-441MHz)
LoraChn = 433
--Lora无线速率(范围:0.3, 1.2, 4.8, 9.6, 19.2kpbs)
LoraDdr = "9.6kpbs"
--Lora发射功率(范围:11, 14, 17, 20dB)
LoraTxPwr = "22dB"
--只有NetID相同的lora主从机之间才可通信(范围:0-255),该参数在多个Lora星型网络共存时有用
LoraSubNetID = 0
--等待RS485设备的最长应答时间,单位:毫秒
MbWaitTimeMs = 1000

----------------------固定值----------------------
--UART相关信息
BdrMap = {"BAUDRATE_4800","BAUDRATE_9600","BAUDRATE_19200","BAUDRATE_38400","BAUDRATE_115200","BAUDRATE_230400","BAUDRATE_460800","BAUDRATE_921600"}--1~8
PrtyMap = {"NoneParity","EvenParity","OddParity"}--1~3
StpBtMap = {"StopBit_1","StopBit_1_5","StopBit_2"}--1~3


--LIB_SystemLogEnable()
--配置D0,D1,D3为普通GPIO输出,控制LED_R,LED_G,LED_B
LIB_GpioOutputConfig("D0","STANDARD")
LIB_GpioOutputConfig("D1","STANDARD")
LIB_GpioOutputConfig("D3","STANDARD")
LIB_GpioWrite("D0",1)
LIB_GpioWrite("D1",1)
LIB_GpioWrite("D3",1)
--配置D11为普通输出,控制看门狗
LIB_GpioOutputConfig("D11","STANDARD")
--设置Lora模块占用TX0、RX0、Aux接D5引脚,Md0接D6引脚
--Lora通信参数:地址=1,通信信道=433M,无线速率=9.6kbps,发射功率=20dBm
LIB_LoraConfig("UART0","D5","D6",LoraAddr,LoraChn,LoraDdr,LoraTxPwr,LoraSubNetID)
--配置Uart1开始工作,并且D8引脚作为自动切换485收发芯片的引脚
--当用LIB_Uart1BlockSend发送时,D8会自动变成低电平,发送完后会立刻变成高电平
LIB_Uart1Rs485Config("BAUDRATE_9600","D8","NoneParity","StopBit_1")
--使能系统10毫秒定时器开始工作
LIB_10msTimerConfig("ENABLE")
LED_G_OnTimeMsCnt = 0
LED_R_OnTimeMsCnt = 0
DelayTimeMs = 0

--定义10毫秒定时器的回调函数,函数名字必须是LIB_10msTimerCallback
function LIB_10msTimerCallback()
LIB_GpioToggle("D11") --喂硬件看门狗
--绿色LED灯处理程序
if LED_G_OnTimeMsCnt >= 10 then
LED_G_OnTimeMsCnt = LED_G_OnTimeMsCnt - 10
LIB_GpioWrite("D1",0) --亮
else
LIB_GpioWrite("D1",1) --灭
end
--红LED灯处理程序
if LED_R_OnTimeMsCnt >= 10 then
LED_R_OnTimeMsCnt = LED_R_OnTimeMsCnt - 10
LIB_GpioWrite("D0",0) --亮
else
LIB_GpioWrite("D0",1) --灭
end
DelayTimeMs = DelayTimeMs + 10
end

--开始大循环
while(GC(1) == true)
do
--查询是否收到Lora中心点发来的无线数据
lora_flag,lora_addr,lora_data = LIB_LoraRecv()
if lora_flag == 1 then
--绿灯闪0.1秒
LED_G_OnTimeMsCnt = 100
--调试打印收到的Lora Hex数据
print("Recv(Lora):"..LIB_HexTabToHexStr(lora_data))
--提取出前5字节包含的baudrate、校验、停止位配置信息
if lora_data[1] == 0x55 and lora_data[2] == 0xaa and #lora_data > 5 then
--解析Uart参数:波特率,1~8
BdrSel = lora_data[3]
if BdrSel < 1 or BdrSel > 8 then
Baudrate = BdrMap[2]--9600bps
else
Baudrate = BdrMap[BdrSel]
end
--解析Uart参数:校验方式,1~3
PrtSel = lora_data[4]
if PrtSel < 1 or PrtSel > 3 then
Parity = PrtyMap[1]--NoneParity
else
Parity = PrtyMap[PrtSel]
end
--解析Uart参数:停止位,1~3
StpSel = lora_data[5]
if StpSel < 1 or StpSel > 3 then
StopBit = StpBtMap[1]--StopBit_1
else
StopBit = StpBtMap[StpSel]
end

--将收到的Lora无线数据从第6个字节开始原封不动的通过RS485串口发出去
--设置读取485传感器的波特率,校验方式,停止位
LIB_Uart1SetParam(Baudrate, Parity, StopBit)
SendTab = {}
for i=6,#lora_data do
SendTab[#SendTab+1] = lora_data[i]
end
LIB_Uart1BlockSend(SendTab)

--最多等待DelayTimeMs毫秒的应答时间
DelayTimeMs = 0
while DelayTimeMs < MbWaitTimeMs do
--判断是否收到485应答数据
rs485_flag,rs485_tab = LIB_Uart1Recv()
if rs485_flag == 1 then
--红灯闪0.1秒
LED_R_OnTimeMsCnt = 100
--调试打印收到的串口Hex数据
print("Recv(Rs485):"..LIB_HexTabToHexStr(rs485_tab))
--将收到的485串口Hex数据原封不动的通过Lora发回去
LIB_LoraSend(lora_addr, rs485_tab)
DelayTimeMs = MbWaitTimeMs --即然收到Lora数据了就提前退出等待
end
end
if rs485_flag ~= 1 then--通信超时
print(string.format("None RS485 data response in %d ms!", MbWaitTimeMs))
end
end
end
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值