Modbus 一主多从:HMI 作为 Modbus 主机,通过 start_read 后台轮询多个从机的寄存器。核心函数 start_read 建任务、get_xxx 读缓存、on_cmd_resp 收结果——不阻塞脚本。
1. start_read 参数
start_read(index, vtype, addr, quantity, cycle, cycle_run, mode)
| 参数 | 说明 |
|---|---|
| index | 任务索引 0~127,stop_read(index) 用 |
| vtype | 寄存器类型(VT_0x/VT_3x/VT_4x 等) |
| addr | 起始地址 |
| quantity | 读取数量 1~120 个寄存器 |
| cycle | 选填,轮询周期倍数(默认 0=每周期都读) |
| cycle_run | 选填,周期内第几次执行(0-based,须 < cycle) |
| mode | 选填,0=持续周期读(默认)/1=仅读一次(需先 create_resp_que()) |
2. 基本用法
function on_init() -- 每周期都读从机0的 4x1000~1009(10个寄存器) start_read(0, VT_4x, 0x1000, 10) -- 每 3 个周期读一次从机1的 4x2000~2009,且在周期内第3次执行 start_read(1, VT_4x, 0x2000, 10, 3, 2) end function on_run(screen) -- 读数据直接拿缓存,零通信开销 local v = get_uint16(VT_4x, 0x1000) local f = get_float(VT_4x, 0x2000) end
start_read 只建任务,实际数据靠 get_xxx 从本地缓存读——和寄存器操作篇同一个机制。要拿读完成通知,用 on_cmd_resp 回调(需 create_resp_que 配合)。
3. 多从机轮询调度
-- 8 台从机,每台读 20 个寄存器,错开周期避免总线拥堵
function on_init()
for i = 0, 7 do
start_read(i, VT_4x, 0x0000, 20, 8, i) -- 8周期轮一遍,每周期读一台
end
end
function on_cmd_resp(slave, vtype, addr, count, ret, wr)
if ret == 0 then
-- 第 slave 台从机读取成功,处理数据
else
-- 通信异常,标记从机离线
end
end
从机多了总线带宽有限,用 cycle/cycle_run 错峰读;异常在 on_cmd_resp 里 ret 非 0 判断,做离线标记。
三个坑:①quantity 最大 120,超过要分多次 start_read;②cycle_run 必须小于 cycle,且 cycle_run 从 0 计数;③stop_read 停止任务后缓存保留最后值——不会清零,判断离线要靠 on_cmd_resp 的 ret。
整理自 广州大彩科技 VisualHMI 开发文档(hmi-doc.gz-dc.com)LUA 教程「Modbus一主多从」,版权归大彩科技所有。
发表回复