适用版本:1.0.27 更新日期:2026-10-09
Lua 提供两种周期任务:on_run(screen) 用于工程的常规周期处理,start_timer() 用于按不同周期、次数执行独立任务。时间单位均为毫秒。
| 接口 | 用途 | 返回值 |
|---|---|---|
start_timer(timer_id, timeout, countdown, repeat_count) |
创建指定编号的定时器 | 无返回值 |
stop_timer(timer_id) |
停止指定编号的定时器 | 无返回值 |
set_run_cycle(cycle) |
修改 on_run 的运行周期 |
无返回值 |
on_timer(timer_id) |
定时器到期后,由系统调用的脚本回调 | 不使用返回值 |
on_timer、on_run 是脚本中定义的回调函数。接口参数数量、类型或取值错误会抛出 Lua 错误。无返回值的函数不能用 == 0 判断成功。
start_timer(timer_id, timeout, countdown, repeat_count)
| 参数 | 类型与范围 | 说明 |
|---|---|---|
timer_id |
整数,0~2147483647 | 自定义定时器编号,用于回调分辨任务和停止定时器 |
timeout |
整数,1~2147483647 | 触发周期,单位为毫秒;第一次也在经过此周期后触发 |
countdown |
整数,0~2147483647 | 当前版本保留参数,不参与计时;填写 0 |
repeat_count |
整数,0~2147483647 | 0 表示无限循环;正数表示总触发次数 |
返回值:无。
同时最多存在 16 个定时器。定时器编号不必连续,也不必限制在 0~15。
同一编号已经运行时,再调用 start_timer() 会忽略新请求,并输出提示;不会改变已有定时器的周期、次数或下一次触发时间。需要重设时先调用 stop_timer(),再创建。
定时器槽位用完时只输出提示,不创建新的定时器;当前接口不返回创建状态。建议集中分配编号,避免在业务分支中不断创建不同编号的定时器。
function on_timer(timer_id)
-- 根据 timer_id 执行相应任务。
end
timer_id 是触发本次回调的定时器编号。多个定时器共用一个 on_timer(),用 if 或任务表分配处理逻辑。
定时器到期后,在界面主循环中执行回调。每轮对每个到期定时器最多调用一次;如果脚本或其他任务耗时较长,不会连续补发错过的次数。下一次触发从本轮处理时间重新计算。因此定时器适合界面刷新、周期读取和业务调度,不适合要求严格时序的波形输出。
没有定义 on_timer() 时,不会执行业务代码,但有限次数定时器仍会消耗次数。回调中的 Lua 错误会输出到运行日志,该次到期仍计入触发次数。
local TIMER_POLL = 1
local TIMER_DELAY = 2
local poll_count = 0
function on_init()
start_timer(TIMER_POLL, 1000, 0, 0)
start_timer(TIMER_DELAY, 3000, 0, 1)
end
function on_timer(timer_id)
if timer_id == TIMER_POLL then
poll_count = poll_count + 1
print("周期任务次数:", poll_count)
elseif timer_id == TIMER_DELAY then
print("启动 3 秒后的单次任务")
end
end
local TIMER_RETRY = 3
local retry_count = 0
function on_init()
start_timer(TIMER_RETRY, 500, 0, 5)
end
function on_timer(timer_id)
if timer_id == TIMER_RETRY then
retry_count = retry_count + 1
print("第 " .. retry_count .. " 次处理")
end
end
第四项参数填 5 表示总共触发 5 次,不是“首次执行后再重复 5 次”。
stop_timer(timer_id)
timer_id 为 0~2147483647 的整数。返回值:无。对应定时器不存在时不执行任何操作,也不抛出“未找到”错误。
local TIMER_POLL = 1
function change_poll_period(period_ms)
stop_timer(TIMER_POLL)
start_timer(TIMER_POLL, period_ms, 0, 0)
end
也可以在 on_timer() 中停止自己,或停止后创建同编号的新定时器。新定时器会按新的周期和次数独立计时。
stop_timer 只停止指定编号的 Lua 定时器,不停止 on_run、PLC 协议轮询或整个串口。
页面切换不会自动停止工程定时器。仅在特定页面执行的任务,应在切页回调中停止,或者在 on_timer() 内检查当前页面。脚本关闭或重新加载时,已有定时器全部清除。
set_run_cycle(cycle)
cycle 为 0~2147483647 的整数,单位为毫秒。默认值为 100 ms,最小有效周期为 10 ms;输入 0~9 时按 10 ms 处理。返回值:无。
此接口只修改 on_run(screen) 的周期,不影响 start_timer() 创建的定时器。set_run_cycle(0) 不会关闭 on_run()。
function on_init()
set_run_cycle(200)
end
function on_run(screen)
-- 约每 200 ms 执行一次常规业务。
-- screen 为当前实际主页面 ID。
end
同样,on_run() 的执行受界面主循环调度影响,不承诺严格每 200 ms 准时调用。避免在周期回调中使用长循环、阻塞等待或不断打印大量日志。
如果演示脚本在 on_run 中不断调用 set_*,应在业务入口增加开关。下例中的 pause_demo、resume_demo 是脚本自己定义的函数,可在相应控件事件或业务分支中调用:
local demo_enabled = true
function pause_demo()
demo_enabled = false
end
function resume_demo()
demo_enabled = true
end
function on_run(screen)
if not demo_enabled then return end
-- 在这里执行演示 set_*,或其他需要暂停的周期业务。
end
写入发生在 on_timer 中时,可用 stop_timer(timer_id) 停止对应任务,或在那个回调里检查同一个业务开关。set_run_cycle(0) 会按 10 ms 运行,不能用于停发;也没有注册 uart_stop 或 uart_close Lua 接口。
仅需抑制 DCBUS/DGUS 自动上传时使用 set_notify;PLC 外部寄存器写入不受此开关抑制,说明见寄存器操作函数。
get_timestamp() 返回运行时的毫秒计数,用于计算两次操作之间的间隔;它不是日期时间,也不是 Unix 时间戳。当前返回有符号 32 位整数,长期运行会回绕。计算小于 2147483648 ms(约 24.8 天)的短间隔时,直接使用整数相减;Lua 整数运算会按 32 位回绕。
local start_ms = nil
function on_init()
start_ms = get_timestamp()
start_timer(4, 1000, 0, 1)
end
function on_timer(timer_id)
if timer_id == 4 then
local elapsed_ms = get_timestamp() - start_ms
print("实际经过:", elapsed_ms, "ms")
end
end
| 现象 | 原因与处理 |
|---|---|
| 修改周期后仍按原周期执行 | 同编号已经存在;先停止再重新创建 |
countdown 没有倒计时效果 |
当前版本未使用该参数,固定填 0 |
| 新定时器没有运行 | 检查是否超过 16 个、编号已存在,以及是否正确定义 on_timer |
| 定时任务在切页后仍执行 | 定时器属于工程脚本,按业务需要显式停止 |
第四项参数填 -1 报错 |
无限循环应填 0,负数不合法 |
set_run_cycle(0) 后仍调用 on_run |
最小周期为 10 ms;此接口没有停止语义 |
| 定时回调间隔比设置值大 | 主循环或回调耗时;缩短回调,拆分工作,不使用阻塞等待 |
以上示例用于说明接口与脚本结构。使用时将示例逻辑合并到工程已有的回调中,同名回调只保留一份。