Skip to content

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。

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