主题
🔗 Lua 与 PLC 协同开发指南
理解 Lua 脚本与梯形图程序的运行关系和数据共享机制
📖 双引擎架构
LPPLC 采用"梯形图 + Lua"双引擎架构:
| 特性 | PLC 梯形图引擎 | Lua 脚本引擎 |
|---|---|---|
| 运行核心 | Core 1 | Core 0 |
| 优先级 | 4 | 5 |
| 执行方式 | 周期扫描(固定周期) | 事件驱动 + 协程 |
| 擅长领域 | 逻辑控制、时序控制 | 网络通信、数据处理 |
| 数据共享 | 通过 D/M/S 寄存器 | 通过 plc 模块访问寄存器 |
🔄 数据共享机制
Lua 与梯形图通过 D 寄存器共享数据:
约定规则
地址分区:为避免冲突,约定 D 寄存器分区使用
- D0-D499:梯形图使用
- D500-D999:Lua 使用
- D1000-D1999:共享数据区(双方都读写)
位标志约定:M 继电器分配
- M0-M99:梯形图使用
- M100-M199:Lua 使用
- M200-M299:交互标志(Lua 写→梯形图读,或反向)
握手协议:跨引擎通信时使用 M 标志握手。Lua 写入 D500 数据后置位 M200(表示数据就绪);梯形图检测到 M200 后读取 D500,再复位 M200。
⏱️ 运行时序
时序对比见页面顶部的双引擎架构图,要点:
- 梯形图以固定周期扫描执行(通常 1-10ms)
- Lua 以事件驱动方式运行,回调之间可能间隔较长
- 两者访问 D 寄存器是原子操作(单寄存器读写)
- 32 位寄存器(dd/df)读写不是原子的,跨引擎时需注意
🏗️ 典型架构模式
模式一:Lua 做通信,梯形图做控制
lua
-- Lua 端:接收云端指令,写入共享区
mqtt.reg(client, mqtt.RECVDATA, function(topic, payload)
if topic == "pump/start" then
plc.m(200, 1) -- 置位启动标志
end
if topic == "pump/speed" then
plc.d(500, tonumber(payload)) -- 写入速度设定
end
end)梯形图端:检测标志,执行控制
LD M200 -- 检测 Lua 启动标志
OUT Y0 -- 启动水泵
RST M200 -- 复位标志
LD M200
MOV D500 D100 -- 读取 Lua 写入的速度设定模式二:梯形图采集,Lua 上报
lua
-- Lua 端:定时上报梯形图采集的数据
timer.start(5000, function()
local temp = plc.d(500) -- 读取梯形图写入的温度
local pres = plc.d(501)
plc.cloud_publish("temp", tostring(temp))
plc.cloud_publish("pres", tostring(pres))
end)模式三:Lua 独立控制
Lua 脚本 → plc.y/plc.d → 直接控制输出lua
-- 不使用梯形图,Lua 完全控制
timer.start(1000, function()
local temp = plc.df(100)
if temp > 80 then
plc.y(0, 1) -- 开风扇
else
plc.y(0, 0)
end
end)⚠️ 注意事项
32 位寄存器非原子:Lua 写
plc.dd(100, val)时先写 D100 再写 D101,梯形图可能在两次写入之间读取到不一致的数据。用 M 标志做握手避免。扫描周期差异:梯形图扫描周期毫秒级,Lua 定时器回调间隔可能 10ms+。实时性要求高的控制应由梯形图完成。
避免同时写同一地址:梯形图和 Lua 不应同时写同一个 D 寄存器,否则结果不可预测。
Lua 不应替代梯形图做关键控制:安全相关的控制(急停、限位保护)必须放在梯形图中,Lua 只做辅助。
脚本异常不影响梯形图:Lua 脚本崩溃或死循环不会影响梯形图程序的正常运行,但会导致云平台通信中断。
相关例程
想直接抄可运行的脚本,去 例程总览 B-0:按模块分组列出了每个页面里的 3 个完整例程(场景 / 代码 / 要点 / 验证 / 注意事项)。
- 通信:com 串口 · tcp_server · mqtt · pipe 概述 · net
- 云与数据:cloud · json · data · fdb
- 综合工程:Modbus 采集 + MQTT 上报 + 云端下发
写例程的硬规矩(禁止阻塞主循环、API 不编造等)见 B-0 的「写例程时的硬性约定」。
最后更新: 2026-08-04