Skip to content

com — 串口通信 ​

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.NONE0无校验
com.ODD1奇校验
com.EVEN2偶校验

com.setup ​

lua
com.setup(port, [baud, parity, databits, stopbits]) --> device

打开一个物理串口并返回串口对象。

参数

#参数类型必填默认值说明
1portinteger是—串口号。ESP32 端只接受 1~3,超出返回 nil。COM2/COM3 是否存在取决于机型
2baudinteger否9600只接受 300 600 1200 2400 4800 9600 19200 38400 57600 76800 115200,其它值本函数一个返回值都不压栈。76800 是 BACnet MS/TP 常用速率
3parityinteger否com.NONEcom.NONE/com.ODD/com.EVEN;其它值按无校验处理
4databitsinteger否87 / 8 有效;传 1 按 8 位,传 0 按 7 位,其它值按 8 位
5stopbitsinteger否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(...)

发送任意个数的字符串或字节。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象(冒号写法自动传入)
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()

读取串口已收到的数据。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象

返回值

类型说明
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。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象
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)

注册串口收到数据时的回调,并启动一个串口接收线程。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象
2callbackfunction是—收到数据时调用,入参是一个 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 的接收超时。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象
2msinteger是100超时毫秒数。小于 100 会被强制按 100 处理

返回值

无返回值。


com.set_time_lunxun ​

lua
com.set_time_lunxun(dev, ms)
dev:set_time_lunxun(ms)

设置轮询采集时两次报文之间的间隔。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象
2msinteger是100轮询间隔毫秒。小于 1 会被强制按 1 处理

返回值

无返回值。

说明

  • 只对 add_device + start 的轮询模式有意义,对手动 send/recv 无影响。

com.add_device ​

lua
com.add_device(dev, son)
dev:add_device(son)

把协议子设备挂到这个串口上,交给轮询线程自动采集。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象
2sonuserdata是—只接受 com_modbus.creat、com_fx.creat、com_dlt645.creat 返回的对象

返回值

无返回值。

说明

  • 传入其它类型的对象会被静默忽略,既不挂载也不报错。采集不到数据时应先确认此步的参数类型是否正确。

com.set_transparent ​

lua
com.set_transparent(dev, [target])
dev:set_transparent([target])

设置透传。

参数

#参数类型必填默认值说明
1devuserdata是—源串口对象
2targetuserdata否—传另一个串口对象 → 串口到串口透传;省略、或传入的不是串口对象 → 把 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 的间隔轮询所有已挂载的子设备。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象

返回值

无返回值。

说明

  • 应在所有 add_device 调用完成后再执行 start。

com.close ​

lua
com.close(dev)
dev:close()

关闭底层串口。

参数

#参数类型必填默认值说明
1devuserdata是—串口对象

返回值

无返回值。

说明

  • 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。

验证方法:

  1. 接好串口设备,下载脚本并重启。
  2. 日志每 3 秒打印一次「仪表回应: ...」;若设备没接,打印「仪表无回应」。
  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)。

验证方法:

  1. 下载重启后,上位机「在线监视」里 D100-D101 应有温度原始值,换算后约 25.0℃ 量级。
  2. st:get_num() 应为 0(通讯成功);拔掉从站电源应变 2(通信超时),收到错报文变 1(报文异常)。
  3. 改 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。
  • 两个透传串口的参数(波特率、校验)通常要一致,否则对端收的是乱码。

验证方法:

  1. 串口互转:从 COM2 接一个串口助手发数据,COM1 侧应原样收到(可用另一台 PC 或 USB 转串口监听)。
  2. 云透传:在上位机「远程串口透传」里连接,应能直接操作 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 不一致时表现为“屏上有显示但数据不动”。

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