主题
pipe "xinje" — 信捷 PLC
协议名:"xinje"
信捷 XC / XD 系列 PLC,走串口 Modbus RTU,但地址用信捷软元件名而不是 Modbus 寄存器号。读写方法的返回值约定和错误码见 7.1 Pipe 通信概述。
平台限制
本协议只在上位机版本和 Linux 网关版本里提供,ESP32 机型不支持,调用会返回 nil。
ESP32 上访问信捷 PLC 用 "modbus.rtu",自己按信捷手册换算 Modbus 地址。
创建管道
lua
pipe.setup("xinje", "COM口[:波特率]") --> pipe | nil| 形式 | 说明 |
|---|---|
"COM1:9600" | 指定串口和波特率 |
"COM1" | 用默认波特率 9600 |
lua
xc = pipe.setup("xinje", "COM1:19200")说明
- 串口帧格式固定 8 数据位 + 无校验 + 1 停止位,站号固定
1,都不可配。 - 底层是 Modbus RTU(带 CRC16)。
地址格式
| 前缀 | 软元件 | 编号进制 | 类型 |
|---|---|---|---|
X | 输入 | 八进制 | 位(只读) |
Y | 输出 | 八进制 | 位 |
M | 辅助继电器 | 十进制 | 位 |
S | 步进 | 十进制 | 位 |
T | 定时器(映射到 TD 区) | 十进制 | 字 |
C | 计数器(映射到 CD 区) | 十进制 | 字 |
D | 数据寄存器 | 十进制 | 字 |
lua
xc:read_bite("X0") -- X 是八进制
xc:write_bite("Y0", true)
xc:read_u16("D100", 10)
xc:read_u16("TD0") -- 写 T0 即访问 TD0 当前值说明
- X / Y 是八进制,其它软元件十进制。
X10= 十进制编号 8 的输入点。 T和C访问的是当前值寄存器(TD / CD 区),不是触点。要读触点位请用 Modbus 地址走"modbus.rtu"。X区只能读。- 代码里不做地址范围检查。
可用方法
可用:read_bite write_bite read_u16 write_u16 read_s16 write_s16 read_u32 read_s32 read_float
空实现(读返回 nil,写返回失败):
write_u32 write_s32 write_float read_double write_double read_string write_string
32 位数据只能读不能写,双精度和字符串不支持。要写 32 位就拆成两个 write_u16。
p:read() / p:write() 未实现。
常见用法
lua
xc = pipe.setup("xinje", "COM1:19200")
function poll()
local ret = xc:read_u16("D100", 20)
if ret.errno == 0 then
for i = 1, 20 do plc.d(i, ret.data[i]) end
end
if plc.m(0) == 1 then xc:write_bite("Y0", true) end
end
t = timer.start(500, poll)注意事项
- ESP32 固件不支持本协议,返回
nil。 - X / Y 用八进制编号。
- 32 位写、双精度、字符串不可用。
- 站号固定 1,多台设备请改用
"modbus.rtu"指定slave。 - 管道对象要用全局变量长期持有。
例程
每个例程都是可直接下载运行的完整脚本(仅上位机 / Linux 网关版本,ESP32 上
pipe.setup("xinje", ...)返回nil)。底层串口 Modbus RTU,地址用信捷软元件名。通用接口见 8.1 概述。统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。
例程 1:轮询 D 区 + 写 Y
适用:LP3232 / LP3288 / 软PLC模拟器 / 上位机(不含 ESP32)| 依赖模块:pipe timer plc | 难度:★☆☆
场景:信捷 XC/XD 系列,每 500ms 把 D100 起 20 个字读到本机 D 区,本机 M0 置位时写 Y0。
完整代码(可直接下载运行):
lua
xc = pipe.setup("xinje", "COM1:19200") -- 第二参字符串,信捷常用 19200
if not xc then
print("创建失败(ESP32 不支持 xinje,改用 modbus.rtu)")
return
end
function poll()
local ret = xc:read_u16("D100", 20)
if ret.errno == 0 then
for i = 1, 20 do plc.d(i, ret.data[i]) end
end
if plc.m(0) == 1 then xc:write_bite("Y0", true) end
end
t = timer.start(500, poll)要点:
pipe.setup("xinje", "COM1:19200")—— 第二参是字符串;串口 8N1、站号固定 1。- X / Y 用八进制编号,其它十进制(
X10= 十进制编号 8);X 只读;T/C访问的是当前值寄存器(TD/CD 区)。 - ESP32 上创建返回
nil,必须判空。
验证方法:上位机 / Linux 网关版本运行,本机 D100~D119 出现信捷 D100~D119 的值。
注意事项:X/Y 八进制易算错;32 位只能读不能写、双精度/字符串不支持——写 32 位要拆两个 write_u16。
例程 2:写回(写方法返回整数错误码)
适用:同上 | 依赖模块:pipe | 难度:★☆☆
场景:把 1234 写到 D300,并置位 Y0。
完整代码(可直接下载运行):
lua
local xc = pipe.setup("xinje", "COM1:19200")
if not xc then return end
local e1 = xc:write_u16("D300", 1234)
local e2 = xc:write_bite("Y0", true)
print("写D:", e1 == 0 and "OK" or "FAIL", "写Y:", e2 == 0 and "OK" or "FAIL")要点:写方法返回整数错误码;X 只读不能写。
验证方法:信捷侧 D300 = 1234、Y0 = 1。
注意事项:写返回整数非 table,别查 result.errno;32 位/双精度/字符串写是空实现。
例程 3:注意事项——X 只读 / X Y 八进制
适用:同上 | 依赖模块:pipe | 难度:★☆☆
场景:最常见的两类误用:对 X 写、X/Y 十进制编号。
完整代码(可直接下载运行):
lua
local xc = pipe.setup("xinje", "COM1:19200")
if not xc then return end
-- ❌ 错误
xc:write_bite("X0", true) -- X 只读,被拒
-- ✅ 正确
xc:read_bite("X0") -- X 只读 OK
xc:write_bite("Y0", true) -- Y 可写要点:X 只读;X/Y 八进制编号;T/C 读的是当前值寄存器(TD/CD),要读触点位请用 "modbus.rtu"。
验证方法:正确写法生效;错误写法被拒。
注意事项:ESP32 用 xinje 会返回 nil;站号固定 1,多台设备改用 "modbus.rtu" 指定 slave。