VisualHMI LUA 做 Modbus 一主多从:start_read/select_slave 実践与坑

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

前面讲了屏在工程里配 Modbus 主从,但碰到"一主多从 + 复杂逻辑"(比如读2つスレーブ的电量求和、按条件写レジスタ、バッチ書き込みコイル),光靠画面変数の束縛不够,得用 LUA script接管通信。这篇把 Modbus 相关的 LUA API 讲透,代码都是大彩ドキュメント里的真实例程,我加了エンジニア视角的注解和踩坑提示。

⚠️ 适用範囲: HMI&M&Dx 系列。サンプル是 Modbus 2つスレーブ,ステーション番号 10 和 20,逻辑对 FX2N/FX3U 主从同样适用。

一、核心通信 API

1.1 start_read —— 后台自动ポーリング(most common)

マスターモード下周期性读スレーブレジスタ的调度函数。调用后系统把它加进通信队列,每个周期自动发リクエスト,戻るデータ写进 HMI 内存镜像,你用 get_uint16/get_float 直接读缓存,ない通信延迟

start_read(index, vtype, addr, quantity, cycle, cycle_run, mode)
parameterType説明
indexnumber任务索引 0~127,stop_read 时用
vtypenumberdata type VT_3x / VT_4x 等
addrnumberregister address
quantitynumberReading quantity 1~120
cyclenumberポーリング周期倍数,0=每周期都读
cycle_runnumber周期内第几次执行(0-based,需 < cycle)
modenumber0=持续读(デフォルト) / 1=仅读一次
💡 调度精髓: cycle/cycle_run 用来分高低频。高频变量(速度、temperature)cycle=0 每周期读;低频变量(累计量、ステータス字)cycle=5, cycle_run=4 每 5 周期读一次,降バス負荷。例:
start_read(0, VT_4x, 0x1000, 10) → 每周期读 4x1000~1009
start_read(1, VT_4x, 0x2000, 10, 3, 2) → 每 3 周期、No. 3 个周期读 4x2000~2009

1.2 其它管理函数

  • stop_read(index):停单个ポーリング任务,缓存保留最后一次值
  • stop_all_read():一键停すべて,适合复位/急停
  • set_auto_read(en):1=有効画面绑定变量自动读(デフォルト),0=只靠脚本 start_read 接管,适合高带宽场景去冗余

1.3 select_slave —— 切换スレーブ(关键)

多スレーブ下,select_slave(slave_id) 临时指定后续 get_xxx/set_xxx アクセス哪个スレーブ。注意 slave_id 是スレーブリスト下标,ではない Modbus ステーション番号!

术语含义example
スレーブ索引 slave_idHMI 内部リスト下标 0,1,20 = 第一个スレーブ
Modbus ステーション番号デバイス物理アドレス10, 33
⚠️ 最容易错的点: slave_id=0 对应ステーション番号 10,slave_id=1 对应ステーション番号 33,这个マッピング在工程設定里定。脚本里填错下标就读到别的スレーブ去了,查半天以为是协议問題。

二、LUA 读レジスタ(带オンライン判断)

读之前两件事不能省:判断スレーブオンライン + 选对スレーブ。オンラインステータス存在系统变量 VT_LW 0x01A3 的对应位。

-- read holding registers 4x
function mb_read_reg_03(slave, addr)
  local onlineState = get_uint16(VT_LW, 0x01A3)   -- スレーブオンラインステータス字
  if ((onlineState >> slave) & 0x01) == 0x01 then  -- 该スレーブオンライン
    select_slave(slave)                            -- 切到这个スレーブ
    return get_uint16(VT_4x, addr)                 -- 读缓存
  else
    return false
  end
end

-- 读2つスレーブ电量求和,写回 LW 区
function on_run(screen)
  local Energy1 = mb_read_reg_03(0, 0x0000)
  local Energy2 = mb_read_reg_03(1, 0x0000)
  if Energy1 ~= false and Energy2 ~= false then
    set_uint16(VT_LW, 0x1000, Energy1 + Energy2)
  end
end

三、LUA 写レジスタ

-- 単一保持レジスタの書き込み 0x06
function mb_write_reg_06(slave, addr, value)
  local onlineState = get_uint16(VT_LW, 0x01A3)
  if ((onlineState >> slave) & 0x01) == 0x01 then
    feed_dog()              -- 喂狗,防脚本卡死ウォッチドッグ复位
    select_slave(slave)
    set_uint16(VT_4x, addr, value)
    return true
  else
    return false
  end
end
⚠️ 重点:写之前务必 feed_dog()。 LUA script跑在屏的实时任务里,长时间不喂狗会被ウォッチドッグ当死循环干掉,屏再起動。凡是循环或耗时逻辑,間隔里加 feed_dog。

一个称重校准的实例(三种校准モード),表示 on_update 回调里根据 LW 变量做分支写:

function on_update(slave, vtype, addr)
  if vtype == VT_LW and addr == 0x1004 then
    local mode = get_uint16(VT_LW, 0x1003)
    if mode == 0 then
      mb_write_reg_06(0, 0x1002, 57)            -- 零点校准
    elseif mode == 1 then
      local w = get_uint16(VT_LW, 0x1005)        -- 砝码校准
      mb_write_reg_06(0, 0x1002, w)
    elseif mode == 2 then
      local c = get_uint16(VT_LW, 0x1006)        -- 实物校准
      local s = get_uint16(VT_LW, 0x1007)
      if c > 0 and s > 0 then
        mb_write_reg_06(0, 0x1002, (s*w)//c)
      end
    end
  end
end

四、バッチ書き込みコイル(0x0F 封装)

VisualHMI バッチ書き込みコイル最小単位是 16 位对齐。下面这个函数是大彩封装的(非系统 API,自己写的),演示如何把 14 1つのコイル值合并写入:

mb_write_coil_15(slave_id, addr, coilsTb)
-- slave_id: スレーブ索引; addr: starting address; coilsTb: コイル値表
デバッグ提示: 联机验证用 Modbus Slave 软件 + バーチャルシリアルポート对,让屏当マスター、电脑当スレーブ,实时看总电压/总电量变化。比直接上真机快得多。

本記事整理自 广州大彩科技 VisualHMI 开发ドキュメント LUA Tutorial「Modbus 应用」章节,代码与 API 均按原文保真,著作権は大彩科技すべての,此处加エンジニア注解与重点标注,参照文献のみ。。

Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email address will not be published. Required fields are marked *.