1. 西门子S7协议通信基础解析
作为一名长期从事工业自动化开发的工程师,我发现在PLC通信领域,直接操作S7协议进行数据交互远比依赖第三方库来得灵活高效。特别是在一些资源受限或需要深度定制的场景下,纯Socket编程实现协议通信成为必备技能。
S7协议是西门子PLC系列设备的标准通信协议,基于ISO-on-TCP(RFC1006)传输。与常见的Modbus协议不同,S7协议采用更为复杂的报文结构,但相应地提供了更高的通信效率和更丰富的功能支持。协议通信的核心在于正确构造请求报文和解析响应报文,整个过程可以分为以下几个关键环节:
- 建立TCP连接(S7 Smart PLC默认端口102)
- 发送协商帧(COTP连接建立)
- 构造S7通信请求报文
- 接收并解析PLC响应
- 处理数据转换(字节序、数据类型等)
在实际项目中,我特别推荐从S7-200 Smart系列PLC入手学习协议通信。原因有三:首先,这款PLC性价比高,广泛应用于中小型自动化项目;其次,它支持标准S7协议的子集,复杂度适中;最重要的是,其网口通信稳定性好,调试方便。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 协议报文结构深度剖析
2.1 基础报文框架
一个完整的S7协议报文由三部分组成:TPKT头部、COTP头部和S7通信数据。在Python中,我们可以用bytearray来构造这些原始数据帧。以下是各部分的详细说明:
python复制def build_base_header():
"""构造TPKT+COTP头部"""
tpkt = bytearray([
0x03, # TPKT版本
0x00, # 保留
0x00, 0x1f, # 总长度(后续根据实际调整)
])
cotp = bytearray([
0x02, # COTP连接长度
0xf0, 0x80, # 连接参数
])
return tpkt + cotp
注意:总长度字段需要根据实际报文长度动态计算,在最终发送前应该更新这个值。
2.2 读请求参数构造
读操作是PLC通信中最常用的功能。构造读参数时需要明确以下几个关键信息:
- 存储区类型(I/Q/M/V区)
- DB块编号(V区对应DB1)
- 起始地址
- 读取长度
python复制def build_read_param(area, db_number, start, length):
param = bytearray([
0x04, # 固定参数
0x01, # 读命令
0x12, # 后续数据长度
0x0A, # 后续数据长度
0x10, # 数据长度
0x02, # 项个
