首页 > 其他分享 >DIY一个以太网转RS485 Modbus网关

DIY一个以太网转RS485 Modbus网关

时间:2024-04-01 12:33:18浏览次数:23  
标签:网关 LIB -- RS485 u0 SendData CH9121 以太网

DIY一个以太网转RS485 Modbus网关

69314642dcb098e5dbf57e239b0c809f.jpeg

1 实现功能

基于 FlexLua DTU01万能采集器实现 以太网 通信和 RS485 通信之间的数据透传,以太网接入服务器的方式为 Tcp Server。

  • 在 以太网 通信链路上,DTU01 和 远端服务器通信数据格式为 HEX 字节流
  • 在 485 通信链路上,DTU01 和 RS485 节点通信数据格式为 HEX 字节流

eac9176926076aa6f05b0080df63b7ad.jpeg

下行通道举例:例如当远端的 TCP 服务器向 DTU 发送 0x08 0x09 0x0A,则 DTU 在收到这些数据后会原封不动通过 485总线 将 0x08 0x09 0x0A 转发给RS485 节点。

上行通道举例:例如当 RS485 节点向 DTU 发送 0x01 0x02 0x03,则 DTU 在收到这些数据后会原封不动通过 以太网 将 0x01 0x02 0x03 转发给远端的服务器。

建议:由于 DTU01 是 Tcp Server ,远端服务器是 Tcp Client,所以整个系统不适合双向随机透传数据。建议由远端服务器发起数据传输,进而等待RS485节点回复应答数据。

2 实现方法

(1)硬件

f4eec52476d137616c767461a4d0d8a7.jpeg

由于 DTU01 的硬件接口是可配置的,所以需要确认一下您手上的 DTU01 采集器是否满足要求,如果确认已满足就无需再做任何操作,否则请按《DTU01硬件使用指导书》完成下面的硬件配置:

  • DTU01 电路板上的 ‘A’ 和 ‘B’ 引脚需配置成 485 接口的 ‘A’ 和 ‘B’,即 S3 选择
  • DTU01 电路板正面焊接上 SB-C18 以太网通信模块
  • DTU01 电路板上的 ‘+’ 和 ‘-’ 电源输出引脚配置成 12v 输出用来接12v的传感器/仪表/设备(非必须)

《DTU01硬件使用指导书》可在 {FlexLua开源网盘}->{Hardware}->{DTU01万能采集器}->{DTU01硬件使用指导书} 文件夹中找到。

(2)软件

只需将本文章末尾提供的源码拷贝覆盖至设备上的 main.lua 文件中,并根据实际情况修改源码开头部分的配置信息,即可实现大部分场景的需求。

操作方法:首先用TypeC USB数据线将设备和电脑连接,然后在电脑上会自动出现一个1.6MB大小的U盘(如果U盘大小是0MB,则需用FAT32快速格式化该盘),找到 main.lua 代码文件(如果没有请自行创建一个 main.lua文件),然后将本文的源码拷贝覆盖至 main.lua 文件中然后Ctrl+S保存即可,代码更新后在下次重新上电后其会自行编译并运行。

3 源代码

下面贴出完整的源代码,但是可能在网页上展示格式比较混乱,看源代码的话可以在 FlexLua 官网的 C004A 文档中找到源码。

----------------------配置信息开始------------------------
--Part1: 以太网参数配置:TCP Server 静态IP示例(本机IP=192.168.0.35,本机端口号=40001)
ROLE = {0x00} --0x00:TCP Server, 0x01:TCP Client, 0x02:UDP Server, 0x03:UDP Client
SRCPORT = {0x41,0x9c} --源端口号,例如40001=0x9c41
DHCP = {0x00} --0x00关闭DHCP, 0x01使能DHCP
SRCIP = {192,168,0,35} --源IP地址
GATEWAY = {192,168,0,1}--网关地址
SUBNET = {255,255,255,0} --子网掩码
DESPORT = {0,0} --目的端口号,无需配置
DESIP = {0,0,0,0} --目的IP地址,无需配置

--Part2:RS485 通信配置
Rs485BaudRate = "BAUDRATE_9600"
--串口校验设置
Rs485ParitySet = "NoneParity" --"NoneParity","EvenParity","OddParity"
--串口停止位设置
Rs485StopBitSet = "StopBit_1" --"StopBit_1","StopBit_1_5","StopBit_2"

----------------------配置信息结束------------------------

