3. S7comm 西门子PLC数据采集
任务目标
本案例实现一个基于 S7comm 协议的西门子 S7-1200 PLC 数据采集程序,使用 Python 的 python-snap7 库读取 PLC DB 块中的生产数据(整数、实数、布尔量),并输出到控制台。程序需具备连接状态检查、数据读取与错误处理能力。
环境依赖
- Python 3.8+
- 安装依赖:
pip install python-snap7 - PLC 侧需启用 PUT/GET 通信(S7-1200 在“设备组态 → 属性 → 防护与安全 → 连接机制”中勾选“允许来自远程对象的 PUT/GET 通信访问”)
- PLC 与运行程序的 PC 需在同一以太网内,IP 可达
关键完整代码
import snap7
import struct
import time
# ========== 配置参数(按实际环境修改) ==========
PLC_IP = "192.168.0.1"
RACK = 0
SLOT = 1
DB_NUMBER = 1 # 数据块编号
READ_TIMEOUT = 3 # 秒
# DB1 内部偏移定义(示例布局)
OFFSET_INT = 0 # 2字节 整数(例如:当前工件计数)
OFFSET_REAL = 4 # 4字节 实数(例如:温度值)
OFFSET_BOOL = 10 # 1字节 位0(例如:设备运行状态)
def read_plc_data():
"""连接 PLC 并读取 DB 块中的生产数据"""
client = snap7.client.Client()
try:
# 建立连接
client.connect(PLC_IP, RACK, SLOT)
if not client.get_connected():
raise ConnectionError("无法连接到 PLC")
print(f"✅ 已连接 PLC {PLC_IP} (机架 {RACK}, 槽位 {SLOT})")
# 读取 DB 块数据(一次读取 12 字节,覆盖上述偏移区域)
db_data = client.db_read(DB_NUMBER, 0, 12)
# 解析数据(按小端字节序)
int_value = struct.unpack_from(">h", db_data, OFFSET_INT)[0] # 有符号16位整数
real_value = struct.unpack_from(">f", db_data, OFFSET_REAL)[0] # 32位浮点数
bool_byte = db_data[OFFSET_BOOL]
bool_value = bool(bool_byte & 0x01) # 取第0位
# 输出采集结果
print(f"📊 工件计数 (INT): {int_value}")
print(f"🌡️ 温度值 (REAL): {real_value:.2f} °C")
print(f"⚙️ 设备运行状态 (BOOL): {'运行中' if bool_value else '停止'}")
return int_value, real_value, bool_value
except snap7.snap7exceptions.Snap7Exception as e:
print(f"❌ Snap7 通信错误: {e}")
except ConnectionError as e:
print(f"❌ {e}")
except Exception as e:
print(f"❌ 未预期错误: {e}")
finally:
client.disconnect()
print("🔌 连接已断开")
if __name__ == "__main__":
# 单次采集(如需周期采集,可在此处加循环)
read_plc_data()
运行方式
- 将上述代码保存为
s7_read.py - 修改
PLC_IP、DB_NUMBER及偏移量以匹配实际 PLC 组态 - 执行命令:
python s7_read.py
验证方法
- 连接验证:程序输出“✅ 已连接 PLC”且无异常,说明网络与通信参数正确
- 数据验证:在 TIA Portal 中在线监控 DB1,对比程序输出的 INT/REAL/BOOL 值与 PLC 监控值是否一致
- 错误验证:断开网线或修改错误 IP,程序应输出“❌ Snap7 通信错误”或“❌ 无法连接到 PLC”,且不会崩溃
- 通过条件:程序能稳定读取并正确解析 DB 块中三种数据类型,数值与 PLC 侧一致
常见问题
- 连接超时:检查 PLC IP 是否可达(
ping),确认机架/槽位号(S7-1200 通常为 Rack 0, Slot 1) - 读取错误 0x81000000:DB 块不存在或偏移越界,核对 DB 编号与数据长度
- 字节序错误:S7 协议使用大端字节序,代码中已用
>h和>f正确解析 - 无法访问 DB:确认 PLC 已启用 PUT/GET 通信,且 DB 块无优化访问(需取消“优化的块访问”属性)