Skip to content

🚀 第一个 Lua 脚本 ​

从编写到运行,5 分钟完成第一个 LPPLC Lua 程序


📖 编写 Lua 脚本 ​

从写好脚本到看到输出:新建 → 下载 → 重启 → 看日志

入口有两个,推荐用新版上位机

设备自带的 Web 管理页面可以写脚本;新版上位机工具里有基于 Monaco 的 Lua 编辑器 (自动补全、语法检查、右侧 API 面板),体验更好 —— 用法见 上位机工具 · Lua 脚本编辑器。 两边都是下载后要重启设备才生效。

第 1 步:进入 Lua 编辑页面 ​

  1. 浏览器访问 LPPLC 的 IP 地址(如 http://192.168.1.100)
  2. 登录管理页面
  3. 点击 "Lua 脚本" 菜单进入编辑器

第 2 步:编写脚本 ​

在编辑器中输入以下代码:

lua
-- 我的第一个 Lua 脚本
print("Hello, LPPLC!")

-- 读取 X0 输入状态
local x0 = plc.x(0)
print("X0 状态: " .. x0)

-- 将 D100 的值加 1 写入 D101
local val = plc.d(100)
plc.d(101, val + 1)
print("D100 = " .. val .. ", D101 = " .. (val + 1))

-- 控制 Y0 输出
if x0 == 1 then
    plc.y(0, 1)
    print("Y0 已开启")
else
    plc.y(0, 0)
    print("Y0 已关闭")
end

print("脚本执行完毕")

第 3 步:下载运行 ​

  1. 点击 "下载" 按钮将脚本写入设备
  2. 点击 "运行" 按钮执行脚本
  3. 在 "日志输出" 窗口查看运行结果

预期输出 ​

Hello, LPPLC!
X0 状态: 0
D100 = 0, D101 = 1
Y0 已关闭
脚本执行完毕

🔄 让脚本持续运行 ​

上面的脚本只执行一次就结束了。要让它一直跑,不需要自己写主循环:把定时器、回调这些注册好, 让脚本正常走到最后一条语句结束就行 —— 脚本一结束,固件自动进入消息泵分发消息, 之后到点的定时器、收到的 MQTT / 串口数据照常触发回调。

写法一:注册完定时器,让脚本自然结束(推荐) ​

lua
-- 定时器模式:注册回调函数,不需要主循环
print("脚本启动")

-- 每 1 秒读取 D100 并打印
timer.start(1000, function()
    local val = plc.d(100)
    print("D100 = " .. val)
end)

-- 每 5 秒上报云平台
timer.start(5000, function()
    local temp = plc.df(100)
    plc.cloud_publish("temperature", tostring(temp))
end)

print("定时器已注册")

说明:这段脚本没有循环、没有 return,跑到 print 就结束 —— 这是故意的, 结束后固件才开始替它泵消息。真要在脚本里写循环,见下面两种写法。

写法二:一个脚本同时做几件事 —— 用协程 ​

要一边轮询串口、一边按时上报,就把两条流程各写进一个协程,在协程里用 system.sleep 等待: 协程内的 sleep 是挂起,不是阻塞,主线程照旧分发消息,两条流程互不耽误。 完整写法见 协程 的例程 1。

⚠️ 协程那套循环只能在协程里跑。把它抄到主线程上(while true do ... system.sleep ... end), 消息泵就断了 —— 症状是"定时器不触发、MQTT 回调没反应、设备像死机", 成因见下面写法三里那个警示框。

写法三:要一直跑、中间还要等 —— 用任务 ​

比协程更省事的形状:task.start 起一个后台任务,循环写在任务体里, system.sleep / event.wait 都是让出。适合"采集 → 等设备回应 → 再处理"这类分步流程。

lua
-- 任务模式:一段代码在后台一直跑,等待期间其它功能照常
task.start(function()
    while true do
        local val = plc.d(100)
        print("D100 = " .. val)
        system.sleep(1000)          -- 让出一拍,不是阻塞
    end
end)

完整说明与更多例程见 后台任务 与 事件订阅与发布。

主循环里只能用 system.recv,绝不能用 sleep

主线程里的 while true do ... system.sleep(n) ... end 会堵死消息泵 —— 期间定时器、MQTT/TCP/串口回调、on_change 一个都不会触发,设备看起来像死机。

lua
-- 错误:回调永远不触发
while true do
    do_work()
    system.sleep(5000)   -- 真阻塞,不推进消息泵
end

-- 正确①:按时做几件事 → 定时器(推荐)
timer.start(5000, do_work)

-- 正确②:几件事同时进行 → 协程
coroutine.wrap(function()
    while true do
        do_work()
        system.sleep(5000)   -- 协程内:挂起,不阻塞
    end
end)()

-- 正确③:一直跑、中间还要等 → 任务
task.start(function()
    while true do
        do_work()
        system.sleep(5000)   -- 任务内:让出一拍
    end
end)

system.sleep 只在协程内或任务内才不阻塞(那里是让出而非阻塞),主线程里永远不要用。

2026-10-22 起脚本侧的 system.recv 已删除(消息泵改在固件 C 侧)。 更早的工程里那种 while true do system.recv(10) end 手写主循环,现在会报 attempt to call a nil value —— 把整段删掉即可,脚本注册完定时器/任务直接结束,泵由固件接管。

怎么选:只是按时做几件事 → 写法一;几件事同时进行、要写顺 → 写法二(协程); 一直跑、中间还要等 → 写法三(任务)。


🛠️ 实用入门脚本 ​

闪烁 LED ​

lua
local led_state = 0
timer.start(500, function()
    led_state = 1 - led_state
    plc.led(led_state)
end)
print("LED 闪烁中")

定时采集存储 ​

lua
-- 每 2 秒采集 D100 温度值存入 D200-D219 循环缓冲
local buf_index = 0
local buf_size = 20

timer.start(2000, function()
    local temp = plc.d(100)
    plc.d(200 + buf_index, temp)
    buf_index = (buf_index + 1) % buf_size
end)
print("采集任务已启动")

简单 MQTT 上报 ​

lua
local client = mqtt.creat("broker.emqx.io", 1883, "lpplc_demo", "", "")

client:reg(mqtt.CONNECTED, function()
    print("MQTT 已连接")
end)

client:reg(mqtt.DISCONNECTED, function()
    print("MQTT 已断开")
end)

client:start()

-- 每 10 秒上报一次
timer.start(10000, function()
    if mqtt.is_linked(client) then
        local temp = plc.d(100)
        mqtt.publish(client, "demo/temp", tostring(temp), 1)
        print("已上报: " .. temp)
    end
end)

⚠️ 常见问题 ​

问题原因解决方法
日志无输出脚本未下载或未运行点击"下载"→"运行"
脚本执行一次就停了没有 timer.start 或 while 循环使用定时器模式
plc 报 nil模块名拼写错误使用小写 plc,不是 PLC
定时器回调不触发脚本里用 sleep 阻塞了,或自己写了 while true 死循环改回 timer.start;要"一直跑、中间还要等"用 task.start
修改脚本后行为不变只修改未下载修改后需重新点击"下载"

上一篇:表与数据结构 | 下一篇:系统功能

相关例程 ​

想直接抄可运行的脚本,去 例程总览 B-0:按模块分组列出了每个页面里的 3 个完整例程(场景 / 代码 / 要点 / 验证 / 注意事项)。

写例程的硬规矩(禁止阻塞主循环、API 不编造等)见 B-0 的「写例程时的硬性约定」。

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