--外围设备GPIO分配
CH9121_RSTI = "D6"
CH9121_CFG = "D5" --DTU01电路板没有连接CFG引脚,所以不能用CFG引脚方式配置以太网模块,必须要用协商方式(该方式需要提前用Wch厂家提供的上位机开启)

-------------------全局变量(可变值)-------------------
RedLedTimeMsCnt = 0
GreenLedTimeMsCnt = 0
EthLostContactTimeMsCnt = 0 --以太网故障计时器

--CH9121以太网模块写命令和数据
function Ch9121Write(cmd, data)
LIB_GpioToggle("D11") --喂硬件看门狗
SendData = {0x57,0xab}
SendData[#SendData+1] = cmd
for i=1,#data do
SendData[#SendData+1] = data[i]
end
--发送数据包
LIB_Uart0Send(SendData)
LIB_DelayMs(100)--延时不能低于100ms,不然会有个别指令收不到回复
--查询Uart0是否收到0xaa应答
u0_flag,u0_tab = LIB_Uart0Recv()
if u0_flag == 1 and u0_tab[1] == 0xaa then
print(string.format("Ch9121 0x%02x wr ok, Send=",cmd)..LIB_HexTabToHexStr(SendData).."\r\n")
else
print(string.format("Ch9121 0x%02x wr fail, Send=",cmd)..LIB_HexTabToHexStr(SendData).."\r\n")
end
end

--CH9121以太网模块读命令和数据
function Ch9121Read(cmd)
LIB_GpioToggle("D11") --喂硬件看门狗
SendData = {0x57,0xab}
SendData[#SendData+1] = cmd
--发送数据包
LIB_Uart0Send(SendData)
LIB_DelayMs(100)--延时不能低于100ms,不然会有个别指令收不到回复
--查询Uart0是否收到应答
u0_flag,u0_tab = LIB_Uart0Recv()
if u0_flag == 1 then
print(string.format("Ch9121 0x%02x rd ok, Recv=",cmd)..LIB_HexTabToHexStr(u0_tab).."\r\n")
else
print(string.format("Ch9121 0x%02x rd fail, Send=",cmd)..LIB_HexTabToHexStr(SendData).."\r\n")
end
end

--CH9121初始化
function Ch9121Init()
LIB_GpioOutputConfig(CH9121_RSTI,"STANDARD")
LIB_GpioOutputConfig(CH9121_CFG,"STANDARD")
--CH9121复位
LIB_GpioWrite(CH9121_RSTI,0)
LIB_DelayMs(100)
LIB_GpioWrite(CH9121_RSTI,1)
LIB_DelayMs(200)--这里需要延时
LIB_GpioToggle("D11") --喂硬件看门狗
--CH9121进入配置模式(CFG引脚方式)
LIB_GpioWrite(CH9121_CFG,0)--DTU01没接CFG,此种配置方式无效!
LIB_DelayMs(100)
--CH9121进入配置模式(串口协商方式)
LIB_DelayMs(500)
SendData = {0x55,0xaa,0x5a}
LIB_Uart0Send(SendData)--发送 55 aa 5a
cnt = 0
while cnt < 500 do --500ms内等待ch9121回复a5
LIB_DelayMs(1)
LIB_GpioToggle("D11") --喂硬件看门狗
cnt = cnt + 1
u0_flag,u0_tab = LIB_Uart0Recv()
if u0_flag == 1 and u0_tab[1] == 0xa5 then
break
end
end
if cnt >= 500 then
print("Ch9121 init fail, system reset!")
LIB_GpioWrite("D3",0) --蓝灯亮3秒后重启
LIB_GpioToggle("D11") --喂硬件看门狗
LIB_DelayMs(3000)
LIB_SystemReset()
end

SendData = {0xa5}
LIB_Uart0Send(SendData)--发送 a5
cnt = 0
while cnt < 500 do --500ms内等待ch9121回复a5
LIB_DelayMs(1)
LIB_GpioToggle("D11") --喂硬件看门狗
cnt = cnt + 1
u0_flag,u0_tab = LIB_Uart0Recv()
if u0_flag == 1 and u0_tab[1] == 0xa5 then
break
end
end
if cnt >= 500 then
print("Ch9121 init fail, system reset!")
LIB_GpioWrite("D3",0) --蓝灯亮3秒后重启
LIB_GpioToggle("D11") --喂硬件看门狗
LIB_DelayMs(3000)
LIB_SystemReset()
end

LIB_DelayMs(20)

--读取芯片MAC地址
mac_ok,mac = Ch9121Read(0x81)
if mac_ok == 1 and #mac == 6 then
print("Mac:"..LIB_HexTabToHexStr(mac))
end
Ch9121Write(0x10,ROLE) --0x00:TCP Server, 0x01:TCP Client, 0x02:UDP Server, 0x03:UDP Client
--配置网络信息(目的IP和端口号配置),仅当Client时有效
if ROLE[1] == 0x01 or ROLE[1] == 0x03then
Ch9121Write(0x15,DESIP)--目的IP
Ch9121Write(0x16,DESPORT)--目的端口号
end
--配置网络信息(静态IP配置)
if DHCP[1] ~= 0x01 then
Ch9121Write(0x11,SRCIP)--源IP
Ch9121Write(0x12,SUBNET)--子网掩码
Ch9121Write(0x13,GATEWAY) --网关
end
Ch9121Write(0x14,SRCPORT)--本地源端口PORT
Ch9121Write(0x23,{0x01,0x00,0x00,0x00})--RX接收打包超时时间1*5ms
Ch9121Write(0x24,{0x00})--网线断开不断网
Ch9121Write(0x25,{0x00,0x02,0x00,0x00})--RX接收打包数据个数512字节
Ch9121Write(0x26,{0x01})--网络连接时清空串口数据
Ch9121Write(0x33,DHCP)--DHCP or Static
Ch9121Write(0x0d,{})--更新配置参数至EEPROM
Ch9121Write(0x0e,{})--执行配置,复位CH9121
LIB_GpioToggle("D11") --喂硬件看门狗
LIB_DelayMs(200)
--CH9121退出配置模式
LIB_GpioWrite(CH9121_CFG,1)--DTU01没接CFG,此种配置方式无效!
--CH9121退出配置模式(串口协商方式)
Ch9121Write(0x5e,{})
LIB_DelayMs(50)
end

--该函数用来判断以太网模块是不是很久没收到消息了,有可能是以太网模块故障了
--如果是故障就重启执行以太网模块的初始化流程
function EthKeepAlive()
--超过30分钟没有以太网通信行为,认为以太网模块出问题
if EthLostContactTimeMsCnt >= 1800000 then
LIB_SystemReset() --重启整个系统
end
end

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

--硬件初始化函数
function Init()
--使能系统日志,不用的时候关闭
--LIB_SystemLogEnable()
--配置Uart0波特率为9600,和CH9121以太网模块通信
LIB_Uart0Config("BAUDRATE_9600")
--配置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")
--初始化CH9121以太网模块
Ch9121Init()
--配置Uart1串口工作,D8自动控制收发电平
LIB_Uart1Rs485Config(Rs485BaudRate,"D8",Rs485ParitySet,Rs485StopBitSet)
--使能系统10毫秒定时器开始工作
LIB_10msTimerConfig("ENABLE")
end

--硬件初始化
Init()
--开始大循环
while(GC(1) == true)
do
--查询是否收到以太网数据,例如:0x01 0x02 0x03
u0_flag,u0_tab = LIB_Uart0Recv()
if u0_flag == 1 then
--绿灯闪0.1秒
GreenLedTimeMsCnt = 100
--清零Eth故障判断计时器
EthLostContactTimeMsCnt = 0
--将收到的数据原封不动转发给485端口
LIB_Uart1BlockSend(u0_tab)
end

--查询是否收到485数据,例如:0x01 0x02 0x03
flag,tab = LIB_Uart1Recv()
if flag == 1 then
--红灯闪0.1秒
RedLedTimeMsCnt = 100
--将收到的数据原封不动转发给以太网
LIB_Uart0Send(tab)
end

--EthKeepAlive()用来进行判断以太网是否正常,也可考虑去掉该函数,原因如下:
--因为如果30分钟收不到以太网数据,该函数会让以太网模块重启,导致TCP断开连接,Client端需要再次重新执行TCP连接
--但如果能够保证30分钟内必然会收到Client端发来的消息,则可保留此函数,因为这样可保证以太网长期工作的稳定性
--综上所述,为了保证长期工作的稳定性,Client端需要在检测到本Server端断连后,再次重新执行TCP连接
EthKeepAlive()
end

标签:网关,LIB,--,RS485,u0,SendData,CH9121,以太网
From: https://blog.csdn.net/ucos_hqu/article/details/137227650

相关文章

  • (学习笔记) 对点信道与广播信道和以太网的关系梳理
    点对点信道:指的是在两个节点之间建立的直接通信路径,只有这两个节点能够相互通信。这种信道通常用于点对点连接,如电话线或点对点网络连接。有时人们可能会将点对点信道归类为广域网(WAN)范畴,这是因为点对点连接通常涉及跨越较大地理距离的通信。虽然点对点通信可以在局域网(LAN)中......
  • 以太网:UDP包结构
    参考:UDP协议报文结构_udp报文结构-CSDN博客千兆以太网(3):接收——包校验和数据筛选-咸鱼IC-博客园(cnblogs.com)计算机网络·啥玩意是源MAC地址,目标MAC地址,源ip地址,目标ip地址_目的mac地址和源mac地址-CSDN博客数据的校验和筛选仅供参考帧首部:7个h55+hd5MAC首部:目的MA......
  • 20设置永久默认网关,ping不通外网、网络不可达
    1.使用route-n查看路由route-n2.手动添加一条默认网关但是这个只是临时生效,重启会丢失routeadddefaultgw192.168.230.23.配置永久默认网关/etc/sysconfig/network在文件/etc/sysconfig/network里面,添加一条默认网关GATEWAY=192.168.230.2重启systemctlres......
  • 基于AI网关的光伏电站在线监测方案
    光伏电站作为利用太阳能的重要方式,凭借其环保、高效和可持续性的优势,在全球范围内得到广泛应用。然而,光伏电站的运营和维护也面临着诸多难点和痛点。在这一背景下,AI智能网关的应用为光伏电站的运营和维护带来了新的突破。 光伏电站运维监测难点痛点 首先,光伏电站的晶板、储......
  • 无人车网关案例:记SV900无人清扫车网关的现场应用
    ​随着无人驾驶技术的不断发展,无人车辆已经开始广泛应用于物流配送、环境保洁、巡逻监控等众多领域,助力城市运营更加高效智能。而要实现无人车辆的安全可靠运行,关键在于选择一款性能卓越的车载网络通信系统.在这一背景下,星创易联推出了SV900无人车网关系列产品。它集5G/4G网络......
  • 智慧酒店(二):AI智能分析网关V4视频分析技术在酒店管理中的应用
    一、人工智能技术如何应用在酒店管理中?随着科技的飞速发展,人工智能技术已经逐渐渗透到我们生活的方方面面,其中,酒店管理行业便是其应用的重要领域之一。人工智能技术以其高效、精准的特点,为酒店管理带来了革命性的变革。人工智能技术可以应用在酒店管理的这些场景中:1、智能客房管......
  • CAN转PROFIBUS DP网关助力和利时PLC连接潍柴发电机组
    潍柴,作为柴油机行业的翘楚,其产品被广泛地应用于通信、石油、医疗、铁路以及农牧业等多个领域。 南通某项目有多台即将发往国外的潍柴发电机组,客户新需发电机组增加PROFIBUSDP接口以达到与上位系统和利时PLC实时通信。 该项目中,上位机系统需实时监控柴油机的转速,机油压力和......
  • 02-基于STM32F407MAC与DP83848实现以太网通讯六(IPerf网络速度测试)
    一、IPerf2网络测试工具Iperf2是一个用于测试网络带宽的工具。它是Iperf的旧版本,专注于提供基本的带宽测量功能。通过在客户端和服务器之间发送测试数据流并测量其性能,用户可以评估网络连接的速度和稳定性。Iperf2提供了一种简单而有效的方式来评估网络性能。IPerf3已经发布了,但......
  • 车载以太网AVB交换机 TSN交换机 时间敏感网络 6端口 百兆 SW100TSN
    SW100TSN时间敏感网络AVB交换机        为6端口百兆车载以太网交换机,其中包含5通道100BASE-T1泰科MATEnet接口和1个通道100/1000BASE-T标准以太网(RJ45接口),可以实现纳米级时间同步,车载以太网多通道交换,Bypass数据采集和监控等功能,支持TSN/AVB协议,边界时钟,gPTP时钟桥......
  • SpringCloud(三)统一网关 -- GateWay
    gateway官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/ 我们为什么选择Gatway?:neflix不太靠谱,zuul2.0一直跳票,迟迟不发布​一方面因为Zuul1.0已经进入了维护阶段,而且Gateway是SpringCloud团队研发的,是亲儿子产品,......