主题
com — 串口通信
模块名:com
打开并驱动设备上的物理串口。既能直接收发字节流,也能作为「父设备」挂载 Modbus / FX / DLT645 协议子设备做自动轮询采集。后者是 DTU 场景的主要用法,无需在脚本中自行拼装报文。
ESP32 端串口号只能是 1~3,波特率必须落在固定档位上,否则 com.setup 会失败。
除 com.setup 之外的函数在库表和对象元表里都注册了,所以 com.send(dev, "x") 和 dev:send("x") 完全等价。下文签名统一写库函数形式,示例用冒号写法。
函数总览
库级函数
| 函数 | 作用 |
|---|---|
com.setup(com_num, [baud, parity, databits, stopbits]) | 打开并配置串口,返回串口对象 |
对象方法
| 方法 | 作用 |
|---|---|
com.send(com_device, dataN, ...) | 发送字符串或字节 |
com.recv() | 读取已收到的数据 |
com.print(com_device, dataN, ...) | 按 print 风格发送多个值,自动补换行 |
com.reg(callback) | 注册收到数据时的回调 |
com.set_timeout(timeout_ms) | 设置 recv 的接收超时 |
com.set_time_lunxun(timeout_ms) | 设置轮询采集的间隔 |
com.add_device(sub_device) | 挂载协议子设备 |
com.set_transparent(transparent_device) | 设置透传目标 |
com.start() | 启动子设备轮询线程 |
com.close() | 关闭串口 |
常量
| 常量 | 值 | 说明 |
|---|---|---|
com.NONE | 0 | 无校验 |
com.ODD | 1 | 奇校验 |
com.EVEN | 2 | 偶校验 |
com.setup
lua
com.setup(port, [baud, parity, databits, stopbits]) --> device打开一个物理串口并返回串口对象。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | port | integer | 是 | — | 串口号。ESP32 端只接受 1~3,超出返回 nil。COM2/COM3 是否存在取决于机型 |
| 2 | baud | integer | 否 | 9600 | 只接受 300 600 1200 2400 4800 9600 19200 38400 57600 76800 115200,其它值本函数一个返回值都不压栈。76800 是 BACnet MS/TP 常用速率 |
| 3 | parity | integer | 否 | com.NONE | com.NONE/com.ODD/com.EVEN;其它值按无校验处理 |
| 4 | databits | integer | 否 | 8 | 7 / 8 有效;传 1 按 8 位,传 0 按 7 位,其它值按 8 位 |
| 5 | stopbits | integer | 否 | 1 | 当前一律按 1 位停止位处理,传其它值无效 |
返回值
| 类型 | 说明 |
|---|---|
| userdata | 串口对象。打开失败返回 nil |
示例
lua
-- COM1,9600,无校验,8 数据位,1 停止位
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
if not com1 then
print("串口打开失败")
return
end说明
- 参数从左往右逐个可选,但要传后面的参数,前面的必须一起传。
- 波特率不在允许列表时函数不返回任何值,赋值端同样得到
nil,和「打开失败」无法区分。 - 对同一个
port重复setup之前,应先把旧对象close掉。
实用例程
lua
modbus_state=data.creat(0)--连接状态标志对象
dianlu=data.creat(0)--电流对象
--zongliangh=data.creat(0)--总量x100对象
--zongliangl=data.creat(0)--总量x1对象
meter=com_modbus.creat(com_modbus.RTU,3,modbus_state)--建立MODBUS子设备,数字是设备地址
--meter:set_32_abcd(com_modbus.)--32位数编码方式
--meter:set_float_abcd(com_modbus.ABCD)
meter:set_time_recv(2000)--接收时间
meter:add_channel(400001,com_modbus.S16,dianlu,com_modbus.READ)--加入采集通道,数字是寄存器D的地址,400001是要采集的MODBUS设备寄存器
--meter:add_channel(400001,com_modbus.S16,zongliangh,com_modbus.READ)--加入采集通道
--meter:add_channel(400001,com_modbus.FLOAT,zongliangh,com_modbus.READ)--加入采集通道
--meter:add_channel(400004,com_modbus.FLOAT,zongliangl,com_modbus.READ)--加入采集通道
--meter:add_channel(400006,com_modbus.FLOAT,liuliang,com_modbus.READ)--加入采集通道
serial=com.setup(1,9600,com.NONE,8,1)--建立串口父设备,前面 1是串口号
serial:add_device(meter)--加入子设备
serial:set_time_lunxun(2000)--设定轮询时间
serial:set_timeout(2000)--接收超时时间
serial:start()--启动串口数据采集
ds1=timer.start(5000,function()
print("dianlu:",dianlu)--plc.d(100))
plc.d(120,dianlu)
end
)把上面的地址、主题、引脚替换成你项目里的即可。
com.send
lua
com.send(dev, ...) --> integer
dev:send(...)发送任意个数的字符串或字节。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象(冒号写法自动传入) |
| 2… | ... | string | number | 否 | — | 可变个数。number 取低 8 位当一个字节发送;string 原样发送;其它类型报错 |
返回值
| 类型 | 说明 |
|---|---|
| integer | 实际写出的字节总数。不传数据时返回 0 |
示例
lua
com1:send("AT\r\n") -- 发字符串
com1:send(0x01, 0x03, 0x00, 0x00) -- 发 4 个字节
com1:send("ID:", 0x01, "\r\n") -- 混合发送com.recv
lua
com.recv(dev) --> data, len
dev:recv()读取串口已收到的数据。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
返回值
| 类型 | 说明 |
|---|---|
| string | 收到的数据。无数据时是空串 "" |
| integer | 数据字节数。无数据时是 0 |
示例
lua
com1:set_timeout(1000)
local data, len = com1:recv()
if len > 0 then print("收到", len, "字节") end说明
- 单次最多读 1024 字节,超出的留到下次读。
- 超时时间取
set_timeout设置的值,未设置时为 100ms。 - 数据可能含
\0,用#data或第二个返回值判断长度,不要依赖字符串结束符。
com.print
lua
com.print(dev, ...)
dev:print(...)按 print 的风格把多个值发到串口,末尾自动补 \r\n。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
| 2… | ... | any | 否 | — | string 原样;number 按 %g;boolean 输出 true/false;nil 输出 nil;table 和 lightuserdata 被跳过但仍占一个分隔位 |
返回值
无返回值。
示例
lua
com1:print("温度:", 25.5, "在线:", true)说明
- 元素之间的分隔符是两个空格加一个制表符。number 走
%g,大整数会被转成科学计数法,要精确控制格式请用string.format再send。
com.reg
lua
com.reg(dev, callback)
dev:reg(callback)注册串口收到数据时的回调,并启动一个串口接收线程。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
| 2 | callback | function | 是 | — | 收到数据时调用,入参是一个 string。类型不是 function 直接报错 |
返回值
无返回值。
示例
lua
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
com1:reg(function(data)
print("异步收到", #data, "字节:", encoder.tohex(data))
end)说明
- 只保留最后一次注册的回调,重复注册会覆盖。
- 回调内部报错不会中断程序,只会输出一行以
ERR:开头的信息。 - 回调方式和主动
recv会争抢同一份接收数据,同一个串口上不要两种方式混用。
com.set_timeout
lua
com.set_timeout(dev, ms)
dev:set_timeout(ms)设置 recv 的接收超时。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
| 2 | ms | integer | 是 | 100 | 超时毫秒数。小于 100 会被强制按 100 处理 |
返回值
无返回值。
com.set_time_lunxun
lua
com.set_time_lunxun(dev, ms)
dev:set_time_lunxun(ms)设置轮询采集时两次报文之间的间隔。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
| 2 | ms | integer | 是 | 100 | 轮询间隔毫秒。小于 1 会被强制按 1 处理 |
返回值
无返回值。
说明
- 只对
add_device+start的轮询模式有意义,对手动send/recv无影响。
com.add_device
lua
com.add_device(dev, son)
dev:add_device(son)把协议子设备挂到这个串口上,交给轮询线程自动采集。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
| 2 | son | userdata | 是 | — | 只接受 com_modbus.creat、com_fx.creat、com_dlt645.creat 返回的对象 |
返回值
无返回值。
说明
- 传入其它类型的对象会被静默忽略,既不挂载也不报错。采集不到数据时应先确认此步的参数类型是否正确。
com.set_transparent
lua
com.set_transparent(dev, [target])
dev:set_transparent([target])设置透传。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 源串口对象 |
| 2 | target | userdata | 否 | — | 传另一个串口对象 → 串口到串口透传;省略、或传入的不是串口对象 → 把 dev 设为云透传口 |
返回值
无返回值。
示例
lua
-- 串口到串口透传
local com1 = com.setup(1, 9600)
local com2 = com.setup(2, 9600)
com1:set_transparent(com2)
-- 云透传:不传参数
com1:set_transparent()说明
- 设为云透传口时会自动启动轮询线程,不需要再调
com.start。 - 免脚本的完整远程透传配置见 远程串口透传。
com.start
lua
com.start(dev)
dev:start()启动父设备轮询线程,按 set_time_lunxun 的间隔轮询所有已挂载的子设备。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
返回值
无返回值。
说明
- 应在所有
add_device调用完成后再执行start。
com.close
lua
com.close(dev)
dev:close()关闭底层串口。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | dev | userdata | 是 | — | 串口对象 |
返回值
无返回值。
说明
close只关闭端口,串口对象本身在被垃圾回收时才真正释放。
常见用法
一问一答收发
lua
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
if not com1 then return end
com1:set_timeout(1000)
local function ask(cmd)
com1:send(cmd)
local data, len = com1:recv()
return len > 0 and data or nil
end
print(ask("AT\r\n") or "无应答")挂 Modbus 子设备自动采集
lua
local state = data.creat(0)
local temp = data.creat(0)
local dev1 = com_modbus.creat(com_modbus.RTU, 1, state)
dev1:add_channel(400001, com_modbus.FLOAT, temp, com_modbus.READ)
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
com1:add_device(dev1)
com1:set_timeout(1000)
com1:set_time_lunxun(1000)
com1:start()
timer.start(2000, function()
print("温度:", temp:get_num(), "状态:", state:get_num())
end)注意事项
- 串口号只能是 1~3,具体可用数量取决于机型。
- 波特率必须是允许档位之一,填错不会报错,只会得到
nil。 - 停止位参数实际无效,固定为 1 位。
- 接收超时下限为 100ms,小于该值无法设置。
- 同一个串口上不要既
reg回调又主动recv。 - 轮询模式下不要再对同一串口手动
send,会打乱协议报文时序。
例程
每个例程都是可直接下载运行的完整脚本:注册完串口/子设备/定时器后脚本就结束,固件自动进入消息泵。 API 只用本页已文档化的函数;统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。
例程 1:一问一答读 ASCII 仪表(同步 send/recv,由定时器驱动)
适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 | 依赖模块:com timer | 难度:★☆☆
场景:串口接一个 ASCII 协议仪表(或 DTU/模块),需要定时发查询帧、等回应、取回数据。收发是同步的(send 后 recv 阻塞等回应),但用 timer.start 触发、不要用 while true + sleep,否则会冻死消息泵。
完整代码(可直接下载运行):
lua
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
if not com1 then
print("串口打开失败")
return
end
com1:set_timeout(1000) -- recv 最多等 1 秒
local function query(cmd)
com1:send(cmd)
local data, len = com1:recv() -- 同步等待回应
return len > 0 and data or nil
end
timer.start(3000, function() -- 每 3 秒查一次,不在主线程阻塞
local r = query("$01RD0102\r\n")
if r then
print("仪表回应:", r)
else
print("仪表无回应")
end
end)要点:
com.setup失败返回nil,必须先判空再使用,否则后续调用会报错。recv是同步阻塞等待(最多set_timeout设定的 1000ms),所以它只能放在定时器/回调里,不能放在脚本顶层死循环。- 波特率必须落在允许档位,填错不报错只是得到
nil。
验证方法:
- 接好串口设备,下载脚本并重启。
- 日志每 3 秒打印一次「仪表回应: ...」;若设备没接,打印「仪表无回应」。
- 用串口助手从 PC 模拟仪表回一句,应能被
recv取到并打印。
注意事项:
- 同一个串口上不要既
reg回调又主动recv—— 两种接收方式会争抢同一份缓冲。 - 停止位参数实际无效(固定 1 位),填了也不报错但不生效。
- 别写成
while true do query() sleep(3000) end:sleep不泵消息队列,会冻死定时器与所有回调。
例程 2:挂 Modbus 子设备自动轮询(推荐,不用自己拼报文)
适用:同上 | 依赖模块:com com_modbus data timer plc | 难度:★☆☆
场景:RS485 上挂一台温控表,希望把浮点温度自动轮询到寄存器,脚本只管读数值、不必自己拼 Modbus 帧、算 CRC。轮询由 com.start 的后台线程完成。
完整代码(可直接下载运行):
lua
local st = data.creat(0) -- 通信状态(0/1)
local dev1 = com_modbus.creat(com_modbus.RTU, 1, st)
dev1:set_float_abcd(com_modbus.CDAB) -- 国产表常见字序
dev1:set_time_recv(500)
dev1:add_channel(400001, com_modbus.FLOAT, 100, com_modbus.READ) -- 浮点温度 → D100-D101
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
com1:add_device(dev1) -- 把从站挂到串口
com1:set_time_lunxun(1000) -- 轮询间隔
com1:start() -- 启动后台轮询线程
timer.start(2000, function()
print("温度:", plc.df(100), "在线:", st:get_num() == 0)
end)要点:
com_modbus本身不碰串口,必须add_device挂到一个com对象、再com.start才会真正轮询。creat第 3 个参数st回写该从站的通信状态码:0=通讯成功、1=报文异常、2=通信超时。 判"在线"要写st:get_num() == 0,不要写== 1(1 是报文异常,恰好是出故障)。- 浮点占 2 个寄存器,
add_channel里地址写400001就够;读取用plc.df(100)(不是plc.DF100)。
验证方法:
- 下载重启后,上位机「在线监视」里 D100-D101 应有温度原始值,换算后约 25.0℃ 量级。
st:get_num()应为 0(通讯成功);拔掉从站电源应变 2(通信超时),收到错报文变 1(报文异常)。- 改
set_float_abcd的字序(如ABCD)后若数值乱码,说明表的实际字序不同 —— 依次试四种。
注意事项:
- 字节序要和通道数据类型配对:
set_float_abcd只对FLOAT通道生效,S16用set_16_ab,S32/U32用set_32_abcd。给S16调set_32_abcd不会报错也不会生效。 - 组合地址
400001是从 1 开始(= 偏移 0),分离形式是add_channel(4, 0, ...)从 0 开始,别混。 - 轮询启动后不要再对该串口手动
send,会打乱协议报文时序。
例程 3:串口到串口透传 / 云透传
适用:同上 | 依赖模块:com | 难度:★☆☆
场景:需要把 COM1 进来的数据原样转发到 COM2(比如接老式串口设备经 4G 口出去),或把某个串口设成「云透传口」让上位机远程直连底层的串口设备。
完整代码(可直接下载运行):
lua
local com1 = com.setup(1, 9600, com.NONE, 8, 1)
local com2 = com.setup(2, 9600, com.NONE, 8, 1)
-- 串口互转:COM1 收到的数据全部转发给 COM2
com1:set_transparent(com2)
-- 云透传:省略参数,把 COM1 设为云透传口(上位机可远程直连该串口设备)
-- com1:set_transparent()要点:
set_transparent传另一个串口对象 = 串口到串口透传;省略参数 = 设为云透传口。- 设为云透传口时会自动启动轮询线程,不需要再调
com.start。 - 两个透传串口的参数(波特率、校验)通常要一致,否则对端收的是乱码。
验证方法:
- 串口互转:从 COM2 接一个串口助手发数据,COM1 侧应原样收到(可用另一台 PC 或 USB 转串口监听)。
- 云透传:在上位机「远程串口透传」里连接,应能直接操作 COM1 下的设备。
注意事项:
- 透传口不要再
add_device/ 手动recv/ 手动send,透传线程已经在管这条串口了。 - COM2/COM3 是否存在取决于机型,不存在的口
setup返回nil。
例程 4:现场常用脚本 com库同步模式.LPLUA(原文)
适用:同上 | 依赖模块:com string timer | 难度:★☆☆
场景:不挂任何协议子设备,自己拼一条 Modbus 报文发出去、再同步把回帧读回来打印。 这是裸报文收发最常用的一份(文件 com库同步模式.LPLUA),当前固件上可直接运行。
完整代码(com库同步模式.LPLUA 原文):
lua
serial=com.setup(1,9600,com.NONE,8,1)--建立串口设备
serial:set_timeout(100)--设定接收超时时间
timer.start(1000,function()--定时发送
x="010300000001840A"
x=x:tohex()
print("send",x:fromhex())
serial:send(x)--发送数据
y=serial:recv()--接收数据
print("recv",y:fromhex())--打印接收到的数据
end)要点:
- 这两个方法的名字和直觉是反的:
x:tohex()是「十六进制文本→字节串」(发送前用),x:fromhex()是「字节串→可打印的十六进制文本」(打印时用)。完整说明见 string 字符串库。 send传的必须是tohex()转换后的字节串,直接发"010300000001840A"这串字符, 对端收到的是 ASCII 码而不是报文。- 同步
recv会当场等最多set_timeout那么久,所以它跑在定时器回调里; 放在脚本顶层则会把主线程阻塞到超时。
验证方法:接一台 Modbus 从站(或仿真),日志应每 1 秒出一对 send 010300000001840A / recv 010302xxxxb8xx;拔掉串口线后 recv 返回空串而不报错。
注意事项:set_timeout(100) 对慢设备偏短,收不到回帧时先把它调到 300~500 再判; 这条链路没挂子设备,不要又去 add_device,否则串口时序会互相干扰。
例程 5:现场常用脚本 com库异步模式.LPLUA(原文)
适用:同上 | 依赖模块:com string timer | 难度:★☆☆
场景:同样的报文,但改成“先注册接收回调,发完不等回音”,适合对端主动上报、 或一台设备上多路串口并行跑的场合(文件 com库异步模式.LPLUA)。
完整代码(com库异步模式.LPLUA 原文):
lua
serial=com.setup(1,9600,com.NONE,8,1)--建立串口设备
serial:set_timeout(100)--设定接收超时时间
serial:reg(function(y)--注册接收到数据事件
print("recv",y:fromhex())--打印接收到的数据
end
)
timer.start(1000,function()--定时发送
x="010300000001840A"
x=x:tohex()
print("send",x:fromhex())
serial:send(x)--发送数据
end)要点:
serial:reg(函数)注册的是“收到数据”事件,参数y是收到的字节串,用y:fromhex()转成文本才能看。- 回调里不要再调
serial:recv():数据已经交给回调了,再recv只会白等到超时。 - 与同步版相比,异步版不靠“发完就收”配对,所以自己要把请求和回帧对应起来 (按内容、或按“一问一答”串行化)。
验证方法:与例程 4 同样的接线,日志里 recv 行与 send 行分开出现(回帧可能在下一毫秒), 把对端改成主动周期上报时,不发也能看到 recv。
注意事项:reg 只能注册一个回调,重复注册会覆盖前一个;收到的数据不保证是一整帧 (可能被拆成两次回调),分帧处理见 tcp_client 例程 2。
例程 6:现场常用脚本 串口立即收发.LPLUA(原文)
适用:同上 | 依赖模块:com encoder timer os | 难度:★☆☆
场景:每 5 秒向 COM2 发一个 05 字节,发完立即把回帧读回来,两边都带时间戳打印。 常用于“发了就要看到响应的”心跳/唤醒类串口设备(文件 串口立即收发.LPLUA)。
完整代码(串口立即收发.LPLUA 原文):
lua
com1=com.setup(2,9600,com.NONE,8,1)
com1:set_timeout(1000)
buffer="05"
xz=timer.start(5000,function()
local getTime = os.date("%Y-%m-%d %H:%M:%S")
print("send",buffer,getTime)
send_buffer=encoder.to16hex(buffer)
com1:send(send_buffer)
recv=com1:recv()
getTime = os.date("%Y-%m-%d %H:%M:%S");
print("recv",encoder.from16hex(recv),getTime)
end
)要点:
buffer="05"是十六进制文本,encoder.to16hex()把它变成个0x05字节发出去;直接send("05")发的是两个字符30 35。encoder.to16hex/encoder.from16hex与string.tohex/string.fromhex是同一对实现,两种写法等价; 但encoder.tohex/encoder.fromhex是另一对(字节↔小写十六进制),别混。- 发送与接收的时间戳分开取,从两个时间差就能直接看出设备响应耗时。
验证方法:接一个收到 0x05 会回数据的设备(或环接 TX-RX),日志里 send 05 与 recv 05 的时间 应相差不到一个轮询周期;把 set_timeout(1000) 改小到 100 后,recv 行变空,能直观看到超时效果。
注意事项:recv 返回空串(不是 nil),拼接到 encoder.from16hex("") 不会报错,所以“没收到”与 “收到空”在日志里长一样,要看时间差判断;同一条串口上又跑透传又手动 send 会互相干扰。
例程 7:现场常用脚本 串口透传示例.LPLUA(原文)
适用:同上 | 依赖模块:com | 难度:★★☆
场景:串口 1 负责采集 MODBUS 设备,串口 2 作为透传口接触摸屏 —— 屏接在串口 2 上, 实际访问的是串口 1 上的设备(文件 串口透传示例.LPLUA)。这份脚本大量用的是注释, 因为它是“把两种透传都写在一起、用哪种就解开哪段”的模板。
完整代码(串口透传示例.LPLUA 原文,解开注释的部分才是实际跑的):
lua
--串口采集透传示例,串口1采集MODBUS,串口2作为透传到串口1(串口2上接触摸屏实际连接串口1上的设备)
--modbus_state=data.creat(0)--连接状态标志对象
--zongliangh=data.creat(0)--总量对象
--meter=com_modbus.creat(com_modbus.RTU,2,modbus_state)--建立MODBUS子设备
--meter:set_32_abcd(com_modbus.)--32位数编码方式
--meter:set_float_abcd(com_modbus.ABCD)
--meter:set_time_recv(100)--接收时间
--meter:set_time_error(0)--错误恢复时间
--meter:add_channel(400001,com_modbus.FLOAT,zongliangh,com_modbus.READ)--加入采集通道
serial_slave=com.setup(1,9600,com.NONE,8,1)--建立串口父设备
--serial_master=com.setup(2,9600,com.NONE,8,1)--建立透传口设备
--serial_master:set_timeout(100)
--serial_slave:add_device(meter)--加入子设备
--serial_slave:set_transparent(serial_master)--加入透传串口
serial_slave:set_transparent()--加入远程透传
serial_slave:set_time_lunxun(0)--设定轮询时间
serial_slave:set_timeout(200)--设定本串口接收时间
serial_slave:start()--启动串口数据采集要点:
- 当前生效的只有未注释的四行,即「把串口 1 设为云透传口」:
set_transparent()不带参数 = 远程透传, 带另一个串口对象 = 串口到串口透传(就是注释里那两行的用法)。 - ⚠ 注释行里有一句
meter:set_32_abcd(com_modbus.)是写坏了的(com_modbus.后面缺常量名), 整段解开会直接报语法错误、脚本一行都不跑。要用就改成meter:set_32_abcd(com_modbus.ABCD)。 - 两种透传只选一种:要“采集 + 透传”共存,解开
add_device(meter)与set_transparent(serial_master), 并把末行set_transparent()注释掉。
验证方法:云透传——在上位机“远程串口透传”里连本机,向串口 1 发一条 Modbus 查询,屏/PC 端能看到回帧; 串口互转——串口 2 接屏、串口 1 接设备,屏上改参数能在设备里读到。
注意事项:set_time_lunxun(0) 是“不留轮询间隙”,总线上设备多时容易超时,改成 50~200 更稳; 透传口上不要再手动 send/recv;触摸屏波特率与 com.setup 不一致时表现为“屏上有显示但数据不动”。