Skip to content

B8. 串口 ↔ 网口互转框架(把现场串口设备搬到远端) ​

综合例程。同组其余例程、以及这个库的函数说明在 05-03-tcp-client。 这一页给的是可直接照搬的框架,不是单点示例:下面的代码除了改地址/波特率,基本不用动。

适用:带 RS485/232 串口的机型 | 依赖模块:tcp_client com | 难度:★★☆

场景:现场的仪表/PLC 只出 RS485,远端上位机或服务器想直接跟它对话。两套做法:

  • 透传模式:固件直接把"串口收到的字节"原样转发出去、"网口收到的字节"原样写回串口,你不用写任何收发逻辑。
  • 代理模式:你想在设备里拦一道(加校验、改内容、做协议转换)时用,自己 send/recv + 分帧 + 重连。

框架 A:透传模式(最简单,推荐先用) ​

lua
-- 串口 ↔ TCP 全双工透传;两侧的 set_transparent 都要调
local com1 = com.setup(1, 9600, com.NONE, 8, 1)   -- 串口号/波特率/校验/数据位/停止位 按现场仪表改
if not com1 then
    print("串口打开失败,检查串口号与波特率档位")
    return
end

local tc = tcp_client.creat("192.168.1.100", 9000)  -- 远端透传服务端地址

tc:reg(tcp_client.CONNECTED, function()
    print("透传通道已建立")
end)
tc:reg(tcp_client.DISCONNECTED, function()
    print("透传断开,固件会在重连后自动恢复")
end)

tc:start()
tc:set_transparent()     -- ① TCP 侧:这条连接用于透传
com1:set_transparent()  -- ② 串口侧:设为透传口并自动起轮询线程

要点:

  • 两个 set_transparent() 缺一不可;顺序无所谓,但两边都要有。
  • 设成透传口后不要再自己 send/recv(会抢数据、打乱时序),固件直接转发。
  • 波特率必须是允许档位(见 com.setup),填错不报错只返回 nil,所以上面判了空。
  • TCP 断开重连后透传自动恢复,不用重下脚本。

验证方法:PC 起一个监听 9000 的 TCP 服务端;串口挂一块 Modbus 仪表。服务端发 Modbus 查询帧 → 串口侧原样出去;仪表应答 → 原样回服务端。确认固件没有插入任何多余字节。

注意事项:只用了一侧 set_transparent 会"一边通、一边没反应";透传期间对同串口再 send 数据链路会乱。


框架 B:代理模式(要拦一道内容时) ​

lua
-- 串口 ↔ TCP 代理:自己收发,可加校验/改内容/做协议转换
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
if not com1 then print("串口打开失败"); return end
com1:set_timeout(1000)

local tc = tcp_client.creat("192.168.1.100", 9000)
local netbuf = ""   -- 网口侧待转发到串口的缓冲

tc:reg(tcp_client.RECVDATA, function(data)
    if data and #data > 0 then
        com1:send(data)          -- 网口来的字节 → 写进串口
    end
end)
tc:reg(tcp_client.DISCONNECTED, function()
    print("TCP 断开")
end)
tc:start()

-- 串口来的字节 → 转发出去(这里原样转发,要改内容就在发出前处理)
com1:reg(function(data)
    if data and #data > 0 then
        if tc:is_linked() == 1 then   -- 返回整数,必须 == 1
            tc:send(data)
        end
    end
end)

要点:

  • 代理模式不要调 set_transparent,否则串口数据被固件直接吞掉,你的回调收不到。
  • 网口侧用 tc:is_linked() == 1 判在线再发,断线期间的字节直接丢弃(透传缓冲交给业务层自己管)。
  • 串口回调里只做"搬运",别在里面跑长逻辑;要处理内容用 timer 或协程。

验证方法:同框架 A,但这次在 com1:reg 回调里加一行 print(string.tohex(data)) 能看到串口原始字节,确认转发链路通。

注意事项:串口回调和 TCP 回调不在同一线程上下文,共享变量(如 netbuf)要注意读写时机;简单转发不需要 netbuf,直接 com1:send(data) 即可。


什么时候用哪种 ​

需求选
仪表只出 RS485,远端直接对话,不改内容框架 A 透传
要在设备里加校验/做协议转换/记录日志框架 B 代理
免脚本、纯配置上位机 远程串口透传

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研