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