ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python+Snap7采集西门子PLC数据:跨平台工业数采实战指南

Python+Snap7采集西门子PLC数据:跨平台工业数采实战指南 前阵子帮朋友调一条包装产线的数据采集现场的PLC是西门子S7-1500上位机一台Windows一台Linux工控机。客户提了几个硬性要求不要OPC Server的额外授权费不依赖组态软件最好能直接在Linux上跑采集程序还要支持远程写入配方参数。我第一反应就是Python配Snap7这个组合在工业数采圈子这几年越来越常见。如果你也在做类似的设备数据对接比如MES系统采PLC数据、设备状态监控、能源管理系统能耗采集或者是想用Python写一套跨平台的数据采集服务这篇文章应该能帮你少走不少弯路。我会把整个实战过程拆开讲为什么选Snap7、环境怎么搭、连接读写怎么做、一个完整的数据采集小系统怎么落地最后是排错经验和踩坑记录。内容偏实战代码都是能直接跑的原理部分我也尽量用大白话讲清楚。1. 整体方案为什么是Python加Snap71.1 Snap7到底解决了什么问题先回答一个很多人问过我的问题Python本身根本不认识PLC它怎么跟西门子PLC通信答案就在Snap7这个开源库上。Snap7是意大利人Dave Nardella写的一个基于S7协议的通信库底层是C运行效率高对外提供C、C、Python、Node.js等语言的接口。S7协议是西门子PLC以太网通信的底层协议走的是TCP/IP协议族的102端口。Snap7相当于帮你把S7协议栈、COTP握手、TPKT封装这些底层细节全部封装好了你用Python调用的时候只需要关心读哪个数据块、从哪个偏移开始、读多少字节不需要关心那些字节在网络上是怎么组装的。这个库解决了几个实际问题。第一个是授权问题。OPC Server要买授权组态软件要买授权西门子自己的通信库比如Simatic Net也涉及授权和授权版本管理。Snap7是LGPL协议开源个人和商用都不用掏钱这是很多中小项目选它的直接原因。第二个是跨平台。Snap7有Windows版、Linux版、树莓派版、macOS版。同一套Python代码开发机上跑Windows部署到工控机上跑Ubuntu代码基本不用改顶多是底层动态库的路径不一样。第三个是部署轻量。不需要装西门子的软件生态一台普通Windows电脑或者Linux小主机装个Python环境把snap7的dll或者so文件放好就能直接连PLC。对于边缘计算、设备物联网网关这种场景这个优势非常明显。1.2 和OPC、组态软件相比怎么选很多人喜欢一上来就问我到底用OPC还是用Snap7说实话这两个东西不是一个层面的选择要看场景。我用一个表对比一下你在项目选型时可以对照看。方案优点缺点典型场景OPC UA/DA Server工业标准上层软件兼容性好支持复杂数据模型和安全机制授权成本高部署较重配置麻烦大型自动化系统集成多品牌PLC统一接入组态软件WinCC/组态王等画面、报表、报警开箱即用授权昂贵跨平台差二次开发受制传统HMI监控界面西门子Simatic NetAPI官方原生兼容性最稳授权和版本管理麻烦开发难度高西门子全生态深度集成Snap7Python免费开源轻量跨平台开发效率高数据落地方便没有图控界面安全性需自己实现大规模复杂架构需自己设计数据采集、边缘计算、MES对接、IoT平台这个表是我做项目时常用的选型逻辑。如果你的目标只是搞一个可视化界面看现场设备状态WinCC这类组态软件还是合适的但如果你要的是把PLC数据取出来接入关系数据库、Redis、MQTT、Kafka或者要写业务逻辑做数据分析和预警那用Python加Snap7开发效率会高出一大截。1.3 数据流动的整体架构我在项目中通常会把整个采集系统分成三层这样代码结构清晰后期也方便维护。第一层是数据源层就是西门子PLC本身。PLC内部的DB块存放工艺参数和数据M区存中间变量I/Q区对应输入输出信号。你要采集的数据本质上是PLC的各种存储区加上对应地址。第二层是通信层也就是Snap7的Python绑定。它负责和PLC建立TCP连接执行读写请求。这一层有一点要注意Snap7的读写是请求响应模式不是订阅推送所以你需要自己设计轮询策略。第三层是应用层也就是你的Python业务代码。采集到的字节流在这里被解析成温度、压力、产量计数、设备状态这些看得懂的值然后写入数据库、推送到MQTT、展示到Web界面或者触发报警。数据流大概是这样的PLC存储区 → Snap7请求 → 字节数组 → struct解析为具体数值 → 业务处理 → 入库/推送/展示。后面实战项目的代码就是按照这个流程来写的。2. 环境搭建Windows和Linux下的部署细节2.1 安装Python基础环境Snap7的Python包名字叫python-snap7它在PyPI上可以直接装支持Python 2.7老版本和Python 3.x。新项目我建议直接用Python 3.8以上版本。Windows环境下先去Python官网下载安装包安装的时候注意勾选Add Python to PATH这个选项很多人会漏掉。装完以后在命令行验证一下python --version pip --version如果pip版本太旧顺手升级python -m pip install --upgrade pipLinux环境下Ubuntu或者Debian系的系统我一般直接用系统Python或者用apt装python3-venv建一个虚拟环境sudo apt update sudo apt install python3 python3-pip python3-venv python3 -m venv plc_env source plc_env/bin/activate这里建议一定要用虚拟环境尤其你还要装其他依赖的时候虚拟环境能把依赖冲突这个坑直接绕开。我见过太多人在系统Python里pip全局安装最后版本冲突把环境搞乱的例子。2.2 安装python-snap7和底层依赖主库安装很简单一行命令pip install python-snap7但这里有个非常关键的隐藏坑python-snap7本质上是Snap7 C库libsnap7的Python绑定它依赖系统里的snap7动态库。Windows上pip包通常自带了snap7.dll装完就能用。Linux上情况不一样有时候pip包不会自动帮你把libsnap7.so放到系统库目录导致import snap7直接报错提示找不到库文件。我遇到这种情况的处理方法是到Snap7官方GitHub仓库下载对应平台的Release包里面会附带编译好的动态库。Linux环境下把库文件放到系统库目录再执行一次动态库刷新sudo cp libsnap7.so /usr/local/lib/ sudo ldconfig验证是否安装成功在Python里执行import snap7 client snap7.client.Client() print(client.get_connected())如果这一行不报错说明库已经能正常加载了。get_connected()返回False是正常的因为你还没建立连接。这里我还要提醒一个细节Windows下如果报找不到snap7.dll可以检查一下你有没有装Visual C运行库某些精简版系统确实缺这个。去微软官网装一个Visual C Redistributable就能解决。2.3 连接PLC前必须完成的三项确认很多新手按教程写好代码一运行就连接超时然后就开始怀疑代码有问题。其实大部分连接问题都不是代码问题而是PLC侧设置和网络环境没准备好。我每次都会提前确认三件事你可以直接抄这个检查清单。第一PLC的IP地址和你的电脑IP地址要在同一个网段。比如PLC是192.168.1.10你的电脑就应该是192.168.1.x。这个看起来简单但实际项目中因为网段配错导致连不上的情况特别多尤其是设备被接在不同的交换机上时。第二防火墙要放行TCP 102端口。Snap7和PLC通信走的是TCP 102端口Windows或者Linux的防火墙如果默认拦截连接就会超时。我建议先把防火墙临时关掉测试连通性通了以后再针对102端口加放行规则这样能快速定位问题到底是不是防火墙。第三S7-1200和S7-1500需要在PLC程序里启用允许来自远程对象的PUT/GET通信访问。这个选项在博途软件的PLC属性里在防护与安全分类下勾选允许来自远程对象的PUT/GET通信访问。这步不做Snap7连接时大概率会因为通信访问被拒绝而报错。对于S7-1500的DB块还有一个容易踩坑的地方DB块默认勾选了优化块访问勾选后变量是按符号名访问的没有固定的偏移地址Snap7这种按地址访问的方式就会失灵。解决办法是在DB块属性里取消优化块访问编译下载后每个变量才有确定的偏移量供你使用。这块我在后面数据解析的部分还会展开讲。3. 通信核心连接、读写、解析3.1 连接参数怎么填rack和slot的含义Snap7连接PLC时connect函数需要四个核心参数IP地址、机架号rack、槽号slot、TCP端口。import snap7 client snap7.client.Client() client.connect(192.168.1.10, 0, 1, 102)IP地址和端口好理解。rack和slot这两个参数对新手来说比较绕它其实是描述PLC内部物理位置的逻辑概念用来告诉Snap7你要访问的CPU插在哪个机架的第几个槽位上。我整理了一个常用对照表不同PLC型号取值不同实际项目里你可以按这个参考具体以现场硬件组态为准。PLC型号rackslot说明S7-30002最常见配置CPU通常在2号槽S7-40003部分型号还有更高槽位需要看硬件配置S7-120001一体化PLC固定配置S7-150001一体化PLC固定配置S7-200带以太网模块0配置根据模块情况不是所有型号都能用Snap7直连很多现成例子里都是rack0、slot1拿来连S7-1200/1500没问题如果照抄去连S7-300就会连接失败原因就是slot不对。所以连接参数一定要搞清楚你现场设备的具体型号和硬件组态不要无脑复制网上的代码。3.2 读取DB块和M区数据连接建立之后核心操作就是读写。我先说DB块的读取。DB块是西门子PLC里用来存放数据的存储区相当于一个数据结构化的仓库。读取DB块的API是db_read你需要告诉它三个信息DB块的编号、从哪个字节偏移开始读、读多少个字节。# 读取DB1从偏移0开始的4个字节 data client.db_read(1, 0, 4)读出来的data是一个bytes对象比如b\x41\xc8\x00\x00。如果你直接把这种原始字节拿去用肯定看不懂。这一步是理解Snap7通信的关键协议层传给你的永远是原始字节数据类型的解释完全由你来做。M区位存储区的读取稍微不一样用的是read_area。M0.0表示M区的第0字节的第0位这种地址在梯形图里很常见。读取M区的一段数据要指定区域类型import snap7 from snap7.types import Areas, S7WLByte # 读取M区从偏移10开始的2个字节 data client.read_area(Areas.MK, 0, 10, 2)Areas.MK代表M区第二个参数0是DB块编号M区不需要填0就行第三个参数是偏移量第四个参数是长度。类似地Areas.DB可以配合db_number参数来通过read_area读取DB块Areas.PE对应输入映像区I区Areas.PA对应输出映像区Q区。需要注意一点read_area底层其实比db_read更通用但它的参数稍微复杂些。日常读取DB块用db_read就够了读取M区、I/Q区这些再用read_area。3.3 读取结果怎么解析成真实数值这是整个流程里最容易出错的一步也是我要重点讲的地方。西门子PLC的数据存储是大端模式Big-Endian也就是高字节在前低字节在后。而你的电脑CPU多半是小端模式Little-Endian直接用普通的处理方式去解析读出来的一定是错的。Python的struct模块是这里最好的工具。用struct.unpack去解包bytes关键就是你得在格式字符串里用上表示大端对齐。先看一个例子读取温度传感器PLC里是一个Real类型32位浮点数存放在DB1的偏移0处。import struct data client.db_read(1, 0, 4) temperature struct.unpack(f, data)[0] print(f当前温度{temperature} ℃)这里的f意思就是大端序的32位浮点数。如果你写成f或者干脆忘了指定字节序解析出来的数值会非常离谱甚至有可能是NaN。为了省事python-snap7也提供了一些工具函数比如snap7.util模块里的get_real、get_int、get_bool等可以直接帮你解析。具体用法是这样from snap7.util import get_real data client.db_read(1, 0, 4) temperature get_real(data, 0)get_bool稍微特殊一点因为位Bool是藏在字节里的。比如你要读DB1.DBX0.0那它位于DB1的字节0的位0。读法如下from snap7.util import get_bool data client.db_read(1, 0, 1) flag get_bool(data, 0, 0)我把常用类型和struct格式对照列出来你可以收藏保存。PLC数据类型占用字节数struct格式说明Bool1实际只用到1个位用get_bool/set_bool按位处理Byte1B无符号8位Int2h有符号16位整数DInt4i有符号32位整数Word2H无符号16位DWord4I无符号32位Real4f32位浮点数String1N按长度自行解析首字节是长度千万不要把所有数字类型的长度搞混比如把Int当成4字节去读或者把Real当成2字节去读那样解析出来的值必然对不上而且排查起来很费劲。3.4 写入控制指令和参数有了读取的基础写入其实就是把过程反过来把你的数值打包成PLC约定的字节格式再通过Snap7写过去。写入DB块的API是db_write它接收DB块号、起始偏移、要写入的字节数据。import struct # 把26.5以Real类型写入DB1偏移0 value 26.5 data struct.pack(f, value) client.db_write(1, 0, data)写入M区类似用write_areaclient.write_area(Areas.MK, 0, 10, data)写入Bool类型的时候要小心位操作。比如你只想修改DB1.DBX0.1这一位不能直接写一个字节进去因为那会覆盖同字节里的其他位。正确做法是先把整个字节读出来用set_bool修改目标位再把整个字节写回去。from snap7.util import set_bool data bytearray(client.db_read(1, 0, 1)) set_bool(data, 0, 1, True) client.db_write(1, 0, bytes(data))这种读-改-写的操作用在Bool变量上非常常见尤其是一个字节里定义了多个独立的布尔标志位时一定要按这个流程来否则会互相踩坏数据。另外我建议凡是写入PLC的指令尤其是控制电机启停、打开阀门这类动作在生产环境里一定要做权限校验和操作确认最好在PLC侧也加逻辑互锁。软件上写错了顶多报错但如果把不安全的指令直接发给产线设备后果就不一样了。这个安全意识从开发阶段就要有不要等到现场出了事再后悔。3.5 循环采集与断线重连实际项目里你不会只读一次数据就完事通常要循环采集。但有一个性能方面的坑我在这里提前提醒不要每一次采集都重新建立连接也不要在一个很短的循环里频繁发起小数据量的读写请求。Snap7连接是一次性握手建立连接的连接建立以后后续读写走的是同一个TCP连接。频繁connect/disconnect不仅慢还可能让PLC侧的通信资源变得紧张。所以正确做法是启动时建立一次连接之后在循环里反复读写程序退出时再断开。我一般会封装一个采集线程里面做这几件事循环执行采集任务每次任务前检查连接状态断开了就重连重连失败时做退避处理避免每秒钟都在疯狂尝试连接采集的数据放入队列由业务线程去消费处理伪代码如下import time import snap7 class PLCCollector: def __init__(self, ip, rack0, slot1): self.ip ip self.rack rack self.slot slot self.client snap7.client.Client() self.running False def connect(self): if not self.client.get_connected(): self.client.connect(self.ip, self.rack, self.slot, 102) def reconnect_loop(self): while not self.client.get_connected(): try: self.connect() except Exception as e: print(f连接失败5秒后重试: {e}) time.sleep(5) def read_temperature(self): data self.client.db_read(1, 0, 4) return struct.unpack(f, data)[0] def start(self): self.running True while self.running: try: if not self.client.get_connected(): self.reconnect_loop() temp self.read_temperature() # 放入队列或直接处理 time.sleep(1) except Exception as e: print(f异常: {e}) time.sleep(2)这个结构的核心思想是把连接状态判断纳入循环逻辑确保通信链路断了能自动恢复。工业生产环境不比开发环境网络抖动、PLC重启、交换机断电都是家常便饭没有自动重连机制的采集程序是跑不长的。4. 实战项目跨平台数据采集与监控系统4.1 需求拆解和模块设计我以一个实际的设备数据采集小系统为例把完整思路走一遍。假设现场有一台S7-1500PLC我需要采集它的实时温度、电机转速、产品计数、设备启停状态并且支持远程下发一个转速设定值。采集到的数据要写入SQLite数据库还要提供一个简单的HTTP接口给上层MES系统查询。这个需求拆解后分成几个模块通信模块负责连接PLC执行数据读写解析模块把原始字节转换成真实物理量存储模块把采集结果写入SQLiteWeb接口模块用Flask提供HTTP查询和写入接口模块之间通过队列解耦采集线程负责把数据放进队列存储线程和Web服务各自消费。这样做的好处是即使Web服务繁忙也不会阻塞采集线程的实时性。4.2 核心代码实现下面是通信模块的完整实现包含连接管理、读写数据和自动重连。import struct import time import threading import queue import snap7 from snap7.types import Areas class S7Client: def __init__(self, ip, rack0, slot1): self.ip ip self.rack rack self.slot slot self.client snap7.client.Client() def connect(self): if not self.client.get_connected(): self.client.connect(self.ip, self.rack, self.slot, 102) def disconnect(self): self.client.disconnect() def read_db_real(self, db_number, offset): data self.client.db_read(db_number, offset, 4) return struct.unpack(f, data)[0] def read_db_int(self, db_number, offset): data self.client.db_read(db_number, offset, 2) return struct.unpack(h, data)[0] def read_db_dint(self, db_number, offset): data self.client.db_read(db_number, offset, 4) return struct.unpack(i, data)[0] def read_db_bool(self, db_number, byte_offset, bit_offset): data self.client.db_read(db_number, byte_offset, 1) return bool(data[0] (1 bit_offset)) def write_db_real(self, db_number, offset, value): self.client.db_write(db_number, offset, struct.pack(f, value)) def write_db_bool(self, db_number, byte_offset, bit_offset, value): data bytearray(self.client.db_read(db_number, byte_offset, 1)) if value: data[0] | (1 bit_offset) else: data[0] ~(1 bit_offset) self.client.db_write(db_number, byte_offset, bytes(data))这个S7Client类把读DB、读M、写DB、自动重连这些常用功能都封装好了。实际开发中我还会加超时设置、日志记录这些增强功能但核心逻辑就是上面的样子。采集线程这边用一个线程循环读取PLC的多个地址class CollectorThread(threading.Thread): def __init__(self, s7, data_queue): super().__init__() self.s7 s7 self.data_queue data_queue self.daemon True self.running True def run(self): while self.running: try: if not self.s7.client.get_connected(): self.s7.connect() record { timestamp: time.time(), temperature: self.s7.read_db_real(1, 0), speed: self.s7.read_db_int(1, 4), count: self.s7.read_db_dint(1, 6), running: self.s7.read_db_bool(1, 10, 0) } self.data_queue.put(record) except Exception as e: print(f采集异常: {e}, 尝试重连...) time.sleep(2) time.sleep(1)这里注意我把S7Client类的client对象直接暴露了在run方法里用self.s7.client.get_connected()判断连接状态。你也可以在S7Client里封装一个is_connected方法代码会更规整。这种设计见仁见智重点是连接判断和重连逻辑必须在采集循环里因为网络断了以后只有在后续请求时才会发现异常这时候要有机制自动恢复。4.3 Web接口和数据存储存储和Web接口我就不贴完整代码了讲一下思路就够了。存储用sqlite3每次从队列里取一条记录插入一张表表字段跟record的key对应。为了避免频繁提交可以攒几条批量插入性能会好不少。Web接口用Flask提供两个路由GET /api/status返回最近一条采集记录POST /api/speed接收JSON里的speed字段写入PLCPOST接口核心代码大概这样from flask import Flask, request, jsonify app Flask(__name__) s7 S7Client(192.168.1.10, 0, 1) app.route(/api/speed, methods[POST]) def set_speed(): data request.get_json() speed data.get(speed) if speed is None: return jsonify({code: 400, msg: speed is required}), 400 try: s7.write_db_real(1, 4, float(speed)) return jsonify({code: 0, msg: ok}) except Exception as e: return jsonify({code: 500, msg: str(e)}), 500这样一个完整的跨平台采集系统就成型了PLC数据被周期读出来存入SQLite同时提供HTTP接口给MES或者其他上层系统调用写入接口完成远程参数下发。4.4 在Linux工控机上跑起来Windows开发调试没问题后部署到Linux工控机时有几点要特别留意。代码层面文件路径分隔符不要硬编码成反斜杠用os.path.join或者pathlib要不会在Linux上报路径不存在。另外如果你的Linux机器没装Python记得先装具体命令前面环境搭建部分已经写了。依赖打包方面建议你导出一个requirements.txtpip freeze requirements.txt在Linux上用虚拟环境安装python3 -m venv plc_env source plc_env/bin/activate pip install -r requirements.txt我前面强调过Linux上装完python-snap7后优先确认libsnap7.so放到了合适的位置import不报错再往下走。长期运行的话Linux下我推荐用systemd托管你的采集程序。写一个.service文件放到/etc/systemd/system/下面[Unit] DescriptionPLC Data Collector Afternetwork.target [Service] ExecStart/opt/plc_env/bin/python /opt/plc_collector/main.py WorkingDirectory/opt/plc_collector Restartalways RestartSec10 [Install] WantedBymulti-user.target启用服务sudo systemctl daemon-reload sudo systemctl enable plc_collector.service sudo systemctl start plc_collector.serviceRestartalways配合RestartSec10的好处是程序崩溃或者机器重启后采集服务会自动拉起这个在无人值守的工业现场非常重要。5. 排错手册我踩过的坑和解决思路5.1 连接类故障排查连接问题是我被问得最多的。我整理了一个症状速查表你可以对照排查。症状常见原因解决思路connect超时IP不通、防火墙拦截、PLC不在同一网段先ping PLC的IP检查防火墙102端口确认网段连接立即报错提示拒绝访问S7-1200/1500未允许PUT/GET访问博途里勾选允许远程访问并重新下载连接成功但db_read报错DB块不存在、DB号错误、偏移越界核对DB块号和偏移是否在范围内连S7-300总超时rack/slot参数不对把slot改为2确认PLC硬件组态换电脑后连不上新电脑防火墙默认策略不同放行102端口或临时关闭防火墙测试连接问题排查有一个通用思路先网络层再PLC层最后代码层。先用ping工具确认网络通不通再用Snap7自带的小工具或者写一个最小化连接脚本测试最后再加入数据读写的代码逻辑。一层一层缩小范围才不会在错误的方向上浪费时间。我在现场调试时有个习惯连接测试代码永远单独写一个脚本不放业务代码里因为排查问题时一个最小复现脚本比一整套系统好用得多。5.2 数据解析不一致类故障排查连接没问题但读出来的数据不对劲这种情况比连接问题更让人头疼因为错误的表现形式多种多样。我遇到最多的是解析出超大数值或者NaN。这几乎可以断定是字节序搞反了。前面说了PLC是大端你解析的时候格式字符串里必须写f如果写f就会出现这种问题。解决办法就是核对所有struct.unpack的格式字符串DB块里的变量是大端统一用开头。第二种常见问题是可以读到数据但值对不上偏移量不对。这种情况往往出现在S7-1500的DB块上是因为PLC程序里DB块勾选了优化块访问导致实际存储布局跟你在博途里看到的变量声明顺序不完全一致。强烈建议在项目开发阶段就取消优化块访问让变量有确定的物理偏移。已经勾选的只能在博途里取消后重新编译下载DB块。第三种问题是Bool类型解析混乱。Bool在PLC里是按位存储的一个字节可以存8个Bool。如果你把整个字节当成一个普通数字去解析结果当然不对。这种情况要用我说的读-改-写方式或者用get_bool/set_bool这类位操作函数来处理。5.3 性能和稳定性问题处理再分享几个长时间运行才会暴露的性能和稳定性问题。第一个是采集延迟越来越大。如果运行几小时后数据更新时间间隔明显变大多半是某个地方阻塞了。常见的罪魁祸首是数据库写入太频繁或者HTTP接口处理太慢。解决办法是把采集线程和存储/接口线程彻底解耦中间用有界队列缓冲。这样即使存储临时变慢采集也不会被拖住。第二个是通信频繁断开。如果网络环境不稳定TCP长连接可能被中间设备静默断开但客户端这边还认为连接是好的。解决思路是给Snap7设置合理的ping_interval让它周期性地发送保活探测及时发现连接异常client snap7.client.Client() client.set_ping_interval(5000)这个方法的原理是客户端每隔一段时间发一个心跳包如果几次都没有响应就认为连接已经断了下一次读写就会触发异常然后走自动重连逻辑。具体数值可以根据你的网络环境调整一般设3到10秒之间。第三个是CPU占用过高。这个通常是因为轮询间隔太短比如每50毫秒就循环读一次加上每次读的数据量又小字节数多。解决思路是适当加大轮询间隔合并读请求。对于多个相邻的DB地址可以一次db_read读一块连续区域然后在本地用struct批量解析读写交互次数减少后CPU和网络开销都会明显下降。还有一个容易忽视的点采集程序的日志输出不要太多。生产环境里每秒钟打印一行日志都会拖慢程序尤其日志文件无限增长还会占满磁盘。建议只在连接成功、连接失败、读写异常这些关键节点记录日志并且配合日志轮转策略。我的经验是把日志级别默认设为WARNING调试时才改为INFO这样既能保留排障信息又不影响运行性能。6. 最后一个现场故事和一句经验写到最后我讲一个真实的小插曲收尾。有一次在客户现场部署S7-1200的数据采集代码在测试环境跑得好好的到了一线死活连不上。我排查了很久网段没问题IP能ping通防火墙也放行了最后打开博途一看发现PLC属性里的允许PUT/GET通信访问根本没勾选。我一开始还以为是安全默认开着的结果西门子为了让设备更安全默认是禁止远程通信的。勾选之后、重新下载、连接一秒钟就通了。那次以后我学乖了凡是遇到S7-1200/1500连接问题第一件事就是检查这个选项比任何代码层面的排查都管用。所以最后分享一句经验跟PLC打交道很多问题不是程序写得不对而是你还没有完全理解PLC侧的那些设置项。Snap7把网络通信封装得再完美也管不了PLC那边允不允许你连。做工业通信项目一定要同时懂上位机和PLC两侧至少在调试阶段能自己动手在博途里检查一下PLC配置。把这句话记住了你能少踩一半的坑。
返回列表