Skip to content

plc — PLC 数据交互 ​

模块名:plc

Lua 与梯形图之间的桥梁,也是设备参数的总入口。它负责读写全部软元件(X/Y/M/S/T/C/D/R)、配置三个网口、访问远程设备,以及 RTC、持久化、编解码等系统功能。plc 是必加载模块,不需要在脚本里做任何声明。

以下三条通用约定适用于全章:

  • 软元件:plc.名称(地址) 是读,plc.名称(地址, 值) 是写,写入后返回写进去的值。
  • 网络参数:plc.名称() 是读,plc.名称(值) 是写。
  • ds / dsd / dsf / ms 的地址是偏移量,不是绝对编号。plc.ds(13) 访问的是 D8013,plc.ms(0) 访问的是 M8000。

Lua 寄存器访问:各函数占用几个 D,以及 ds 系列的 D8000 偏移换算

函数总览 ​

位软元件 ​

函数作用
plc.x(integer, ...)输入继电器 X(0-255)
plc.y(integer, ...)输出继电器 Y(0-255)
plc.m(integer, ...)内部继电器 M(0-7679)
plc.ms(integer, ...)特殊继电器 M8000 段(偏移 0-511)
plc.s(integer, ...)状态继电器 S(0-4095)
plc.ts(integer, ...)定时器触点(0-511)
plc.cs(integer, ...)计数器触点(0-255)

字软元件 ​

函数作用
plc.d(integer, integer, ...)D 寄存器 16 位整数(0-7999)
plc.dd(address)D 寄存器 32 位整数(占 2 个 D)
plc.df(integer, ...)D 寄存器单精度浮点(占 2 个 D)
plc.ds(integer, ...)特殊寄存器 D8000 段 16 位(偏移 0-511)
plc.dsd(integer, ...)特殊寄存器 32 位(偏移 0-510)
plc.dsf(integer, ...)特殊寄存器浮点(偏移 0-510)
plc.tn(integer, ...)定时器当前值(0-511)
plc.cn(integer, ...)计数器当前值(C0-C199 16 位,C200-C255 32 位)
plc.r(address)R 文件寄存器 16 位(0-32767)
plc.rd(address)R 寄存器 32 位整数(占 2 个 R)
plc.rf(address)R 寄存器单精度浮点(占 2 个 R)

字符串 ​

函数作用
plc.dstr(integer, ...)D 寄存器字符串(最多 32 个 D,64 字符)
plc.rstr(address)R 寄存器字符串(最多 32 个 R,64 字符)

网络配置 ​

函数作用
plc.sta_dhcp(integer, ...) / plc.eth_dhcp(integer, ...)STA / 以太网 DHCP 开关
plc.sta_ip(integer, ...) / plc.ap_ip(integer, ...) / plc.eth_ip(integer, ...)各网口 IP
plc.sta_mask(integer, ...) / plc.ap_mask(integer, ...) / plc.eth_mask(integer, ...)子网掩码
plc.sta_gateway(integer, ...) / plc.ap_gateway(integer, ...) / plc.eth_gateway(integer, ...)网关
plc.sta_ssid(string, ...) / plc.sta_password(string, ...)要连的 WiFi 名 / 密码
plc.ap_ssid(string, ...) / plc.ap_password(string, ...)本机热点的名 / 密码

远程设备 ​

函数作用
plc.get(string, integer, integer, integer)通过 UDP 向远程设备请求 D 寄存器
plc.put(string, integer, integer, integer)通过 UDP 把本地 D 寄存器写到远程设备

设备与系统 ​

函数作用
plc.plc_name读取或设置设备名
plc.led(mode)控制状态指示灯
plc.rtc_set(integer, integer, integer, integer, integer, integer, ...)设置 RTC 时钟
plc.sta_autochnWiFi 射频自动校准开关
plc.lua_password(password_string)设置 Lua 脚本访问密码
plc.plc_password(password_string)设置梯形图保护密码

持久化与编解码 ​

函数作用
plc.kv_set写掉电不丢失的键值对
plc.kv_get读键值对
plc.base64_encode(string)Base64 编码
plc.base64_decode(encoded_string)Base64 解码
plc.aes_encode(string)AES 加密(设备内置密钥)
plc.aes_decode(encrypted_string)AES 解密
plc.bite(data, bit_position)读写一个整数的指定位
plc.AI类型转换与命令式功能入口

云平台 ​

  • plc.cloud_status —— 本机与云平台的连接状态(本页下方有完整说明)
  • plc.cloud_bind / cloud_reg / cloud_publish / cloud_subscribe / cloud_compute 也属于本模块,见 云平台通信。

短信(只在部分机型上有) ​

函数作用
plc.sms_recv()注册"收到短信"回调
plc.sms_send(phone_number, message)发一条短信

这两个函数不是全机型可用,调用前务必先判空,见各自条目。


位软元件读写 ​

7 个位软元件函数共用同一套约定:plc.名称(addr) 读回 0/1,plc.名称(addr, value) 写入并返回写后的 0/1。value 接受 boolean(true/false)或整数(非 0 为 ON)。地址超范围时读返回 0、写被忽略。

lua
plc.x(addr, [value]) --> 0 | 1
plc.y(addr, [value]) --> 0 | 1
plc.m(addr, [value]) --> 0 | 1
plc.ms(addr, [value]) --> 0 | 1
plc.s(addr, [value]) --> 0 | 1
plc.ts(addr, [value]) --> 0 | 1
plc.cs(addr, [value]) --> 0 | 1
函数元件地址范围说明
plc.x输入继电器 X0-255物理输入点,可写但通常只读
plc.y输出继电器 Y0-255
plc.m内部继电器 M0-7679M8000 以上用 plc.ms
plc.ms特殊继电器偏移 0-511plc.ms(0) = M8000,部分位系统写保护
plc.s状态继电器 S0-4095
plc.ts定时器触点0-511定时器溢出线圈状态
plc.cs计数器触点0-255

示例

lua
plc.y(0, 1)             -- Y0 置 ON
local run = plc.m(10)   -- 读 M10
if plc.ts(5) == 1 then  -- T5 到时
    plc.y(0, 0)
end

说明

  • 地址按十进制解析,plc.x(10) 就是第 10 号输入点,不做八进制换算。(八进制换算只发生在 cloud_bind 里 "X10" 这类字符串地址上。)

字软元件读写 ​

字软元件同样是 1 参读、2 参写,写入返回写进去的值。32 位类型占用两个连续寄存器,规划地址时应避免相邻数据重叠。

