3. S7comm 西门子PLC数据采集

S7comm 西门子PLC数据采集 学习卡片

任务目标

本案例实现一个基于 snap7 库的 Python 客户端,通过 S7comm 协议连接西门子 S7-1200 PLC,读取 DB1 块中偏移量为 0.0(Real)、4.0(Real)、8.0(Int)和 10.0(Bool)的生产数据,并在控制台输出。该案例覆盖从 TCP 连接到数据解析的完整最小闭环。

环境与依赖

  • Python 3.8+
  • 安装 snap7:pip install python-snap7
  • PLC 侧需开放 S7 通信(默认端口 102),并确保 DB1 为非优化访问(允许通过偏移读写)

完整实现代码

import snap7
from snap7.util import get_real, get_int, get_bool
from snap7.types import Areas

PLC_IP = "192.168.0.1"      # 按实际 PLC IP 修改
RACK = 0                    # S7-1200 通常为 0
SLOT = 1                    # S7-1200 通常为 1
DB_NUMBER = 1               # 读取 DB1
START_OFFSET = 0            # 从 DB1.DBB0 开始读取
READ_LENGTH = 12            # 读取 12 字节(覆盖 0.0~11.7)

def read_plc_data():
    """连接 PLC 并读取 DB1 中的生产数据"""
    client = snap7.client.Client()
    try:
        client.connect(PLC_IP, RACK, SLOT)
        if not client.get_connected():
            raise ConnectionError("无法连接到 PLC,请检查 IP、机架/槽位及网络")

        # 一次性读取 12 字节,避免多次请求
        data = client.db_read(DB_NUMBER, START_OFFSET, READ_LENGTH)

        # 按偏移解析数据
        temp_value = get_real(data, 0)      # DB1.DBD0 - Real 温度值
        pressure = get_real(data, 4)        # DB1.DBD4 - Real 压力值
        speed = get_int(data, 8)            # DB1.DBW8 - Int 转速
        alarm_flag = get_bool(data, 10, 0)  # DB1.DBX10.0 - Bool 报警标志

        print(f"温度: {temp_value:.2f} °C")
        print(f"压力: {pressure:.2f} bar")
        print(f"转速: {speed} rpm")
        print(f"报警标志: {alarm_flag}")

    except snap7.snap7exceptions.Snap7Exception as e:
        print(f"S7 通信错误: {e}")
    except Exception as e:
        print(f"发生错误: {e}")
    finally:
        client.disconnect()

if __name__ == "__main__":
    read_plc_data()

运行与验证

  1. 将代码中 PLC_IP 修改为实际 PLC 地址。
  2. 在 PLC 侧创建 DB1,定义变量:
    DB1.DBD0: Real(温度)、DB1.DBD4: Real(压力)、DB1.DBW8: Int(转速)、DB1.DBX10.0: Bool(报警标志)。
  3. 确保 DB1 的属性中关闭“优化的块访问”(即支持寻址)。
  4. 运行脚本:python s7_read.py

通过条件:控制台输出 4 行数据,且数值与 PLC 监控表中当前值一致。若输出 S7 通信错误,检查 IP、机架/槽位、DB 号及 PLC 访问权限。

常见问题

  • 连接超时:确认 PLC 的 PUT/GET 通信已允许(在 PLC 属性中勾选“允许来自远程对象的 PUT/GET 通信访问”)。
  • 数据解析错误:检查 DB1 是否为优化访问——优化 DB 无法通过偏移读取,需在 DB 属性中取消勾选“优化的块访问”。
  • 字节序:snap7 默认按大端解析,与 S7-1200 默认一致,无需额外处理。
S7comm 数据读取流程与 DB1 内存映射 S7-1200 PLC DB1(非优化访问) DBD0: Real 温度 DBD4: Real 压力 DBW8: Int 转速 DBX10.0: Bool 报警 Python 客户端 snap7.Client() connect(IP, 0, 1) db_read(1, 0, 12) 读取 12 字节 get_real / get_int get_bool 解析 print 输出结果 关键参数 • 端口: 102 • 机架: 0 • 槽位: 1 • 读取长度: 12B • 字节序: 大端 • 需允许 PUT/GET • 非优化 DB 访问