Lua 脚本用于读写本地 LW、掉电保存 RW 及外部 PLC 变量。vtype 选择存储区,函数名决定数据格式。
核心功能
- 数值、位、字符串及连续数组读写。
- Modbus、FX、DVP、XC、XD 地址映射。
- 从站选择、持续预读与变量更新通知。
完整的四区操作与双从站示例见 5.6 Modbus 读写。
1. 地址与类型
| 变量类型 | vtype | 地址说明 |
|---|---|---|
| LW 本地变量 | 1 | 字地址 0x0000~0xFFFF |
| RW 掉电保存变量 | 2 | 字地址 0x0000~0x7FFF |
| Modbus 0x 线圈 | 3 | 每地址一个位,使用工程配置的数值地址 |
| Modbus 1x 离散输入 | 4 | 每地址一个位;主站访问外部设备时只读 |
| Modbus 3x 输入寄存器 | 5 | 每地址一个 16 位字;主站访问外部设备时只读 |
| Modbus 4x 保持寄存器 | 6 | 每地址一个 16 位字,使用工程配置的数值地址 |
屏作为 Modbus Slave 时,屏内 Lua 可以更新 1x/3x 输入数据,供外部主站读取;外部主站仍不能经写功能码写入这两个区。
Modbus 使用数值地址,例如保持寄存器地址 100 写作 get_uint16(6, 100),不能仅凭设备标签 40101 就把 40101 直接代入。FX、DVP、信捷等 PLC 的 vtype 和地址范围按各自协议的软元件映射选择,不能套用 Modbus 类型表。
运行库没有预设 VT_*、LW、RW 等 Lua 常量;请先添加公共定义,再选择与工程通信协议一致的一段。
数值和位读取函数成功时返回一个数值,字符串读取返回字符串。set_* 成功时没有返回值;数值读写、位读写及写入接口在参数错误、地址或类型不支持、读写失败时抛 Lua 错误,可以用 pcall 捕获。字符串读取规则见“2.3 字符串”。不能通过 set_uint16(...) == 0 判断成功。
主站 get_* 读取运行库中的缓存,调用后不会同步等待 PLC 应答。主站 set_* 校验通过后先提交本地可读值,再尝试发送 PLC 命令;函数正常返回或触发 on_update,均不等于 PLC 已执行。首次缓存值也不能作为设备在线的判断依据。
地址参数使用工程的数值索引。例如 D100 的 addr 是 100;X/Y 的手册编号可能采用八进制表示,脚本应使用工程已经换算后的索引,不把手册标签数字直接作为索引,也不在运行库收到索引后再转换一次。
1.1 公共定义
在 main.lua 顶部先放公共定义,再从 1.2~1.6 中选择与工程通信协议对应的一段。下面使用全局 VT_名称 = 编号、十进制编号和中文注释,便于在各业务回调中直接引用。
--数据类型定义
--VTYPE
VT_LW = 1 --变量地址,屏内LW
VT_RW = 2 --FLASH存储,屏内RW
LW = VT_LW --兼容旧脚本:变量地址
RW = VT_RW --兼容旧脚本:FLASH存储
VT_* 表示寄存器区域;get_uint16、get_int32、get_float 等函数名决定数值格式。常量必须先定义再使用,Lua 区分大小写,例如 VT_0x 中的 x 为小写。
不同协议的定义只选一段,不要同时粘贴。 例如 D 区在 FX 中是 10、DVP 中是 11、信捷 XC 中是 9、信捷 XD 中是 17。同名常量后定义会覆盖前定义,常量赋值不会自动切换工程通信协议。
下列编号表示当前运行库识别的区域,不代表每一种 PLC 型号都具备全部区域或容量。地址范围、写权限和通信参数须与工程及实际设备一致。
1.2 Modbus RTU 主站/从站
lua 复制代码--Modbus寄存器类型
VT_0x = 3 --线圈,位区
VT_1x = 4 --输入点,位区
VT_3x = 5 --输入寄存器,16位字区
VT_4x = 6 --保持寄存器,16位字区
主站访问外部设备时,1x、3x 只读;0x、4x 可写。屏作为 Modbus 从站时,Lua 可以更新屏内四个区域,包括 1x、3x;外部主站仍不能通过写功能码写输入区。
--写法示例:在业务需要时调用
-- get_bit(VT_0x, 0) --读取地址0的线圈
-- set_bit(VT_0x, 0, 1) --地址0的线圈置1
-- get_uint16(VT_4x, 100) --读取保持寄存器地址100
-- set_uint16(VT_4x, 100, 123) --保持寄存器地址100写入123
addr 使用工程配置的数值地址,不把设备标签 40001 默认当成第一个地址。单点用 get_bit/set_bit;Modbus 位区的 get_uint16/set_uint16 会访问连续 16 点,不能用于代替单点操作。
1.3 三菱 FX2N/FX3U
lua 复制代码--三菱FX寄存器类型
VT_X = 3 --输入继电器,位区
VT_Y = 4 --输出继电器,位区
VT_S = 5 --状态继电器,位区
VT_M = 6 --辅助继电器,位区
VT_SM = 7 --特殊辅助继电器,位区;当前FX2N不支持此独立区域
VT_TS = 8 --定时器触点状态,位区;当前FX2N不支持
VT_CS = 9 --计数器触点状态,位区;当前FX2N不支持
VT_D = 10 --数据寄存器,16位字区
VT_SD = 11 --特殊数据寄存器,16位字区;当前FX2N不支持此独立区域
VT_R = 12 --文件寄存器,16位字区;当前FX2N不支持
VT_T = 13 --定时器当前值,16位字区
VT_C = 14 --计数器当前值,16位字区
VT_CX = 15 --32位计数器当前值,索引0~55对应C200~C255
FX2N、FX3U 共用以上编号,不能删掉不支持的区域后把后续编号前移。FX2N 的特殊继电器、特殊数据寄存器通过 VT_M 的 8000 段、VT_D 的 8000 段访问;具体地址以设备型号为准。
TS/CS 是触点状态,T/C 是当前值。get_int32(VT_CX, 0) 对应 C200 的完整 32 位计数值,索引应传 0,不是 200。FX 当前从站选择只支持 select_slave(0)。X 为输入状态,实际写权限以 PLC 为准。
1.4 台达 DVP
lua 复制代码--台达DVP寄存器类型
VT_S = 3 --步进继电器,位区
VT_X = 4 --输入继电器,位区,只读
VT_Y = 5 --输出继电器,位区
VT_T = 6 --定时器触点状态,位区
VT_M = 7 --辅助继电器,位区
VT_C = 8 --计数器触点状态,位区
VT_TV = 9 --定时器当前值,16位字区
VT_CV = 10 --计数器当前值,位宽见下文
VT_D = 11 --数据寄存器,16位字区
T/C 是状态,TV/CV 是当前值。CV0~199 为 16 位,CV200~255 每个计数器为原生 32 位,地址步长仍为 1;例如 get_uint16(VT_CV, 199) 与 get_int32(VT_CV, 200)。不要用 16 位接口读取 CV200~255。
当前 DVP 使用 Modbus ASCII。位元件用 get_bit/set_bit,一个地址对应一个位;数值通路支持 16/32 位整数和 32 位浮点,不应直接套用通用 64 位接口。
1.5 信捷 XC
lua 复制代码--信捷XC寄存器类型
VT_X = 3 --输入点,位区,只读
VT_Y = 4 --输出点,位区
VT_M = 5 --辅助继电器,位区
VT_S = 6 --流程继电器,位区
VT_T = 7 --定时器状态,位区
VT_C = 8 --计数器状态,位区
VT_D = 9 --数据寄存器,字区
VT_TD = 10 --定时器当前值,字区
VT_CD = 11 --计数器当前值,字区
VT_FD = 12 --FLASH寄存器,字区
XC 使用 Modbus RTU。T/C 是状态,TD/CD 是当前值。读取 D100 写作 get_uint16(VT_D, 100);M0 使用 get_bit(VT_M, 0)。
1.6 信捷 XD
lua 复制代码--信捷XD寄存器类型
VT_M = 3 --辅助继电器,位区
VT_X = 4 --输入点,位区,只读
VT_Y = 5 --输出点,位区
VT_S = 6 --流程继电器,位区
VT_SM = 7 --特殊继电器,位区,当前驱动只读
VT_T = 8 --定时器状态,位区
VT_C = 9 --计数器状态,位区
VT_ET = 10 --精确定时器状态,位区
VT_SEM = 11 --顺序功能块专用区域,位区,当前驱动只读
VT_HM = 12 --保持型辅助继电器,位区
VT_HS = 13 --保持型流程继电器,位区
VT_HT = 14 --保持型定时器状态,位区
VT_HC = 15 --保持型计数器状态,位区
VT_HSC = 16 --高速计数器状态,位区
VT_D = 17 --数据寄存器,字区
VT_ID = 18 --输入寄存器,字区,只读
VT_QD = 19 --输出寄存器,字区
VT_SD = 20 --特殊数据寄存器,字区,当前驱动只读
VT_TD = 21 --定时器当前值,字区
VT_CD = 22 --计数器当前值,字区
VT_ETD = 23 --精确定时器当前值,字区
VT_HD = 24 --保持型数据寄存器,字区
VT_HSD = 25 --保持型特殊寄存器,字区
VT_HTD = 26 --保持型定时器当前值,字区
VT_HCD = 27 --保持型计数器当前值,字区
VT_HSCD = 28 --高速计数器当前值,字区
VT_FD = 29 --FLASH寄存器,字区
VT_SFD = 30 --特殊FLASH寄存器,字区,当前驱动只读
VT_FS = 31 --特殊保密寄存器,字区,部分资料称FSD
XD 使用 Modbus RTU。XC 的 D 区编号是 9,XD 的 D 区编号是 17,不能混用。 当前 XD 的 SM/SEM/SD/SFD 按只读处理;未开放字符串及 64 位数据类型。
XC/XD 字区按 Modbus 字地址访问。普通 D 区的 32 位整数、浮点数占两个连续字,字节序取工程协议配置;不要由 PLC 计数器名称推断成台达 DVP 的原生 32 位计数器访问规则。
2. 接口说明
2.1 数值读写
当前工程 Lua 使用 32 位有符号整数和 32 位浮点数。函数名中的 32/64 位描述寄存器的存储格式,不会扩大 Lua 的数值范围;64 位寄存器接口也不能直接接收任意 64 位整数。
这些函数的完整签名为 get_类型(vtype, addr) 和 set_类型(vtype, addr, value)。没有可选的位序、从站、字节序或通知参数;选择从站使用 select_slave,通知参数仅属于后面的 set_bit。
| 读函数 | 写函数 | Lua 数值范围/精度 | 占用 |
|---|---|---|---|
get_uint16 |
set_uint16 |
整数 0~65535 | 1 字 |
get_int16 |
set_int16 |
整数 -32768~32767 | 1 字 |
get_uint32 |
set_uint32 |
0~2147483647 | 2 字 |
get_int32 |
set_int32 |
整数 -2147483648~2147483647 | 2 字 |
get_uint64 |
set_uint64 |
0~2147483647 | 4 字 |
get_int64 |
set_int64 |
-2147483648~2147483647 | 4 字 |
get_float |
set_float |
32 位浮点数,约 7 位有效十进制数字 | 2 字 |
get_double |
set_double |
64 位存储,Lua 仍为单精度 | 4 字 |
vtype 和 addr 必须为整数;整数写函数的 value 也必须为整数。浮点写函数接收数值。地址跨度不得回绕,例如从 0xFFFF 起只能读写 1 个本地字,不能存储 32 位或 64 位值。不同 PLC 的原生元素宽度、读写权限和数据类型支持仍以该协议为准。
本地 LW/RW 的多字数值按高字在前保存;PLC 的数值字节序使用工程中对应协议的设置。完整的 UINT32/UINT64/INT64 存储范围超过当前 Lua 整数范围:读取超出上表范围的值时,可能出现高位截断或符号变化;get_uint64 仅在原始值超过 0x7FFFFFFFFFFFFFFF 时另行报错,不能用它自动检测所有 Lua 范围溢出。
需要保留完整的较大整数时,可在 LW/RW 或普通 16 位字寄存器中按字读取,再分别处理各字;不要把超范围的整数文本转成 Lua 数值后写入。PLC 原生 32 位软元件应按该协议的元素规则处理,不能直接套用连续 LW 字的拆分例子。没有注册 get_uint8、set_uint8、get_int8 或 set_int8 接口。
下面在相互独立的地址保存不同类型,再读取:
lua 复制代码local LW = 1
function on_init()
set_uint16(LW, 0x1014, 9)
set_int16(LW, 0x1020, -9)
set_uint32(LW, 0x1030, 70000)
set_int32(LW, 0x1040, -70000)
set_uint64(LW, 0x1050, 1234567)
set_int64(LW, 0x1060, -1234567)
set_float(LW, 0x1070, 12.5)
set_double(LW, 0x1080, 12.5)
print(get_uint16(LW, 0x1014))
print(get_int16(LW, 0x1020))
print(get_uint32(LW, 0x1030))
print(get_int32(LW, 0x1040))
print(get_uint64(LW, 0x1050))
print(get_int64(LW, 0x1060))
print(get_float(LW, 0x1070))
print(get_double(LW, 0x1080))
end
例如用两个本地字保留完整 0xFFFFFFFF,不把它当成一个 Lua 非负整数:
local LW = 1
function write_large_unsigned_value()
set_uint16_ex(LW, 0x1090, {0xFFFF, 0xFFFF})
local high = get_uint16(LW, 0x1090)
local low = get_uint16(LW, 0x1091)
print(string.format("%04X%04X", high, low))
end
2.2 位读写
lua 复制代码get_bit(vtype, addr)
set_bit(vtype, addr, value)
set_bit(vtype, addr, value, notify)
get_bit 返回 0 或 1。set_bit 的 value 只能是整数 0 或 1,成功无返回值。参数中的 addr 是相应变量地址,没有额外的位索引参数;在 LW/RW 字变量上,这两个接口读取或修改该字的第 0 位。
Modbus 类型 3/4 中,get_bit/set_bit 访问地址所指的单点,get_uint16/set_uint16 则访问连续 16 点;例如 set_uint16(3, 0x224, 1) 会把随后 15 点写为 0,单线圈应使用 set_bit(3, 0x224, 1)。类型 5/6 的 get_bit 读取字内 bit0,主站 set_bit(6, ...) 按已确认缓存合并后发送完整字,须先建立有效读回,不提供 PLC 原子掩码写。任意字内位及字段的辅助函数见专门示例。
| notify | 作用 |
|---|---|
| 0 | 当前写入不产生本地 on_update 通知,也不请求主动协议上传 |
| 1 | 默认值:正常变量更新通知,并请求协议通知 |
| 2 | 正常变量更新通知,不请求主动协议上传 |
主动协议上传指 DCBUS/DGUS 的自动上传,仍受工程“自动上传”设置及 set_notify 开关影响。notify=0/2 不会阻止 Modbus、FX、DVP、XC、XD 等主站向外部寄存器发送写命令。外部 PLC 后续真实应答或读回属于独立的缓存更新,不受此前静默写入的限制。需要操作一个 LW 字的其他位时,可先读取完整字,用 Lua 位运算修改,再用 set_uint16 写回:
local LW = 1
function on_init()
set_bit(LW, 0x1100, 1, 2)
print(get_bit(LW, 0x1100))
local value = get_uint16(LW, 0x1101)
set_uint16(LW, 0x1101, value | (1 << 3))
end
PLC 位软元件使用该协议自己的位地址,不把上面的本地字位运算当作 PLC 相邻位的批量写入。
2.3 字符串
读取和写入
lua 复制代码local text = get_string(vtype, addr)
set_string(vtype, addr, text)
vtype 为寄存器类型:1 表示 LW,2 表示 RW;addr 为起始字地址,例如 0x1000 对应工程中的 LW1000。get_string 没有长度参数,返回字符串;set_string 成功无返回值,参数、长度、地址跨度或写入失败时抛出 Lua 错误。
下面以 LW 为例,脚本保存为 UTF-8;实际工程请把示例地址改为已预留的空闲地址。各示例分别使用;工程已有 on_init() 时,把初始化代码合并到原函数,不要重复定义。
local LW = 1
function on_init()
-- 写入字符串到 LW1000
set_string(LW, 0x1000, "你好,鑫通态")
-- 读取 LW1000 的字符串
local text = get_string(LW, 0x1000)
print(text)
end
拼接后写回
Lua 使用 .. 拼接字符串。拼接后先检查字节数,避免超过写入上限:
local LW = 1
local text = get_string(LW, 0x1000)
local result = text .. ",运行正常"
if #result <= 127 then
set_string(LW, 0x1000, result)
else
print("字符串超过127字节")
end
这里的 #result 是字节数,不是中文字符个数。不要直接截取前 127 字节来处理超长中文,否则可能截断一个 UTF-8 字符。
清空字符串
lua 复制代码set_string(1, 0x1000, "")
写入空字符串后,get_string(1, 0x1000) 返回 ""。此操作把起始字写为零,使文本内容为空,不会擦除整个预留区的旧数据。
长度、寄存器空间和中文显示
- 写入最多 127 字节。 接口自动补零结束符,并按完整的 16 位字对齐;占用字数为
math.floor(#text / 2) + 1。 - 为字符串预留连续地址。 若需要支持最大长度,应预留 64 个寄存器,例如 LW1000~LW103F(
0x1000~0x103F),这段地址不要再放其他变量。短字符串只写入所需字数。 - 读取最多 64 个字,即 128 字节。 返回内容在首个零字节处结束;接近地址末端时只读剩余范围。读取失败时可能返回空串或已读到的较短字符串,不能据此判断外部设备在线。
- 接口不做编码转换。 中文按 Lua 字符串原有字节保存,UTF-8 中文通常占多个字节;不要在普通文本中插入零字节。
- 文本控件需匹配编码和字内顺序。 上述例子使用 UTF-8;控件也选择 UTF-8,并使字内顺序与 Lua 写入一致。可先写入
AB验证,控件应显示AB,而不是BA。
本地 LW/RW 按每字高字节在前保存文本字节:"A" 占 1 个字(0x4100),"AB" 占 2 个字(0x4142、0x0000)。
PLC 字符串读写还受驱动的数据区、缓存和字节序设置影响,不是所有 PLC 软元件都支持字符串;不要直接把上述 LW 示例视为已验证的外部 PLC 字符串方案。
2.4 连续数组
lua 复制代码set_uint16_ex(vtype, addr, values)
set_array(vtype, addr, values)
两者功能相同:values 为从下标 1 开始、没有空洞的整数表,长度为 1~2000,每项表示一个 16 位字,按连续地址写入。每项请使用 0~65535 的整数;成功无返回值。它们不是 8 位字节数组接口,没有对应的 get_array 原生接口。
local LW = 1
function on_init()
set_uint16_ex(LW, 0x1014, {9, 0, 9})
-- LW1014=9,LW1015=0,LW1016=9。
set_array(LW, 0x1300, {0x1234, 0x5678})
for i = 0, 1 do
print(get_uint16(LW, 0x1300 + i))
end
end
字表提交原始 16 位字,不执行单值数值接口的 16 位整序交换;超范围表项当前会截断为 UINT16,应在调用前检查。Modbus 线圈字表每项覆盖 16 点,{1, 0, 1} 表示 48 点,不是三个单点;具体保尾及分帧规则见专门示例。
数组跨度不能越过地址末端,PLC 后端也可能因设备区、只读范围或缓存容量拒绝。需要发送原始字节表时使用 uart_send,不要把它与寄存器字数组混用。
2.5 从站与预读
lua 复制代码select_slave(slave_index)
start_read(slave_index, vtype, addr, count)
slave_index 是工程配置中的从站索引,从 0 开始,不是设备通信站号。默认选择索引 0;例如第二个配置从站的站号是 7,仍应使用 select_slave(1)。索引必须为已配置的 0~7,FX 只支持 0;非法选择会抛错误并保留此前选择。选择影响后续数值、位、字符串及数组读写,LW/RW 仍使用本地数据区。
start_read 登记持续轮询范围,成功无返回值,不同步返回数据。通常在脚本顶层或 on_init 登记一次,换页和通信重配会恢复登记,不需要每次 on_run 重复登记。
count 为整数 1~65535,且 addr + count <= 65536;最多保留 16 个不同的“从站索引 + 类型 + 起始地址”范围,同一起点再次调用会修改数量。Modbus 字区以 16 位字计数;Modbus 类型 3/4 延续寄存器桥接语义,每个登记字覆盖最多 16 个位。LW/RW 不登记外部轮询,也不消耗范围槽位。PLC 仍受工程地址范围、设备原生元素宽度和驱动容量限制。
local HOLDING = 6
function on_init()
select_slave(0)
start_read(0, HOLDING, 100, 10)
set_run_cycle(100)
end
function on_run(screen)
local value = get_uint16(HOLDING, 100)
print("page", screen, "cached value", value)
end
没有注册名为 poll_register 或 stop_read 的 Lua 接口。脚本关闭或重载会清理旧脚本的预读范围,控件自身的轮询独立保留。首次预读登记成功不代表已经收到从站应答。
2.6 变量更新
脚本可定义 on_update(slave, vtype, addr)。运行库在可读缓存更新后调用;slave 是从站索引,本地 LW/RW 为 0,addr 是实际更新的地址。使用相应 get_* 读取最新值:
local LW = 1
function on_update(slave, vtype, addr)
if vtype == LW and addr == 0x1014 then
local value = get_uint16(LW, addr)
print("temperature", value)
end
end
相同值通常不重复通知,外部源首次有效零值也会通知;同一地址分发前的多次变化可能合并为一次。多字值可能按组成它的多个寄存器通知。回调中同步写变量不会递归触发新的 on_update,回调返回值不能撤销写入。
2.7 自动上传
lua 复制代码set_notify(enable)
enable 必须是整数 0 或 1,成功无返回值。默认开启;set_notify(0) 关闭 DCBUS/DGUS 自动上传,set_notify(1) 恢复后续自动上传。它作用于 Lua set_*、控件通知及系统复制触发的自动上传,仍需在工程中开启“自动上传”。
local LW = 1
function update_demo_value()
set_notify(0)
set_uint16(LW, 0x2100, 123)
set_notify(1)
end
关闭时仍更新本地值、控件显示及相应 on_update;恢复后不会补发关闭期间的数据。脚本关闭、重载或加载失败时,运行库会在脚本资源和终结器清理完成后恢复默认开启。
此接口不是整个串口的停发开关。 它不停止协议应答、PLC 主站轮询、主动 uart_send、独立第二串口或串口下载。Modbus、FX、DVP、XC、XD 等外部寄存器的 set_* 仍进入主站写队列;要暂停这类发送,应停止或限制脚本中的写操作。暂停定时写入见5.4 定时器。
3. 应用
3.1 读取 XD 寄存器
下面是信捷 XD 的完整示例,选择第一个配置从站,每 200 ms 读取 D100 和 M0,仅在值变化时打印。工程已有 on_init/on_run 时,把内容合并到原回调,不要重复定义。
--信捷XD示例;工程通信协议须选择信捷XD
VT_LW = 1
VT_RW = 2
VT_M = 3
VT_D = 17
LW = VT_LW
RW = VT_RW
local d100 = nil
local m0 = nil
function on_init()
select_slave(0) --第一个配置从站,不是PLC站号0
set_run_cycle(200)
start_read(0, VT_D, 100, 1) --D100,一个16位字
start_read(0, VT_M, 0, 1) --M0,一个位元件
--按业务需要放入已有回调;以下写入默认不执行
-- set_uint16(VT_D, 100, 123)
-- set_bit(VT_M, 0, 1)
end
function on_run(screen)
select_slave(0)
--首次尚无有效数据时可能读取失败,保留nil,不当作0
local ok_d, value_d = pcall(get_uint16, VT_D, 100)
local ok_m, value_m = pcall(get_bit, VT_M, 0)
if ok_d and value_d ~= d100 then
d100 = value_d
print("D100 =", d100)
end
if ok_m and value_m ~= m0 then
m0 = value_m
print("M0 =", m0)
end
end
换成 XC 时,上述示例的 VT_M 改为 5、VT_D 改为 9,并在工程中选择信捷 XC。其他协议使用各自的定义和原生元素规则,不能照搬本例的位区预读计数。
get_* 读取 HMI 缓存,不同步等待 PLC,应答尚未到达时可用 pcall 捕获读取错误。通信中断后缓存可能仍保留旧值;set_* 正常返回或触发 on_update 表示本地可读值已提交,不代表 PLC 已确认执行,也不能据此判断在线。
4. 常见问题
| 现象 | 检查方法 |
|---|---|
使用未定义的 LW 常量 |
在脚本中先写 local LW = 1,或者直接传整数 1 |
| 给整数函数传小数、布尔值或字符串 | 使用对应整数值;浮点数使用 set_float 或 set_double |
| 忽略 32/64 位的连续地址 | 为数据预留 2/4 个字,避免覆盖旁边的变量 |
| 把从站索引当站号,或把读缓存当同步读 | 按工程配置选择索引,使用持续预读与更新回调 |
为 get_string 传长度、为 set_uint16 多传通知参数 |
签名不支持这些参数 |
| 将成功无返回值误判为失败 | 需要捕获错误时使用下面写法 |
捕获写入错误
lua 复制代码local ok, err = pcall(set_uint16, 1, 0x1014, 9)
if not ok then
print("write failed", err)
end