lua
plc.d(addr, [value])   --> integer     -- 16 位有符号
plc.dd(addr, [value])  --> integer     -- 32 位有符号,占 D(addr)、D(addr+1)
plc.df(addr, [value])  --> number      -- 单精度浮点,占 2 个 D
plc.ds(addr, [value])  --> integer     -- D8000 偏移,16 位
plc.dsd(addr, [value]) --> integer     -- D8000 偏移,32 位
plc.dsf(addr, [value]) --> number      -- D8000 偏移,浮点
plc.tn(addr, [value])  --> integer     -- 定时器当前值
plc.cn(addr, [value])  --> integer     -- 计数器当前值
plc.r(addr, [value])   --> integer     -- R 文件寄存器 16 位
plc.rd(addr, [value])  --> integer     -- R 32 位,占 2 个 R
plc.rf(addr, [value])  --> number      -- R 浮点,占 2 个 R
函数数据类型占用地址范围
plc.d16 位整数1 个 D0-7999
plc.dd32 位整数2 个 D0-7998
plc.df单精度浮点2 个 D0-7998
plc.ds16 位整数1 个偏移 0-511(D8000-D8511)
plc.dsd32 位整数2 个偏移 0-510
plc.dsf单精度浮点2 个偏移 0-510
plc.tn16 位整数1 个0-511
plc.cn16/32 位整数—C0-C199 按 16 位,C200-C255 按 32 位
plc.r16 位整数1 个 R0-32767
plc.rd32 位整数2 个 R0-32766
plc.rf单精度浮点2 个 R0-32766

示例

lua
plc.d(100, 1234)          -- 写 D100
local temp = plc.df(200)  -- 读 D200-D201 的浮点
plc.dd(300, 100000)       -- 写 32 位整数到 D300-D301
local c = plc.cn(200)     -- 读 C200(32 位计数器)
local special = plc.ds(13)-- 读 D8013

字符串读写 ​

把字符串按每个寄存器 2 字节的方式存入 D 或 R 区。

lua
plc.dstr(addr, [str]) --> string
plc.rstr(addr, [str]) --> string

参数

#参数类型必填默认值说明
1addrinteger是—起始寄存器编号
2strstring否—省略为读取;提供为写入。最多 32 个寄存器(64 字符)

返回值

类型说明
string读取或写入的字符串

示例

lua
plc.dstr(300, "Hello")     -- 写字符串到 D300 起
local name = plc.dstr(300) -- 读回

说明

  • 每个寄存器存 2 个字符,遇到值为 0 的高字节视为字符串结束。

网络配置 ​

三个网口(STA=WiFi 客户端、AP=WiFi 热点、ETH=以太网)的参数读写。0 参数为读、1 参数为写,写入返回新值。IP/掩码/网关既接受点分字符串也接受整数,读出为点分字符串;DHCP 读出为 0/1。

lua
plc.sta_dhcp([v])  plc.eth_dhcp([v])                      --> 0 | 1
plc.sta_ip([v])    plc.ap_ip([v])    plc.eth_ip([v])      --> string
plc.sta_mask([v])  plc.ap_mask([v])  plc.eth_mask([v])    --> string
plc.sta_gateway([v]) plc.ap_gateway([v]) plc.eth_gateway([v]) --> string
plc.sta_ssid([v])  plc.sta_password([v])                 --> string
plc.ap_ssid([v])   plc.ap_password([v])                  --> string

参数

下面 15 个函数共用同一套参数约定:不传参数是读,传 1 个参数是写。

#参数类型必填默认值说明
1值string | integer | boolean否—DHCP 开关传整数或布尔;IP / 掩码 / 网关传点分字符串;SSID / 密码传字符串。省略即为读取

返回值

类型说明
stringIP / 掩码 / 网关 / SSID / 密码:读出当前保存的值,写入后返回写入的值
integerDHCP 开关:0 关闭、1 开启

示例

lua
plc.eth_dhcp(0)
plc.eth_ip("192.168.1.100")
plc.eth_mask("255.255.255.0")
plc.eth_gateway("192.168.1.1")
print("以太网 IP:", plc.eth_ip())

说明 —— 下面这几条对全部 15 个函数都成立,各函数条目里只写差异

  • 写入只是把值存进参数区(掉电不丢),不会立刻改变正在运行的网络。 生效时机每条函数各自写明,共同点是:改完要重启(或重新联网)才看得出结果,不要在运行中反复改。
  • 软 PLC 模拟器里这 15 个函数是空实现:不报错,但读回来是 nil、写入没有任何效果。它们只在设备上有意义。脚本要兼顾模拟器时先判空:local ip = plc.eth_ip(); if ip then ... end。
  • IP / 掩码 / 网关一律传点分字符串。 整数形式按设备内部的字节顺序解释(最低位那个字节才是第一段),和常见的 0xC0A8xxxx 写法正好相反 —— 传进去会得到一个首尾颠倒的地址,且不会报错。
  • 地址写错了不报错,会被存成一个奇怪的地址。 解析不出来的字符串("abc"、"300.1.1.1"、"192.168.1.")会存成 255.255.255.255;少写一段的简写会被自动补全("192.168.1" 被当成 192.168.0.1)。写完立刻读一次,读回的不是您填的那个值就说明没被接受。
  • 传既非数字也非字符串的参数(nil、true、table)时行为未定义:IP 类会把一个不确定的值写进参数区,DHCP 类一律按"开启"处理 —— 所以 plc.sta_dhcp("0") 是打开 DHCP 而不是关闭。
  • 一次调用传两个及以上参数时什么都不写(也不报错),别把 plc.sta_ip(a, b) 当成批量设置。
  • SSID / 密码最长 31 个字符。 超长的写入不报错、也确实存进去了,但之后无论是函数读取还是设备开机取用,都会退回出厂默认值 —— 表现为"改了没生效"。写完立刻读一次即可判断有没有被接受。

plc.sta_dhcp ​

lua
plc.sta_dhcp()      --> 0 | 1   -- 读
plc.sta_dhcp(1)     --> 0 | 1   -- 写:1 开启,0 关闭

WiFi 客户端要不要用 DHCP 自动取地址。

参数

#参数类型必填默认值说明
1enableinteger | boolean否—省略为读。0 / false 关闭,非 0 / true 开启;其它类型一律按开启处理

返回值

类型说明
integer0 固定 IP,1 DHCP。写入时返回写入后的值

说明

  • 出厂默认是开启。
  • 只有关闭后,plc.sta_ip / plc.sta_mask / plc.sta_gateway 保存的值才会被真正配到网卡上;开启时这三个函数读到的是路由器下发的地址。
  • 生效时机:设备连上路由器的那一刻读取本开关,改完要重启或让 WiFi 重连一次。

实用例程 ​

lua
-- 宁夏设备监控脚本 - 基于nx20250901.md
-- 功能:采集纺织机数据并通过MQTT发送

--配置plc wifi
plc.ap_ssid("")
plc.sta_ssid("<设备ID或凭据>")--wifi账号
plc.sta_password("<设备ID或凭据>!")--wifi密码
plc.sta_dhcp(1)--开启wifi的DHCP
plc.sta_autochn(1)--开启天线校准
local table_result = plc.AI(
{
cmd="set",
data={
		cmdtype="set_cloud",
		name="JDD",
		pass="<设备ID或凭据>",
		enable=true
		}
}
)--设置云服务

把上面的地址、主题、引脚替换成你项目里的即可。

plc.sta_ip ​

lua
plc.sta_ip()              --> string   -- 读
plc.sta_ip("1.1.1.1")     --> string   -- 写

WiFi 客户端的地址。

参数

#参数类型必填默认值说明
1ipstring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的地址。DHCP 开启时这就是路由器实际分配到的地址

示例

lua
-- 固定 IP 部署:关 DHCP,配好三项,再重启
plc.sta_dhcp(0)
plc.sta_ip("192.168.1.100")
plc.sta_mask("255.255.255.0")
plc.sta_gateway("192.168.1.1")

