Previously, we discussed configuring screens with Modbus master and slave in engineering projects. However, when encountering "one master and multiple slaves + complex logic" (such as reading the sum of electricity from two slaves, writing to registers based on conditions, and batch writing to coils), relying solely on binding variables to the screen is insufficient. LUA scripts must be used to take over communication. This article will thoroughly explain the Modbus-related LUA APIs, with code examples from real-world projects in the documentation. I have added annotations and pitfall warnings from an engineer's perspective.
1. Core Communication API
1.1 start_read —— Background automatic polling (most commonly used)
This is a scheduling function for periodically reading slave registers in master mode. After calling, the system adds it to the communication queue, automatically sends requests every cycle, and writes the returned data into the HMI memory image. You can directly read the cache usingget_uint16/get_float, withno communication delay..
start_read(index, vtype, addr, quantity, cycle, cycle_run, mode)| Parameters | Type | Description |
|---|---|---|
| index | number | Task index 0~127, used when stopping read |
| vtype | number | Data type VT_3x / VT_4x, etc. |
| addr | number | Register address |
| quantity | number | Read quantity 1~120 |
| cycle | number | Polling cycle multiplier, 0=read every cycle |
| cycle_run | number | Execution count within the cycle (0-based, must be < cycle) |
| mode | number | 0=continuous reading (default) / 1=read only once |
start_read(0, VT_4x, 0x1000, 10)→ read 4x1000~1009 every cyclestart_read(1, VT_4x, 0x2000, 10, 3, 2)→ Every 3 cycles, read 4x2000~2009 in the 3rd cycle1.2 Other management functions
stop_read(index): Stop a single polling task, cache retains the last valuestop_all_read(): One-click stop all, suitable for reset/emergency stopset_auto_read(en): 1=Enable automatic reading of screen binding variables (default), 0=Rely only on scriptstart_readTake over, suitable for redundancy removal in high bandwidth scenarios
1.3 select_slave —— Switch slave (critical)
Under multiple slaves,select_slave(slave_id)temporarily specify which slave to access nextget_xxx/set_xxx.Note that slave_id is the index of the slave list, not the Modbus station number!
| Terminology | Meaning | Example |
|---|---|---|
| Slave index slave_id | HMI internal list index 0,1,2 | 0 = first slave |
| Modbus station number | Device physical address | 10, 33 |
II. LUA reading registers (with online judgment)
Before reading, two things cannot be omitted:Determine if the slave is online + Select the correct slave. The online status is stored in the corresponding bit of the system variableVT_LW 0x01A3.
-- 读保持寄存器 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
-- 读两个从机电量求和,写回 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
endIII. LUA Write Registers
-- 写单个保持寄存器 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
endAn example of weighing calibration (three calibration modes), showingon_updatebranching writing based on the LW variable in the callback:
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
endIV. Batch Write Coils (0x0F Package)
The minimum unit for batch writing coils in VisualHMI is 16-bit alignment. The following function is for the large color package (non-system API, written by myself), demonstrate how to write 14 coil values together:
mb_write_coil_15(slave_id, addr, coilsTb)
-- slave_id: 从站索引; addr: 起始地址; coilsTb: 线圈值表This article is compiled from the "Modbus Application" section of the VisualHMI development documentation LUA tutorial by Guangzhou Dacai Technology. The code and API are faithfully preserved from the original text. The copyright belongs to Dacai Technology. Here, we add engineer's notes and key annotations for learning and reference purposes only.
Leave a Reply