VisualHMI Lua API Complete Guide: Quick Reference Table for Callback, Communication, and Register Read/Write Functions

freeFree Technical Resource

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

This is the complete API manualfor the Lua script of the VisualHMI platform: 10 system callback functions + 32 read-write register functions + 10 drawing functions, totaling 52 interfaces. Before writing scripts, review this document, which is faster than going through the tutorials one by one. The platform is based on Lua 5.3.

0. Basics: The automatically generated main.lua

menu: Project → Script Programming. By default, main.lua is generated, automatically including the data type definitions corresponding to the protocol:

ENCRYPT_ = 0        -- LUA脚本加密开关
-- 数据类型定义(随协议变化,以下为 Modbus)
VT_LW = 1           -- 内部变量
VT_RW = 2           -- FLASH掉电存储
VT_0x = 10          -- 线圈
VT_1x = 11          -- 输入点(离散输入)
VT_3x = 12          -- 输入寄存器
VT_4x = 13          -- 保持寄存器

function on_init() end
function on_run(screen) end
function on_update(slave,vtype,addr) end
function on_draw(screen_id,control_id) end

Under the FX3U protocol, there are also types such as VT_M (internal relay) and VT_D (D register). The first parameters of the vtype, get/set functions in on_update use these constants.

1. Common callback functions (10)

CallbackTrigger timingKey points
on_init()Immediately execute once after the system loads LUAInitialize, dofile to load other Lua scripts, and write initial values
on_run(screen)Each main loop cycle automatically callscore cycle scheduling. It is prohibited to use delay_ms/long loops/network synchronization/internal set_run_cycle(); when acting as a Modbus master, avoid high-frequency writes to slaves (bus congestion)
on_update(slave,vtype,addr). Register/variable value changes triggerdata-driven non-polling. Serial port/Modbus master writes and set_xxx in on_update do not trigger (to prevent recursion); the global EN_ON_UPDATE_API_CB can be used to control the switch
on_screen_change(screen). After the screen transition is complete,initialization/state synchronization/resource loading
on_press(state,x,y). Touch state changes are triggered at most once every 100ms. state: 0 for lifted/1 for pressed/2 for long pressed (pressed only triggers once); underlying coordinates, tapping on empty space also triggers
on_usb_inserted(driver). U-disk insertion recognition. driver is the drive letter, M series is "2:", recorded using a global variable
on_usb_removed(). U-disk unplugged. Clear the drive letter global variable
on_sd_inserted(dir)SD card insertion recognitiondir drive letter, M series is "1:"
on_sd_removed()SD card removalclear drive letter global variable
on_parse_timestamp(screen,control,timestamp)format time field of alarm/data/operation record tablecontrol must not be equal to 0; paired with make_datetime(timestamp) to return a custom time string

2. Read-write register functions (32 in total)

2.0 First, let's discuss two key mechanisms (common to all set/get functions)

Mechanism 1: get_xxx() has zero communication overhead.The get series all read from the HMI local cache (memory mapping) without generating serial port frames. The HMI background task automatically reads communication variables (such as VT_3x/VT_4x of Modbus) from the PLC and caches them according to the polling period configured by the project. If a screen control is bound to a certain address, that address will automatically be added to the polling list; if a script needs to read an address not referenced by the project, it can explicitly request synchronization using start_read.

Mechanism 2: set_xxx() does not necessarily send serial port frames.Only when both conditions are met will a message be actively sent: ① the HMI is in host mode (Modbus Master/DCBUS/XGUS); ② serial port notifications have not been disabled by set_notify(0). In slave mode, set only updates the local mapping.

2.1 Communication Control

FunctionParameterDescription
set_notify(enable)0: Disable / 1: Enable (Default)Global Serial Port Notification Switch. After setting_notify(0), set_xxx does not send serial port commands. To restore, set_notify(1)
select_slave(slave_id)Slave Index Starting from 0Switch the subsequent get/set access to the slave in multi-slave mode. slave_id is the index of the slave list array in the project, not the Modbus station number
set_endian(en)0: Big-endian (Default) / 1: Little-endianByte order for multi-byte data (uint16/32/float) exchanged with the slave. Only effective when the communication protocol involves multi-byte data
start_read(index,vtype,addr,quantity,cycle,cycle_run,mode)index: 0~127; quantity: 1~120; cycle: polling multiplier (Default 0=every cycle); cycle_run: the number of times within the cycle (0-based); mode: 0: Continuous / 1: Only onceHost mode: Background automatic polling. No return value, data is read from the cache using get_xxx. mode=1 requires creating_resp_que() first
stop_read(index)Task IndexStop specifying background read tasks, cache retains the last value
stop_all_read()-Stop all script-initiated read tasks
set_auto_read(en)1: Enabled (default)/0: DisabledOverall switch for automatic polling of screen binding variables. 0: Fully managed by start_read
create_resp_que()-Create a response queue, coordinate with start_read(mode=1) for single-time on-demand reading
on_cmd_resp(slave,vtype,addr,count,ret,wr)ret: 0 for success/1 for exception; wr: 0 for read/1 for writeAsynchronous callback for host mode communication results, triggered by receiving a response or timeout. Determine the success or failure of single read/write operations
set_slave_site(idx,slave_id)idx: Slave index; slave_id: New station number (Modbus 1~247)Dynamically change the slave station number during runtime to adapt to on-site networking

2.2-bit operation