说明

  • DHCP 开着时,设备每次拿到地址都会把它写回参数区,所以您之前设置的固定值会被顶掉。要固定 IP 必须先 plc.sta_dhcp(0)。
  • DHCP 开着但 3 秒内没拿到地址时,设备会回落到这里存的值(存的是 0.0.0.0 时不回落)—— 这算是断网时的兜底,不是 bug。
  • 生效时机:下一次连上路由器时下发,改完重启确认。

plc.sta_mask ​

lua
plc.sta_mask()              --> string   -- 读
plc.sta_mask("255.255.255.0") --> string -- 写

WiFi 客户端的子网掩码。

参数

#参数类型必填默认值说明
1maskstring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的掩码

说明

  • 与 plc.sta_ip 同一套规则:DHCP 开启时会被路由器下发的值覆盖,只在 plc.sta_dhcp(0) 时生效。

plc.sta_gateway ​

lua
plc.sta_gateway()             --> string   -- 读
plc.sta_gateway("192.168.1.1") --> string  -- 写

WiFi 客户端的网关。

参数

#参数类型必填默认值说明
1gatewaystring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的网关

说明

  • 与 plc.sta_ip 同一套规则:DHCP 开启时会被路由器下发的值覆盖。
  • 网关写错的表现是"能连上路由器、同网段之间 ping 得通,但上不了云、连云一直失败",因为跨网段的数据包没有去处。

plc.eth_dhcp ​

lua
plc.eth_dhcp()      --> 0 | 1   -- 读
plc.eth_dhcp(1)     --> 0 | 1   -- 写:1 开启,0 关闭

以太网口要不要用 DHCP 自动取地址。

参数

#参数类型必填默认值说明
1enableinteger | boolean否—省略为读。0 / false 关闭,非 0 / true 开启;其它类型一律按开启处理

返回值

类型说明
integer0 固定 IP,1 DHCP。写入时返回写入后的值

说明

  • 出厂默认是关闭(用固定 IP),和 WiFi 那边相反。
  • 生效时机:网线链路重新起来(拔插网线)或重启时读取本开关,写入本身不会让网口重新配址。

plc.eth_ip ​

lua
plc.eth_ip()              --> string   -- 读
plc.eth_ip("1.1.1.1")     --> string   -- 写

以太网口的地址。

参数

#参数类型必填默认值说明
1ipstring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的地址。DHCP 开启时这就是路由器实际分配到的地址

示例

lua
plc.eth_dhcp(0)
plc.eth_ip("192.168.1.100")
plc.eth_mask("255.255.255.0")
plc.eth_gateway("192.168.1.1")

说明

  • plc.eth_ip() 读回 0.0.0.0 有两种可能:这台机型没有以太网口(值恒为 0.0.0.0,写进去也只是存在参数区、永远不会生效),或者这个值确实被写成了 0。先看机型有没有网口再判断。
  • 与 plc.sta_ip 同样是「DHCP 拿到地址就回写参数区」,要固定 IP 先 plc.eth_dhcp(0)。
  • DHCP 开着但 3 秒内没拿到地址时,回落到这里存的值。
  • 生效时机:网线拔插一次或重启。

实用例程 ​

