主题
pipe 西门子 S7 系列
西门子 PLC 在 Pipe 里分成 4 个独立协议,协议名、连接参数和地址格式各不相同,不能混用。读写方法的返回值约定和错误码见 7.1 Pipe 通信概述。
协议选择
| 目标 PLC | 协议名 | 第 2 参数 | 默认值 | ESP32 支持 |
|---|---|---|---|---|
| S7-1200 / S7-1500 | "s71200" | "ip[:port]" | 端口 102,rack 0,slot 1 | 支持 |
| S7-300 / S7-400 | "s7300" | "ip[:port]" | 端口 102,rack 0,slot 2 | 不支持 |
| S7-200 SMART | "siemens_smart" | "ip[:port]" | 端口 102 | 不支持 |
| S7-200(PPI 串口) | "siemens_s7200" | "COM口[:波特率]" | 波特率 9600,帧格式 8E1,站号 2 | 不支持 |
平台限制
ESP32 机型只支持 "s71200"。"s7300"、"siemens_smart"、"siemens_s7200" 只在上位机版本和 Linux 网关版本里提供;在 ESP32 上调用会返回 nil。
S7-1500 走 "s71200"(同为 S7 通信),需要在 PLC 侧允许 PUT/GET 并关闭优化的块访问。
rack / slot / 站号都写死在代码里,不能从 Lua 侧配置。
s71200 — S7-1200 / S7-1500
lua
s7 = pipe.setup("s71200", "192.168.1.10:102")地址格式:必须带 % 前缀,编号十进制。
| 形式 | 含义 |
|---|---|
%I0.0 / %Q0.0 / %M0.0 | 输入 / 输出 / 标志位,. 后是位号(0–7) |
%I0 / %Q0 / %M0 | 同区域的字节/字地址(不带小数点) |
%DB1.DBX0.0 | DB1 的位 |
%DB1.DBB0 | DB1 的字节 |
%DB1.DBW0 | DB1 的字 |
%DB1.DBD0 | DB1 的双字 |
lua
s7:read_bite("%M0.0")
s7:write_bite("%Q0.0", true)
s7:read_u16("%MW100") -- 也可写 %M100
s7:read_float("%DB1.DBD0")
s7:write_u16("%DB1.DBW10", 1234)说明
- 少写
%直接失败,返回参数错误8002。 - 位号只接受
0–7,写.8及以上会被拒绝。这是全部 S7 协议里唯一做了范围校验的地方。 - 没有
V/T/C区,那些是 S7-200 SMART 的写法。 p:read()/p:write()目前不可用,调用会直接返回参数错误。请不要用,需要连续读多个字就用read_u16(addr, count)。
s7300 — S7-300 / S7-400
lua
s7 = pipe.setup("s7300", "192.168.1.20:102")地址格式:不带 % 前缀,编号十进制。
| 形式 | 含义 |
|---|---|
I0.0 / Q0.0 / M0.0 | 输入 / 输出 / 标志位 |
DB1.DBX0.0 | DB 位 |
DB1.DBB0 / DB1.DBW0 / DB1.DBD0 | DB 字节 / 字 / 双字 |
T0 / C0 | 定时器 / 计数器 |
lua
s7:read_bite("M0.0")
s7:read_u16("MW100")
s7:read_float("DB1.DBD0")说明
- 每次读写前都会重新建立 S7 (COTP) 连接,通信频率高时开销明显,轮询周期不要设得太短。
- 位号同样限制在
0–7。 p:read()/p:write()未实现。
siemens_smart — S7-200 SMART
lua
s7 = pipe.setup("siemens_smart", "192.168.1.30:102")地址格式:编号十进制。
| 形式 | 含义 |
|---|---|
I0.0 / Q0.0 / M0.0 | 输入 / 输出 / 标志位 |
I0 / Q0 / M0 | 同区域字节地址(不带小数点也接受) |
VB0 / VW0 / VD0 / VR0 | V 区字节 / 字 / 双字 / 实数 |
DB1.DBX0.0 等 | 指定 DB 号访问 |
lua
s7:read_u16("VW100")
s7:write_float("VD200", 3.14)
s7:read_bite("M0.0")说明
- V 区默认落在 DB1。S7-200 SMART 的 V 区就是 DB1,直接用
VW/VD即可。 - 位偏移不做
<8校验,写.9之类会算出错误的地址而不报错。 p:read()/p:write()未实现。
siemens_s7200 — S7-200(PPI 串口)
lua
s7 = pipe.setup("siemens_s7200", "COM1:9600")
s7 = pipe.setup("siemens_s7200", "COM1") -- 默认 9600串口帧格式固定 8 数据位 + 偶校验 + 1 停止位,PLC 站号固定 2,都不可配。
地址格式:编号十进制。
| 形式 | 含义 |
|---|---|
I0.0 / Q0.0 / M0.0 | 位,必须带小数点 |
VB0 / VW0 / VD0 | V 区字节 / 字 / 双字 |
AIW0 / AQW0 | 模拟量输入 / 输出字 |
T0 / C0 | 定时器 / 计数器 |
只实现了 3 类方法:read_bite / write_bite、read_u16 / write_u16、read_s16 / write_s16。
以下方法是空实现,读返回 nil,写返回失败:
read_s32 write_s32 read_u32 write_u32 read_float write_float read_double write_double read_string write_string
需要 32 位数据时自己读两个字再拼。
说明
- 位地址必须带小数点,写
I0(无小数点)会被拒绝。 p:read()/p:write()未实现。
注意事项
- 4 个协议名不通用:S7-1200 是
"s71200",S7-300 是"s7300",SMART 是"siemens_smart",串口 S7-200 是"siemens_s7200"。 %前缀只有"s71200"需要,其它三个都不需要。此处容易出错。- ESP32 固件只有
"s71200",其它三个返回nil。 - S7-1200 / S7-1500 侧要在硬件组态里勾选「允许来自远方伙伴的 PUT/GET 通信访问」,DB 块要取消「优化的块访问」,否则读不到。
- 管道对象要用全局变量长期持有。
- 写方法返回整数错误码,读方法返回
{errno, data}。
例程
每个例程都是可直接下载运行的完整脚本。西门子分 4 个协议(
s71200/s7300/siemens_smart/siemens_s7200),只有s71200在 ESP32 上支持,其余仅上位机 / Linux 网关,返回nil。通用接口见 8.1 概述。统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。
例程 1:读 S7-1200 的 M 位和 DB 字(ESP32 也支持)
适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 / 上位机 | 依赖模块:pipe timer plc | 难度:★☆☆
场景:S7-1200/1500,每 500ms 读 M0.0 到位本机 M0,读 DB1.DBW10 起 5 个字到 D1~D5。
完整代码(可直接下载运行):
lua
s7 = pipe.setup("s71200", "192.168.1.10:102") -- s71200 在 ESP32 上也支持
if not s7 then print("创建失败"); return end
function poll()
local bits = s7:read_bite("%M0.0")
if bits.errno == 0 then plc.m(0, bits.data[1]) end
local ret = s7:read_u16("%DB1.DBW10", 5)
if ret.errno == 0 then
for i = 1, 5 do plc.d(i, ret.data[i]) end
end
end
t = timer.start(500, poll)要点:
s71200是 4 个协议里唯一 ESP32 支持的;地址必须带%前缀(无%直接8002)。- 端口默认
102,rack0、slot1写死;PLC 侧需勾选「允许 PUT/GET」且 DB 块取消「优化的块访问」。
验证方法:M0.0 → 本机 M0;DB1.DBW10~14 → D1~D5。
注意事项:少写 % 直接 8002;p:read()/p:write() 不可用;S7-300/SMART/200 用对应协议名且 ESP32 返回 nil。
例程 2:写回 S7-1200(写方法返回整数错误码)
适用:同上 | 依赖模块:pipe | 难度:★☆☆
场景:把 1234 写到 DB1.DBW10,并置位 Q0.0。
完整代码(可直接下载运行):
lua
local s7 = pipe.setup("s71200", "192.168.1.10:102")
if not s7 then return end
local e1 = s7:write_u16("%DB1.DBW10", 1234)
print("写 DB 字:", e1 == 0 and "成功" or "失败")
local e2 = s7:write_bite("%Q0.0", true)
print("写 Q 位:", e2 == 0 and "成功" or "失败")要点:写方法返回整数;位号只接受 .0~.7。
验证方法:TIA 侧 DB1.DBW10 = 1234、Q0.0 = 1。
注意事项:写返回整数非 table,别查 result.errno;位号写 .8 及以上会被拒。
例程 3:注意事项——4 个协议名与 % 前缀
适用:同上 | 依赖模块:pipe | 难度:★☆☆
场景:最容易错的两点:协议名选错、% 前缀只在 s71200 需要。
完整代码(可直接下载运行):
lua
-- ❌ 错误:s71200 漏了 %,其它协议却多写了 %
s71200:read_u16("M0.0") -- 缺 % → 8002
s7300:read_u16("%M0.0") -- s7300 不要 % → 报错
-- ✅ 正确
s71200:read_u16("%M0.0") -- 只有 s71200 需要 %
s7300:read_u16("M0.0")要点:协议名 s71200/s7300/siemens_smart/siemens_s7200 不容混淆;% 前缀仅 s71200 需要。
验证方法:正确写法拿到值,错误写法被拒。
注意事项:ESP32 只认 s71200,其余返回 nil;PLC 侧 PUT/GET 与 DB 优化设置不到位会 8109/1007。