FunctionParameterDescription
set_bit(vtype,addr,value,count)value 16-bit unsigned, with the lower count bits corresponding to the target bits (bit0→addr, bit1→addr+1, etc.); count optional 1~16Batch bit write. Modbus coil, X/Y/S/M of FX3U are all supported. Write multiple switches in one communication
get_bit(vtype,addr)-Read a single bit, return 0/1. Read from local cache, with zero communication overhead

2.3 Numerical read and write (16/32/64 bits)

FunctionNumerical rangeAddress span
set/get_uint16(vtype,addr,value)0~65535, truncated & 0xFFFF if exceeded1 register
set/get_int16(vtype,addr,value)-32768~+32767, truncated & 0xFFFF if exceeded1 register
set/get_uint32(vtype,addr,value)0~4294967295, truncated & 0xFFFFFFFF2 registers
set/get_int32(vtype,addr,value)-2^31~2^31-12 registers
set/get_uint64(vtype,addr,value)0~2^64-14 registers
set/get_int64(vtype,addr,value)-2^63~2^63-14 registers
set/get_float(vtype,addr,value)IEEE 754 single precision2 registers
set/get_double(vtype,addr,value)IEEE 754 double precision4 registers

All get series read local cache; set series communication triggers refer to "Mechanism 2".

2.4 Strings and batching

FunctionsParametersDescription
set_string(vtype,addr,str)str max 2K bytes, UTF-8 or GBKWrite string to address sequence
get_string(vtype,addr,len)len optional, default 128 bytes, max 2048Read string, automatically truncated
set_uint16_ex(vtype,addr,value1,...,valueN)up to 120 valuesVariable parameter batch write to consecutive registers, suitable for fixed parameter sets
set_array(vtype,addr,buff)buff is a Lua table (word array) with a maximum of 120 characters.Batch writing of tables, suitable for programmatic generation/dynamic data. The difference from set_uint16_ex lies in the parameter passing method.

3. Drawing functions (10)

All draw_xxx functions must be called within theon_draw(screen_id,control_id)callback to take effect, and the control ID must be ≠ 0. Layers are managed according to the control Z-axis (editor stacking order), and drawing is layered based on the control_id. The active refresh callsredraw().

functionwith parameterdescription
set_pen_color(color)RGB565: high 5 bits R (0~31)/middle 6 bits G (0~63)/low 5 bits B (0~31)to set the brush (foreground) color. Red 0xF800, green 0x07E0, blue 0x001F, white 0xFFFF, black 0x0000
draw_line(x0,y0,x1,y1,width)width 1~10draws a straight line, using the current brush color
draw_rect(x0,y0,x1,y1,fill)fill 1 filled/0 bordertop left + bottom right coordinates
draw_rect_alpha(x0,y0,x1,y1,alpha)alpha 0~255 (0 transparent/255 opaque)semi-transparent solid rectangle, commonly used in mask layers
draw_circle(x,y,r,fill)fill 0 solid/non-0 hollow (value as line thickness)center + radius
draw_ellipse(x0,y0,x1,y1,fill)fill 0 solid/non-0 hollowbounding rectangle defines ellipse
draw_image(image_id,frame_id,dstx,dsty,width,height,srcx,srcy)image_id check in build/image.xml; frame_id animation frame (non-animation=0)draw image, supports scaling + cropping. image_id check in image.xml in the project build directory
draw_text(text,x,y,w,h,font_id,size,color,align,charcode)align 0 left/1 center/2 right; charcode 0=UTF-8 (default)/1=GBKregional text drawing, supports multi-byte characters
draw_surface(surface,x,y,w,h,srcx,srcy)surface is a screen/canvas resourcefor screen cropping display and multi-layer composition.

4. Drawing Example: Switch Table-Driven

All drawing examples in the source text follow the same pattern: read button key values in on_update → redraw() → check the switch table for the key values in on_draw to select the drawing function. Taking drawing a line and a circle as an example:

draw_type = 0
mode = { line = 1, rect = 2, rect_alpha = 3, circle = 4, ellipse = 5, imageId = 6, text = 7 }

function on_update(slave,vtype,addr)
  if addr == 0x1000 then
    draw_type = get_uint16(VT_LW, addr)  -- 字设置按钮键值
    redraw()
  end
end

function on_draw(screen_id, control_id)
  local switch = {
    [mode.line] = function(control)
      if screen_id == 0 and control == 1 then
        set_pen_color(0xFFE0)          -- 黄色
        draw_line(225, 253, 405, 253)
        set_pen_color(0xF800)          -- 红色
        draw_line(508, 128, 508, 378, 5)
      end
    end,
    [mode.circle] = function(control)
      if screen_id == 0 and control == 1 then
        draw_circle(300, 253, 100, 0)  -- 实心圆
        draw_circle(450, 253, 150, 1)  -- 空心圆,线厚1
      end
    end,
  }
  if switch[draw_type] then switch[draw_type](control_id) end
end
Three points that are most prone to errors:① get_xxx reads cached values instead of real-time values-- To read the address of an unbound control, first synchronize with start_read;② set_xxx does not send serial port frames in slave mode-- It is normal for the MCU not to receive them, so don't spend a long time checking the baud rate;③ set_run_cycle() and delay_ms are strictly prohibited in on_run, as the scheduler may deadlock. Drawing must be placed in on_draw, and the control ID must be non-zero.

Compiled from VisualHMI development documentation of Guangzhou Dacai Technology (hmi-doc.gz-dc.com) LUA tutorial "Lua Script API Function Interface", copyright reserved by Dacai Technology.

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 *.