lua
				signalFailSecond = Unsigned(plc.rd(10),32), --通讯故障时长
				data =
					{
						{
							identity = "<设备ID或凭据>",                   --参数标识
							name = "<名称>",                        --名称
							value = Unsigned(plc.rd(0),32),    --对应值
							unit = "<名称>",               					  --单位
							dataType = "0"             					  --数据类型:0-数字,1-字符串
						},

					}
			}
			send_data = json.encode(torigin)        --json格式转
			rev_data=http.post(twinhu,send_data,plc.eth_ip())  --发送数据
			print(rev_data)
		end
	
		if  plc.m(2)==1 then		--报警数据发送
			plc.m(2,0)
			plc.m(1,0)					    
			Bnumber = Bnumber+1
			plc.rd(105,Bnumber)	
			local torigin_A =  --建JSON表
			{
				versionNo = 1.0,				    --版本号
				boxId = plc.dsd(37),  	        --box号
				dssn = Bnumber,  				--发送ID序号

把上面的地址、主题、引脚替换成你项目里的即可。

plc.eth_mask ​

lua
plc.eth_mask()              --> string   -- 读
plc.eth_mask("255.255.255.0") --> string -- 写

以太网口的子网掩码。

参数

#参数类型必填默认值说明
1maskstring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的掩码

说明

  • 读写与生效时机同 plc.eth_ip(含"没有网口的机型读回 0.0.0.0"这一条)。

plc.eth_gateway ​

lua
plc.eth_gateway()             --> string   -- 读
plc.eth_gateway("192.168.1.1") --> string  -- 写

以太网口的网关。

参数

#参数类型必填默认值说明
1gatewaystring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的网关

说明


plc.ap_ip ​

lua
plc.ap_ip()              --> string   -- 读
plc.ap_ip("1.1.1.1")     --> string   -- 写

本机热点自己的地址,也就是您的手机 / 上位机连上这个热点后访问设备用的地址。

参数

#参数类型必填默认值说明
1ipstring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的热点地址;出厂默认 192.168.150.1

说明

  • 这是热点自己那一侧的地址,改它会改变访问设备的入口,改完连上热点的电脑也要重新拿地址。
  • 不受 DHCP 开关影响:plc.ap_ip / plc.ap_mask / plc.ap_gateway 三项直接配到热点上,连进来的设备由设备的 DHCP 服务分配地址。
  • 生效时机:重启(WiFi 初始化时一次性配好)。

plc.ap_mask ​

lua
plc.ap_mask()              --> string   -- 读
plc.ap_mask("255.255.255.0") --> string -- 写

本机热点侧的子网掩码。

参数

#参数类型必填默认值说明
1maskstring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的掩码

说明

  • 读写与生效时机同 plc.ap_ip。改掩码要和 plc.ap_ip、plc.ap_gateway 一起改到同一个网段,否则连上热点也访问不到设备。

plc.ap_gateway ​

lua
plc.ap_gateway()             --> string   -- 读
plc.ap_gateway("1.1.1.1")    --> string   -- 写

本机热点侧的网关。

参数

#参数类型必填默认值说明
1gatewaystring否—省略为读,填了是写;点分十进制字符串

返回值

类型说明
string当前保存的网关;出厂默认与热点地址相同(192.168.150.1)

说明

  • 读写与生效时机同 plc.ap_ip。热点是给本地直连用的,一般不需要改这一项。

plc.ap_ssid ​

lua
plc.ap_ssid()          --> string   -- 读
plc.ap_ssid("LP-1")    --> string   -- 写

本机发出的热点名。

参数

#参数类型必填默认值说明
1ssidstring否—省略为读,填了是写;最长 31 个字符

返回值

类型说明
string当前保存的热点名

说明

  • 出厂热点名因机型而异(有 lp,也有带设备后缀的形式),以实际搜到的为准。
  • 置空后重启:部分机型会自动生成一个 lpplc-XXXXXX 的名字并写回,另一些会保持为空;两个 WiFi 名都为空时 WiFi 可能整体关闭。要关热点,建议改成一个好认的名字,别用空串。
  • 生效时机:重启。

实用例程 ​

lua
-- 宁夏设备监控脚本 - 基于nx20250901.md
-- 功能:采集纺织机数据并通过MQTT发送

--配置plc wifi
plc.ap_ssid("")
plc.sta_ssid("<设备ID或凭据>")--wifi账号
plc.sta_password("<设备ID或凭据>!")--wifi密码
plc.sta_dhcp(1)--开启wifi的DHCP
plc.sta_autochn(1)--开启天线校准
local table_result = plc.AI(
{
cmd="set",
data={
		cmdtype="set_cloud",
		name="JDD",
		pass="<设备ID或凭据>",
		enable=true
		}

把上面的地址、主题、引脚替换成你项目里的即可。

plc.ap_password ​

lua
plc.ap_password()           --> string   -- 读
plc.ap_password("ab123456") --> string   -- 写

本机热点的密码。

参数

#参数类型必填默认值说明
1passwordstring否—省略为读,填了是写;最长 31 个字符

返回值

类型说明
string当前保存的热点密码;热点从未设置过时读到出厂默认密码

说明

  • 密码少于 8 个字符(包括置空)会让热点直接变成不加密的开放网络,任何设备都能连进来,且函数不会报错、返回值看起来正常。这是最容易造成现场安全事故的一条,改完请确认长度 ≥ 8。
  • 生效时机:重启。

plc.sta_ssid ​

lua
plc.sta_ssid()        --> string   -- 读
plc.sta_ssid("车间WiFi") --> string -- 写

设备要连接的 WiFi 名字。

参数

#参数类型必填默认值说明
1ssidstring否—省略为读,填了是写;最长 31 个字符

返回值

类型说明
string当前保存的 WiFi 名;没配置过时为空串 ""

说明

  • 空串 = 不连接任何路由器,设备不会去连 WiFi。想改密码别忘了名字也要一致(路由器改了 WiFi 名,设备就再也连不上,表现是设备离线)。
  • 超长(>31 字符)写入会被接受,但读回和开机实际用的值都会退回默认(空串),等于设备变成不连 WiFi。
  • 生效时机:重启。

实用例程 ​

lua
-- 宁夏设备监控脚本 - 基于nx20250901.md
-- 功能:采集纺织机数据并通过MQTT发送

--配置plc wifi
plc.ap_ssid("")
plc.sta_ssid("<设备ID或凭据>")--wifi账号
plc.sta_password("<设备ID或凭据>!")--wifi密码
plc.sta_dhcp(1)--开启wifi的DHCP
plc.sta_autochn(1)--开启天线校准
local table_result = plc.AI(
{
cmd="set",
data={
		cmdtype="set_cloud",
		name="JDD",
		pass="<设备ID或凭据>",
		enable=true
		}
}

把上面的地址、主题、引脚替换成你项目里的即可。

plc.sta_password ​

lua
plc.sta_password()        --> string   -- 读
plc.sta_password("pwd123456") --> string -- 写

设备连接 WiFi 用的密码。

参数

#参数类型必填默认值说明
1passwordstring否—省略为读,填了是写;最长 31 个字符

返回值

类型说明
string当前保存的 WiFi 密码;从未设置过时读到出厂默认密码

说明

  • 密码错了不会有任何提示:plc.sta_ssid() 仍返回您写的名字,但设备一直连不上路由器。排查设备离线时,这一项和 plc.sta_ssid 一起核对。
  • 超长(>31 字符)写入不报错,但读回和开机实际用的值都会退回出厂默认密码。
  • 生效时机:重启。

实用例程 ​

lua
-- 宁夏设备监控脚本 - 基于nx20250901.md
-- 功能:采集纺织机数据并通过MQTT发送

--配置plc wifi
plc.ap_ssid("")
plc.sta_ssid("<设备ID或凭据>")--wifi账号
plc.sta_password("<设备ID或凭据>!")--wifi密码
plc.sta_dhcp(1)--开启wifi的DHCP
plc.sta_autochn(1)--开启天线校准
local table_result = plc.AI(
{
cmd="set",
data={
		cmdtype="set_cloud",
		name="JDD",
		pass="<设备ID或凭据>",
		enable=true
		}
}
)--设置云服务

把上面的地址、主题、引脚替换成你项目里的即可。

plc.cloud_status ​

lua
plc.cloud_status()  --> table

读一次本机与云平台的连接状态,用来回答"配了云服务但连不上,到底卡在哪一步"。

参数

无。

返回值

类型说明
table总是返回一个表,四个字段见下表;未连接时也会正常返回,不会返回 nil

返回的表:

字段类型说明
linkedboolean是否已经登录上云平台
wait_statestring已登录为 "established",否则为 "closed"
hb_secinteger距上一次登录/心跳成功过了多少秒;本次上电以来从未连上过时为 -1
link_detailstring当前配置的云地址和端口,形如 地址:端口

示例

lua
local st = plc.cloud_status()
if not st.linked then
    print("未连云,目标是 " .. st.link_detail .. ",上次心跳 " .. st.hb_sec .. " 秒前")
end

说明

  • 只读,不会触发连接、也不会重连。
  • link_detail 是配置值,不代表这个名字解析得出来、这个端口连得通;网络没通时它照样有内容。
  • 判断口径:linked == false 且 hb_sec == -1 → 本次上电从没连上过,查地址 / 账号 / 网络;linked == false 且 hb_sec 在涨 → 连过之后断了,查链路稳定性;linked == true 但云端看不到数据 → 问题在绑定与上报,见 云平台通信。
  • 云服务总开关没开时(设备不发起连接),这里读到的就是未连接状态。

plc.sms_recv ​

lua
plc.sms_recv(function(number, msg) ... end)   --> 无返回值

注册一个"收到短信时"的回调函数。

参数

#参数类型必填默认值说明
1callbackfunction是—收到短信时被调用,收到两个参数:发件号码、短信内容

返回值

无返回值。

说明

  • 这个函数不是全机型可用:目前只有 4G 网关机型(RDA8910 平台那一族,如 LP8910、LP8913)的固件里有实现;LP32xx 系列 ESP32 机型根本没有注册这个函数,plc.sms_recv 取到的是 nil,直接调用会报 attempt to call a nil value。软 PLC 模拟器里它注册了但是空实现,调用不报错、也永远不会有回调。
  • 调用前先判机型,别让整脚本被一个 nil 打断:
lua
if plc.sms_recv then
    plc.sms_recv(function(number, msg)
        print("短信来 " .. number .. " : " .. msg)
    end)
else
    print("本机不支持短信")
end
  • 回调是在设备收到短信时异步执行的,不在您调用的那一行里跑;回调内部报错只会打印出错误信息,不会中断程序。
  • 先在您手上的机型上确认再写进交付脚本:print(plc.sms_recv, plc.sms_send) 两个都打印出 function: 才算支持。

plc.sms_send ​

lua
plc.sms_send(number, msg)   --> 无返回值

发一条短信。函数名就是常规拼写 sms_send(不是 sms_sned,全站没有注册过带那个拼写的函数)。

机型可用性差别很大,交付前务必先在手上的机型上探一次:

平台短信函数可用性
RDA8910 4G 网关机型✅ 有 sms_recv / sms_send
软 PLC 模拟器✅ 有
ESP32 全系机型❌ 没有
STM32F103 网口版 / 750 / H750❌ 没有

在没注册的机型上 plc.sms_send 取到 nil,调用即 attempt to call a nil value。 判据同 sms_recv 节:print(plc.sms_recv, plc.sms_send),两个都打 function: 才可用。

参数

#参数类型必填默认值说明
1numberstring是—接收方手机号码
2msgstring是—短信内容

返回值

无返回值 —— 发没发出去不能从返回值判断。

说明

  • 两个参数都必须是字符串(可转成字符串的值除外),少传或传 nil 会直接抛出 Lua 错误,脚本中断。
  • 机型可用性与 plc.sms_recv 相同:只有 4G 网关机型(RDA8910 平台那一族)有实现;LP32xx 系列 ESP32 机型没有注册这个函数(取到 nil,调用即报错),软 PLC 模拟器里是空实现(调用不报错、也不会真的发出短信)。
  • 因为没有返回值,验证只能靠收端手机看是否收到;现场用报警类短信时建议同时 plc.cloud_publish 一份,别把短信当唯一通路。
lua
if plc.sms_send then
    plc.sms_send("13800138000", "D100 超温报警")
end

plc.get ​

lua
plc.get(ip, remote_addr, local_addr, len)

通过 UDP 向远程 LPPLC 设备发起一次「读 D 寄存器」请求,把远端数据写回本地 D 区。

参数

#参数类型必填默认值说明
1ipstring是—远程设备 IP
2remote_addrinteger是—远程起始 D 编号
3local_addrinteger是—本地起始 D 编号
4leninteger是—D 寄存器数量,最大 255

返回值

无返回值。

说明

  • 异步 UDP 请求:本函数只把读请求发出去,远端回包后才把数据写进本地 local_addr 起始的 D 区,不在调用内同步返回数据。UDP 不保证可靠,丢包时本轮不更新。
  • 目的端口固定 25388,对方 LPPLC 开机常开、无需任何设定即可应答,也不限制同时被几台读写。
  • 只能访问 D 区(D0-D7999);超出范围的地址读回 0。
  • len 在协议里只占 1 个字节,填超过 255 会被静默截断(填 300 实际只传 44 点),固件不报错。
  • 需要网口 / WiFi 已就绪;两台设备要在同一局域网,UDP 单播穿不了 NAT。跨网段跨地区请改用云服务数据交换。
  • 【Linux / RDA8910 版】该平台固件未处理读回应包,plc.get 收不回数据,只有 plc.put 可用。

实用例程 ​

lua
 
timer1=timer.start(12000,function() --读前端水位高度"192.168.1.100" PLC内D100到本PLC D110 寄存器内
		plc.get ("192.168.1.100",100,110,1)
		print("<名称>",plc.d(110))
	end )

--modbus采集的传感器数据(D100-199用于采集和数据处理下游水位D100  (地址为1)上游水位D110 (地址2)   电流值 D120(地址3)   电压值 D130(地址4)   每一个间距10个寄存器位,方便浮点数等转换用;
--上游水位WL_H  单位: m  \  下游水位WL_L   单位: m  \  电流  I (大写) 单位:A  \电压:V  单位:伏   \功率 	P (大写) 单位:KW  \  
--电折水流量为Q_D  单位 :m3/s 
i_1=1 
i_8=1 
i_24=1 

Q_1H =  0   
Q_8H =  0 
Q_24H= 0

把上面的地址、主题、引脚替换成你项目里的即可。

plc.put ​

lua
plc.put(ip, remote_addr, local_addr, len)

通过 UDP 把本地 local_addr 起始的 len 个 D 寄存器写到远程设备。

参数

#参数类型必填默认值说明
1ipstring是—远程设备 IP
2remote_addrinteger是—远程起始 D 编号
3local_addrinteger是—本地起始 D 编号
4leninteger是—D 寄存器数量,最大 255

返回值

无返回值。

说明

  • 与 plc.get 同一套协议(UDP 25388),限制也一样:只能写 D 区、一次最多 255 点、要在同一局域网内。
  • 对方不回执:写成功与否无法从返回值判断,要确认就过一会用 plc.get 把那几个 D 读回来核对。

实用例程 ​

lua
	mqtt.publish(HomeMqtt,"<设备ID或凭据>/Status",json.encode(doorStatus),0,1)--设置为保留消息
	end
end
statusTimer= timer.start(500,refreshDoorStatus)
-----------------状态反馈处理结束--------------------------
x=modbus_tcp_server.start(502,1) --创建一个modbus-tcp服务,用于外部连接过来同步时间等
---------------------开始向主机反馈状态----------------------------------
local SheFang
local Ding
local WarnReset
local Warning
function StatusTo()
	if SheFang~=  plc.d(16) then
		SheFang=plc.d(16)
		plc.put("192.168.1.100",31,16,1)---发送设防状态给后门
		plc.put("192.168.1.100",34,16,1)---发送设防状态给右前门
	end
		
	if Ding~= plc.m(7) then
		Ding = plc.m(7)
		local DingTo=
		{
		IsOn=plc.m(7)==1
		}
	mqtt.publish(HomeMqtt,"Home/Ding/Status",json.encode(DingTo),0,1)--推送叮铛状态
	end
	
	if Warning~= plc.m(18) then --M18是设防状态

把上面的地址、主题、引脚替换成你项目里的即可。

plc.plc_name ​

lua
plc.plc_name()      --> string   -- 读
plc.plc_name(name)  --> string   -- 写

读取或设置设备名。

参数

#参数类型必填默认值说明
1namestring否—省略为读取当前设备名;提供为设置,最长 32 字节

返回值

类型说明
string读取时返回当前设备名;设置成功返回新名,失败返回空串 ""

实用例程 ​

lua
function isYearGreaterOrEqualTo2024()
    local currentYear = tonumber(os.date("%Y", os.time())) -- 提取当前年份
    return currentYear >= 2024
end

-- MQTT配置参数
mqttHost = "192.168.1.100"
mqttPort = 1883
username = "BWJ"
password = "<设备ID或凭据>"
telemetryTopic = "v1/devices/me/telemetry"

DeviceName = "ZJG-TD-01"
plc.plc_name(DeviceName)--设置设备名称




-- 建立MQTT客户端
mqttClient = mqtt.creat(mqttHost, mqttPort, DeviceName, username, password)

-- 注册MQTT连接成功回调函数
mqtt.reg(mqttClient, mqtt.CONNECTED, function()
    print("MQTT Connected <设备ID或凭据>")
end)

-- 注册MQTT网络断开事件

把上面的地址、主题、引脚替换成你项目里的即可。

plc.led ​

lua
plc.led(mode)

控制状态指示灯。

参数

#参数类型必填默认值说明
1modeinteger是—0=熄灭,1=常亮,其它值(含 2)=交回系统自动控制

返回值

无返回值。


plc.rtc_set ​

lua
plc.rtc_set(timestamp)                       --> true | 无
plc.rtc_set(year, mon, day, hour, min, sec)  --> true | 无

设置设备 RTC 时钟。支持传 Unix 时间戳(1 个参数),或年月日时分秒(6 个参数)。

参数

#参数类型必填默认值说明
1timestamp / yearinteger是—1 参模式为 Unix 秒;6 参模式为年
2-6mon day hour min secinteger6 参模式必填—月、日、时、分、秒

返回值

类型说明
boolean成功返回 true;参数个数不是 1 或 6、或时间戳换算失败时不返回值

示例

lua
plc.rtc_set(2026, 8, 14, 10, 30, 0)
-- 或
plc.rtc_set(os.time())

plc.sta_autochn ​

lua
plc.sta_autochn(enable)

开关 WiFi 射频自动校准。

参数

#参数类型必填默认值说明
1enableinteger是—非 0 开启,0 关闭

返回值

无返回值。


实用例程 ​

lua
-- 宁夏设备监控脚本 - 基于nx20250901.md
-- 功能:采集纺织机数据并通过MQTT发送

--配置plc wifi
plc.ap_ssid("")
plc.sta_ssid("<设备ID或凭据>")--wifi账号
plc.sta_password("<设备ID或凭据>!")--wifi密码
plc.sta_dhcp(1)--开启wifi的DHCP
plc.sta_autochn(1)--开启天线校准
local table_result = plc.AI(
{
cmd="set",
data={
		cmdtype="set_cloud",
		name="JDD",
		pass="<设备ID或凭据>",
		enable=true
		}
}
)--设置云服务

function isYearGreaterOrEqualTo2024()
    local currentYear = tonumber(os.date("%Y", os.time())) -- 提取当前年份
    return currentYear >= 2024
end

-- MQTT配置参数
mqttHost = "192.168.1.100"

把上面的地址、主题、引脚替换成你项目里的即可。

plc.lua_password ​

lua
plc.lua_password(password)

设置 Lua 脚本的访问保护密码。

参数

#参数类型必填默认值说明
1passwordstring是—保护密码

返回值

无返回值。


plc.plc_password ​

lua
plc.plc_password(password)

设置梯形图程序的保护密码。

参数

#参数类型必填默认值说明
1passwordstring是—保护密码

返回值

无返回值。


plc.kv_set ​

lua
plc.kv_set(key, value) --> boolean

写入一条掉电不丢失的键值数据。

参数

#参数类型必填默认值说明
1keystring是—键名
2valuestring是—值,按字节串存储,可含 \0

返回值

类型说明
boolean是否写入成功

示例

lua
plc.kv_set("site_id", "workshop-A")

plc.kv_get ​

lua
plc.kv_get(key) --> true                    -- 读到了
plc.kv_get(key) --> false, string, integer  -- 没读到

读取 plc.kv_set 存入的键值数据。单次最多读 256 字节。

参数

#参数类型必填默认值说明
1keystring是—键名

返回值

类型说明
boolean是否读取成功
string, integer仅在失败时追加返回缓冲区内容和长度

说明

  • 当前固件的返回值约定与常规习惯相反:成功时只返回 true,不返回数据本身;只有失败时才会额外返回缓冲区和长度。这是固件侧的实现问题,需要按值持久化时建议改用 fdb 或 ini。

plc.base64_encode ​

lua
plc.base64_encode(str) --> string

Base64 编码。

参数

#参数类型必填默认值说明
1strstring是—原始字节串

返回值

类型说明
stringBase64 字符串

plc.base64_decode ​

lua
plc.base64_decode(str) --> table | nil

Base64 解码,结果放在一个 table 里。

参数

#参数类型必填默认值说明
1strstring是—Base64 字符串

返回值

类型说明
table{ len = 数据长度, str = 解码后的字节串 }
nil内部内存分配失败时返回 nil

示例

lua
local enc = plc.base64_encode("Hello LPPLC")
local dec = plc.base64_decode(enc)
print(dec.len, dec.str)

说明


plc.aes_encode ​

lua
plc.aes_encode(str) --> string

用设备内置密钥做 AES 加密。

参数

#参数类型必填默认值说明
1strstring是—明文

返回值

类型说明
string密文字节串

说明

  • 密钥由设备固化,脚本无法指定,模式固定为 CBC。要自带密钥、自选 ECB / CBC / CTR,用 crypto 模块, 但它只在部分机型上提供(LP3232、LP3288(ESP32-S3 平台),LP8910、LP8911、LP8912、LP8913、LP8915、LP8916、LP8922(4G 平台),LP2300、LP2323(STM32H750 平台),以及上位机的内置软设备与软 PLC 模拟器);没有该模块的机型仍只能用它。详见加密模块。
  • 长度不是 16 的整数倍时,只有前面向下取整到 16 倍数的部分被加密,尾部字节原样保留明文; 不足 16 字节则整段不加密、原样返回。 所以这两个函数不是传输加密,只能对定长或自己补齐到 16 倍数以上的数据做混淆; 变长报文请自行补零/加分隔后再加密,并在对端按同样规则还原。

plc.aes_decode ​

lua
plc.aes_decode(str) --> string

对 plc.aes_encode 的结果解密。

参数

#参数类型必填默认值说明
1strstring是—密文

返回值

类型说明
string明文

plc.bite ​

lua
plc.bite(data, order)         --> 0 | 1      -- 读某一位
plc.bite(data, order, value)  --> integer    -- 写某一位,返回修改后的整数

对一个整数按位读写。常用于把 16 个开关量打包进一个 D 寄存器。

参数

#参数类型必填默认值说明
1datainteger是—被操作的整数,按 32 位处理
2orderinteger是—位序号,从 0 起。>= 32 时读返回 0、写不改变
3valueboolean | number否—传入即为写位:真置 1、假置 0

返回值

类型说明
integer读时返回该位的 0/1;写时返回修改后的整数

示例

lua
-- 把 D100 的第 3 位置 1
plc.d(100, plc.bite(plc.d(100), 3, 1))

-- 判断 D100 的第 5 位
if plc.bite(plc.d(100), 5) == 1 then print("bit5 ON") end

plc.AI ​

lua
plc.AI(value)  --> converted        -- 类型转换
plc.AI(cmd_table) --> result_table  -- 命令模式

一个多用途入口。传入普通值时做智能类型转换;传入含 cmd 字段的 table 时执行内置命令。

参数

#参数类型必填默认值说明
1valueany是—见下面两种模式

类型转换模式

输入返回
string能解析成整数 → integer;能解析成浮点 → number;"true"/"false" → boolean;否则原样返回 string
number转成字符串(浮点会去掉尾部多余的 0)
boolean"true" / "false"
nil"nil"
不含 cmd 的 table"[table]"
function / userdata / thread"[function]" / "[userdata]" / "[thread]"

命令模式

传入 { cmd = "命令名", data = 载荷 },返回 { cmd = 命令名, errno = 错误码, errmsg = 错误信息, data = 结果 },errno 为 0 表示成功,未知命令返回 -1。

ESP32 固件支持的命令:

cmd作用
"echo"原样回显 data,用于连通性自检
"ShowMe"返回 WiFi 相关信息
"set"设置设备参数
"config"批量部署配置,用于一次性下发整机参数

示例

lua
print(plc.AI("123"))        -- 123(integer)
print(plc.AI("3.14"))       -- 3.14(number)
print(plc.AI(true))         -- "true"

local r = plc.AI({ cmd = "echo", data = "ping" })
print(r.errno, r.data)      -- 0  ping

说明

  • "line convert"(插值转换)和 "kalman filter"(卡尔曼滤波)两个命令只在 Windows / Linux 上位机版本里编译,ESP32 固件不含,调用会返回 errno = -1。

实用例程 ​

lua
-- 宁夏设备监控脚本 - 基于nx20250901.md
-- 功能:采集纺织机数据并通过MQTT发送

--配置plc wifi
plc.ap_ssid("")
plc.sta_ssid("<设备ID或凭据>")--wifi账号
plc.sta_password("<设备ID或凭据>!")--wifi密码
plc.sta_dhcp(1)--开启wifi的DHCP
plc.sta_autochn(1)--开启天线校准
local table_result = plc.AI(
{
cmd="set",
data={
		cmdtype="set_cloud",
		name="JDD",
		pass="<设备ID或凭据>",
		enable=true
		}
}
)--设置云服务

function isYearGreaterOrEqualTo2024()
    local currentYear = tonumber(os.date("%Y", os.time())) -- 提取当前年份
    return currentYear >= 2024
end

-- MQTT配置参数
mqttHost = "192.168.1.100"
mqttPort = 1883

把上面的地址、主题、引脚替换成你项目里的即可。

例程 ​

每个例程都是可直接下载运行的完整脚本:注册完定时器后脚本就结束,固件自动进入消息泵。 API 只用本章已文档化的函数;统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。

例程 1:位元件读写 —— 用 X/Y 和 M 做梯形图与 Lua 的握手 ​

适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 | 依赖模块:plc timer | 难度:★☆☆

场景:梯形图算得了高速、确定性的逻辑,Lua 擅长通信和字符串。两侧分工时要有一套约定好的信号位:这里 X0 让 Lua 干活、Lua 干完置 M10、梯形图收到 M10 就去清 X0 侧的锁存。这样谁也不会抢同一个点。

完整代码(可直接下载运行):

lua
-- 握手约定:X0 = 请求,M10 = Lua 已处理;梯形图看到 M10 就复位自己的请求条件
local last_req = 0

timer.start(200, function()
    local req = plc.x(0)                     -- 读物理输入 X0(0/1)
    if req == 1 and last_req == 0 then       -- 上升沿
        plc.d(300, plc.d(300) + 1)           -- 计一次数到 D300
        plc.y(0, 1)                          -- 点亮输出 Y0
        plc.m(10, 1)                         -- 通知梯形图:已处理
        print("已处理第", plc.d(300), "次请求")
    elseif req == 0 and last_req == 1 then
        plc.y(0, 0)
        plc.m(10, 0)                         -- 请求撤销,握手位跟着复位
    end
    last_req = req
end)

要点:

  • 七个位元件(X/Y/M/MS/S/TS/CS)共用同一套约定:1 参读、2 参写,写入返回写后的 0/1。
  • value 可以传 true/false 也可以传整数,非 0 即 ON。
  • 地址是十进制:plc.x(10) 是第 10 号输入点,不做八进制换算。
  • plc.ts(5) / plc.cs(3) 能直接读定时器/计数器触点,不用去翻他们的当前值寄存器。
  • 地址超范围不报错:读返回 0、写被静默忽略 —— 所以「写了没反应」先查地址范围(见注意事项)。

验证方法:

  1. 下载运行后让 X0 接通一下再断开:日志打印 已处理第 1 次请求,Y0 短暂吸合,D300 变为 1。
  2. 上位机「在线监视」里看 M10 随请求一起置 ON / 复位(握手位真的在动)。
  3. 再通断几次 X0:D300 逐次 +1,不多不少(上升沿只算一次)。
  4. 故意用超范围地址(比如 plc.m(99999, 1)):不报错但也不生效 —— 记住这个"静默失败"手感。

注意事项:

  • X0 抖动会被重复计数:程序里必须像上面那样自己存"上一拍状态"做上升沿。
  • 梯形图和 Lua 写同一个 Y?约定同一时刻只有一侧写,另一侧只读,否则谁也说不清最后那个值是谁给的。
  • 位元件读取返回 0/1 整数,判断用 == 1;if plc.m(10) then 在未置位时也是真值。

例程 2:16 位 / 32 位 / 浮点 / 字符串 —— 四种字数据一次讲清 ​

适用:同上 | 依赖模块:plc | 难度:★★☆

场景:现场计数器值超过 32767、温度是 25.3 这种小数、要给下位屏送一串文字 —— 对应的分别是 dd(32 位整数)、df(浮点)、dstr(字符串)。这一段把四种写法的落点和地址占用一次性摆清楚,照着抄就不会错。

完整代码(可直接下载运行):

lua
-- 地址规划:D100=温度(浮点占 D100-D101),D110=产量(32位占 D110-D111),
--           D120=计数(16位),D130=屏标题(字符串占 D130 起)
plc.df(100, 25.3)            -- 浮点写 D100-D101(必须用 df)
plc.dd(110, 1234567)         -- 32 位整数(超过 32767 就不能用 d)
plc.d(120, 32767)            -- 16 位有符号整数,上限 32767
plc.dstr(130, "Line-A")      -- 字符串,每寄存器 2 字符,这里占 3 个 D

timer.start(2000, function()
    local t   = plc.df(100)
    local cnt = plc.dd(110)
    local n   = plc.d(120)
    local s   = plc.dstr(130)
    print(string.format("温度=%.1f 产量=%d 计数=%d 标题=%s", t, cnt, n, s))
end)

要点:

  • 32 位和浮点没有属性式写法:plc.DD110 / plc.DF100 读出来是 nil 而且不报错,一律用 plc.dd() / plc.df()。
  • plc.d(addr, v) 是 16 位有符号(±32767),更大的数必须升级为 plc.dd(占两个连续 D)。
  • 32 位类型占两个寄存器,规划地址时要留出空位:D100 放浮点就别再把别的数据写到 D101。
  • plc.dstr 每个寄存器装 2 个字符,上限 32 个寄存器(64 字符),遇到 0 高字节认为字符串结束。
  • 定时器当前值用 plc.tn(n)、计数器用 plc.cn(n)(C200 以上是 32 位)。

验证方法:

  1. 下载后每 2 秒日志打印一行含四个值的字符串,逐个对得上。
  2. 上位机把 D100 / D101 按浮点格式查看才是 25.3(按整数看是另一串数字,别以为写错了)。
  3. 试着写成 plc.DF100 读一次:日志里温度变成 nil —— 这就是「属性式写法不生效」的真实现象。
  4. 再往 D101 写一个值,回头看 D100 的浮点是否被破坏(直观看到地址重叠的后果)。

注意事项:

  • 用 plc.d 写过 32767 的值会静默溢出;该用 dd 的地方用了 d,读出来是负数。
  • 浮点读到几万这种离谱数字,多半是字序问题(见 com_modbus 的 set_float_abcd)。
  • 地址超范围照样不报错(读 0、写忽略),调试时先确认范围。

例程 3:定时采集 + 超温联锁 + 结果搬到另一台设备 ​

适用:同上(需两台设备同网段)| 依赖模块:plc timer | 难度:★★☆

场景:本机的梯形图/模拟量算出结果后,一方面本地做联锁保护(超温就切断输出),一方面通过 UDP 把整段 D 区同步给同网段的另一台 LPPLC —— 这是多台设备分工干活时最常见的一跳。

完整代码(可直接下载运行):

lua
timer.start(2000, function()
    local temp = plc.df(100)                       -- 读浮点温度
    local run  = plc.m(0)                          -- 读运行允许标志(梯形图给)

    if run == 1 and temp > 80 then
        plc.y(0, 1)                                -- 超温联锁:切断/报警
        print("超温报警", temp)
    else
        plc.y(0, 0)
    end

    -- 把本地 D200-D209 共 10 个寄存器搬到远端 D100 起
    plc.put("192.168.1.50", 100, 200, 10)
end)

要点:

  • plc.put(ip, remote_addr, local_addr, len) 是本机主动发的一次 UDP 写,参数是"远端起始地址、本端起始地址、长度",顺序别写反。
  • plc.get(ip, remote_addr, local_addr, len) 是反向:向远端要数据、写回本地 D 区。
  • 周期任务用 timer.start 驱动,不要写主循环 —— 会和 modbus / MQTT 的回调抢同一条消息队列。
  • plc.put 没有返回值,成功与否只能在对端读回来核对。

验证方法:

  1. 两台设备同网段、对端 IP 改成本地址,下载运行。
  2. 本机写一组已知值进 D200-D209(上位机写入),2 秒内对端 D100-D109 应出现同样的数值。
  3. 本机把 D100 / D101 的浮点值改成 81 → Y0 吸合、日志打印 超温报警;改回常温值 → Y0 断开。
  4. 拔掉网线:plc.put 静默失败、对端数据停在最后一帧 —— 依赖 UDP 的链路要自己在应用层做超时判断和报警。

注意事项:

  • plc.put / plc.get 基于 UDP,丢包不重传也无返回;关键数据要在应用层自己做确认和补发。
  • plc.y(0, 1) 是联锁的目的地,别让梯形图也写同一个 Y —— 会互相拉扯。
  • 搬一整段数据前先确认地址范围与数据宽度(32 位占两个寄存器,别只搬一半)。

注意事项 ​

  • 32 位类型(dd/df/dsd/dsf/rd/rf)占两个连续寄存器,与 16 位数据混用时应注意避免地址重叠。
  • 软元件地址超范围不会报错:读返回 0,写被静默忽略。调试时先确认地址在有效范围内。
  • 网络参数改完只写进参数区,一般要重启(或重新联网)才生效,不要在运行中频繁改;写错也不报错,改完一律读回来核一遍(规则见本章开头「网络配置」一节)。
  • plc.ap_password 填少于 8 个字符会让本机热点变成不加密的开放网络,函数本身不报错。
  • plc.kv_get 的返回值约定有问题(见该函数说明),新代码请优先用 fdb 或 ini 做持久化。

函数速查表 ​

下表列出本库全部函数与方法(含尚未单独成节的),点「说明」可跳转到对应小节。签名按通用记法:括号内按顺序列全参数,方括号里的可以省略(不传走默认值),... 表示还可继续传同类参数;h: 开头的是对象方法,先用库级函数拿回句柄再冒号调用。

方法与签名作用说明
plc.aes_decode(encrypted_string)Lua接口AES解密函数本文开头
plc.aes_encode(string)Lua接口AES加密函数本文开头
plc.AI(…)—本文开头
plc.ap_gateway(integer, ...)—本文开头
plc.ap_ip(integer, ...)—本文开头
plc.ap_mask(integer, ...)—本文开头
plc.ap_password(string, ...)—本文开头
plc.ap_ssid(string, ...)—本文开头
plc.base64_decode(encoded_string)Lua接口Base64解码函数本文开头
plc.base64_encode(string)Lua接口Base64编码函数本文开头
plc.bite(data, bit_position)位操作函数本文开头
plc.cloud_bind(bind_table)云服务绑定函数本文开头
plc.cloud_compute(json_string)云服务计算函数本文开头
plc.cloud_publish(...)云服务数据发布函数本文开头
plc.cloud_reg(message_type, callback_function)云服务注册函数本文开头
plc.cloud_status(…)只读标量,跨任务读按既有惯例不加锁。本文开头
plc.cloud_subscribe(...)云服务数据订阅函数本文开头
plc.cn(integer, ...)—本文开头
plc.cs(integer, ...)—本文开头
plc.d(integer, integer, ...)—本文开头
plc.dd(address)PLC DD寄存器读写函数本文开头
plc.df(integer, ...)—本文开头
plc.ds(integer, ...)—本文开头
plc.dsd(integer, ...)—本文开头
plc.dsf(integer, ...)—本文开头
plc.dstr(integer, ...)—本文开头
plc.eth_dhcp(integer, ...)—本文开头
plc.eth_gateway(integer, ...)—本文开头
plc.eth_ip(integer, ...)—本文开头
plc.eth_mask(integer, ...)—本文开头
plc.get(string, integer, integer, integer)—本文开头
plc.kv_get—本文开头
plc.kv_set—本文开头
plc.led(mode)LED控制函数本文开头
plc.lua_password(password_string)Lua密码设置函数本文开头
plc.m(integer, ...)—本文开头
plc.ms(integer, ...)—本文开头
plc.plc_name—本文开头
plc.plc_password(password_string)PLC密码设置函数本文开头
plc.put(string, integer, integer, integer)—本文开头
plc.r(address)PLC R寄存器读写函数本文开头
plc.rd(address)PLC RD寄存器读写函数本文开头
plc.recv_sms()短信接收函数跳转
plc.rf(address)PLC RF寄存器读写函数本文开头
plc.rstr(address)PLC R字符串寄存器读写函数本文开头
plc.rtc_set(integer, integer, integer, integer, integer, integer, ...)—本文开头
plc.s(integer, ...)—本文开头
plc.send_sms(phone_number, message)短信发送函数跳转
plc.sms_recv()短信接收函数本文开头
plc.sms_send(phone_number, message)短信发送函数本文开头
plc.sta_autochn—本文开头
plc.sta_dhcp(integer, ...)—本文开头
plc.sta_gateway(integer, ...)—本文开头
plc.sta_ip(integer, ...)—本文开头
plc.sta_mask(integer, ...)—本文开头
plc.sta_password(string, ...)—本文开头
plc.sta_ssid(string, ...)—本文开头
plc.tn(integer, ...)—本文开头
plc.ts(integer, ...)—本文开头
plc.x(integer, ...)—本文开头
plc.y(integer, ...)—本文开头

plc.recv_sms ​

  • 作用:短信接收函数
  • 调用形态:plc.recv_sms()(库级函数)
  • 参数:无参数
  • 返回:无
  • 可用机型:软 PLC 模拟器 / 上位机

plc.send_sms ​

  • 作用:短信发送函数
  • 调用形态:plc.send_sms(phone_number, message)(库级函数)
  • 参数:2 个参数:第 1 个为字符串(必填)、第 2 个为字符串(必填)
  • 返回:无
  • 可用机型:软 PLC 模拟器 / 上位机

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研