ARTICLE DETAIL

资讯详情

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

LabVIEW读取S7-1200的三种冷门方法:不用改PLC程序也能通讯

LabVIEW读取S7-1200的三种冷门方法:不用改PLC程序也能通讯 深夜十一点产线停车窗口只有四个小时自动化部的老张递给我一个U盘LabVIEW数据采集程序要读一台S7-1200里的配方参数和能耗数据但PLC程序是国外设备商封装好的没法改也没给TIA Portal项目。现场最省事的一条路是用NI OPC Server走一遍可一看授权点数不够DCOM还连不上。那晚我用了三条跟“主流玩法”不太一样的路分别把数据读了出来全程没有动过PLC里任何一行逻辑。这篇就聊聊这三种LabVIEW直接读取S7-1200的冷门方法以及NI OPC如果不顺心还能怎么替换。1. 为什么“不改PLC程序”也能读S7-12001.1 现场真实困境动PLC的代价比想象中高得多很多人第一反应是不改PLC程序怎么读数据这个要求听起来反常识但在一线特别普遍。国外设备的PLC程序基本处于加密保护状态用户手里根本没有TIA项目源文件就算有完整项目程序里可能涉及设备商的工艺算法改一个数据块或通讯指令都可能影响系统稳定性设备商也不允许你乱动。更要命的是改造需要停机窗口产线即便在半夜也是按分钟算钱的停车时间只能用来做被动读取不能碰PLC。还有一个隐蔽原因即使你只是想“加一段上位机读取程序”PLC扫描周期、通讯资源、掉电保持区域都会受影响。S7-1200毕竟是小型PLC资源本来就有限随便加一个通讯功能块很可能挤掉原来的中断或延迟任务试错成本非常高。所以从PLC外部“白嫖”数据通道成了性价比最高的方案。1.2 S7-1200对外通讯的“隐藏通道”概览S7-1200这台设备别看是小型PLC对外通讯能力一点都不小。除去需要写功能块的Modbus TCP、开放性比较差的私有协议底层其实藏着几条“配置级”通道通道需要改动PLC程序固件/版本要求典型用途PUT/GET服务不需要仅在CPU属性中开放基本所有S7-1200都支持按地址直接读取DB、M区、I/OOPC UA Server不需要CPU属性中启用固件4.0推荐4.4符号访问不受优化DB限制Web服务器不需要CPU属性中启用固件4.0状态监控、诊断、变量浏览底层S7协议报文不需要依赖PUT/GET开放所有S7-1200自研通讯、深度集成这些通道的共性在于它们属于CPU的“属性配置”或“服务许可”修改后并不改变梯形图、SCL这些程序逻辑。但有一点必须说清楚哪怕只是修改硬件配置S7-1200通常也需要短暂停机来完成下载。所以“不动程序”不等于“不停机”开工前还是得和产线协调好窗口。2. 三种冷门读取方法逐一拆解2.1 方法一S7-1200原生OPC UA服务器把NI OPC Server踢出局很多工程师做LabVIEW与西门子通讯脑子里默认“一定要有OPC Server”而且这个Server最好装在Windows机器上配DCOM、配用户、配权限。其实S7-1200从固件4.0开始就内置了OPC UA Server也就是说PLC本身就是一台“OPC服务器”上位机只要用OPC UA客户端连上去就可以完全不需要NI OPC Server这个中间层。TIA侧配置并不复杂设备视图选中CPU进入“属性→运行系统许可证→OPC UA”勾选“激活OPC UA服务器”然后到“安全→用户”里添加一个系统用户并分配浏览和读写权限。关键优势在这里PLC里的DB块一旦启用OPC UA会以符号形式自动暴露出来即使是“优化的块访问”Optimized Block Access也能按变量名正常访问。这一点很关键因为S7-1200从V4.0开始新建的DB默认是优化块访问而S7协议按地址读取是读不到优化块内部变量的。LabVIEW侧你有两个选择。第一个是用NI DSC模块自带OPC UA客户端拖一个“OPC UA Read”节点直接读写第二个是封装开源OPC UA客户端库比如open62541用CLFN方式调用。我在实际项目里更推荐第一种因为DSC模块不仅提供客户端还能把数据直接映射到共享变量里后续做历史趋势、报警都顺手得多。这个方法的“冷门”之处在于很多人还把OPC UA当成企业级SCADA专属功能根本没想过小型PLC能直接扛起UA服务器。缺点当然也有老固件不支持首次连接需要处理证书和信任关系比Snap7多一道手续。但考虑到中长期的通讯趋势这个方案很值得优先尝试。2.2 方法二Snap7开源库 CLFN兼容老固件的万金油如果现场PLC固件还停在3.x或者调试电脑上没装NI DSC模块那Snap7就是最务实的方案。Snap7是一个开源以太网S7通讯库源码托管在GitHub官方提供Windows/Linux等跨平台预编译动态库体积只有几百KB却能实现绝大多数S7 PLC的读写、上传下载、时间同步等功能。它工作的底层逻辑其实就是直接调用S7协议。由于S7-1200允许通过PUT/GET服务与上位机交换数据Snap7就相当于帮你把复杂的协议报文封装成了几个简单函数。只要在PLC的CPU属性里勾选“允许来自远程伙伴的PUT/GET通信访问”LabVIEW就能通过CLFNCall Library Function Node调用snap7.dll里的接口读DB、读M区、读I/O点。相比NI OPC Server它有几点很讨人喜欢完全免费不受点数限制不需要安装任何运行时一个DLL加一组VI就能跑没有DCOM、防火墙那种复杂配置IP通、端口通就能连跨平台Linux下用LabVIEW同样能调对应的so库。缺点自然也有Snap7读的是“地址”而不是“符号”。如果PLC里的DB是优化访问的按偏移读会读不出预期数据另外搞清字节序和数据类型的映射也需要花一点精力。这个问题我放到后面专门讲。2.3 方法三用LabVIEW裸写S7协议报文零依赖的“硬核”做法第三种方法应该算最冷门的既不装OPC Server也不用Snap7而是直接用LabVIEW的TCP函数连接S7-1200的102端口自己构造S7协议报文完成连接、协商、读数据、解析响应。很多人一听就觉得小题大做但这套思路在定制化设备和板卡上很有用尤其当你不允许现场部署任何DLL或第三方运行库的时候。S7默认使用ISO-on-TCPISO 8073的TPKTCOTP协议来承载通信。连接过程分三步先建立TCP连接端口102发送COTP Connection Request报文用CR TPDU的格式握手让PLC确认这是一个S7连接并获得当前PDU长度然后在同一个TCP连接里发送S7通讯报文HeaderParameterData比如“读请求”读取DB1从偏移0开始的4个字节再把返回的Data部分解析出来。这里面有大量细节比如大端字节顺序、PDU长度协商、序号递增、数据类型返回值映射。我建议第一个版本先用“固定死”的请求模板去读同一段数据跑通后再参数化。否则一边看着十六进制报文一边调LabVIEW程序人很容易崩溃。这个方案最大的优势是不依赖第三方任何工具LabVIEW自带TCP节点就能跑。缺点是开发周期长、排错相对吃力。适合打算长期在这条路上投入的工程师或者想把数据采集做成一个无依赖内部工具的情况。如果只是三天内要交差我还是劝你用Snap7。3. 实战演示用Snap7把S7-1200的DB块读进LabVIEW3.1 TIA侧配置细节要复现这个方法先确认你手上PLC的固件版本打开TIA Portal看设备视图CPU模块下方的固件号。只要是4.0以上都好办老版本也不必怕Snap7反而更通用。接下来的步骤很简单进入CPU的“属性→保护与安全→连接机制”勾选“允许来自远程伙伴的PUT/GET通信访问”如果涉及跨网段或者三层交换机记得在项目里设置好IP和子网掩码把配置下载到PLC。这里重点强调一下下载时在“装载”对话框中尽量选择“仅下载硬件配置”不要勾选程序块选项。这样PLC内存里的逻辑代码不会被覆盖你等于只是刷新了一下CPU的系统属性。虽然严格来说这也算“动过PLC”但和修改梯形图或SCL完全是两码事风险极低。3.2 在LabVIEW里布置CLFN节点把官方提供的snap7.dll放到LabVIEW项目目录或者Windows的System32目录下。打开程序框图放一个Call Library Function Node右键配置Library name or pathsnap7.dll的全路径Function name先选Cli_CreateCalling conventionstdcallWindows版Snap7默认stdcall返回类型int32即错误码。后面按调用顺序依次创建以下CLFN实例函数作用关键参数Cli_Create创建客户端对象无参返回Client句柄Cli_SetConnectionType设置连接类型Client句柄, ConnectionType1PG类型Cli_ConnectTo连接到PLCClient, IP地址, Rack0, Slot1Cli_ReadArea读数据区Client, Area0x84, DBNumber, Start, Amount, WordLen, BufferCli_Disconnect断开连接ClientCli_Destroy销毁客户端对象Client提一句S7-1200的Rack和Slot在TIA默认情况下通常为0和1部分型号或固件可能槽位有差异如果连接不上可以在0和1之间换着试。很多人第一次就连不上问题大多出在这。3.3 数据读取与REAL类型转换CLFN节点配置好之后推荐用一个顺序结构或状态机来控制调用顺序避免每次循环都重复Create和Destroy。我常用的结构是初始化阶段Cli_Create → Cli_SetConnectionType → Cli_ConnectTo循环读取阶段反复调用Cli_ReadArea用移位寄存器保存Client句柄退出阶段Cli_Disconnect → Cli_Destroy。假如要读取DB1前10个字节Cli_ReadArea的参数可以这样配置Area填0x84对应DB区DBNumber为1Start为0Amount为10。WordLen参数要特别小心读字节数组用S7WLByteSnap7头文件里定义为2不要直接指定S7WLReal因为CLFN只会原样拷贝内存不会自动处理浮点数。具体来说我建议用字节方式读4个字节然后通过“将字符串还原为单精度”按Big-Endian字节顺序转换或者直接用Unflatten From String并设置字节顺序为big-endian把Data缓冲区的字节数组还原成LabVIEW的Single类型。这个转换步骤千万不要省否则你会看到读回来的REAL数据像天文数字一样离谱。3.4 几个值得注意的工程细节连接类型一定要用1PG而不是2OP。S7-1200的OP连接会占用组态连接资源PG类型通常属于调试模式资源占用小稳定性更好。单次读取量不要太大。S7-1200的PDU长度大约240字节Snap7虽然会自动分块但如果你一次读几百个REAL整个读取周期会明显变长影响上位机实时性。循环里一定要加断线重连机制。现场偶尔会有网线松动、交换机重启的情况没有重连逻辑LabVIEW程序会一直报错。我一般定时用连接状态检查函数探测断线后从Cli_Create重新开始。别忽略超时设置。Cli_ConnectTo在IP不可达时可能卡很久。可以在连接前先用LabVIEW的“TCP Open Connection”做一次端口探测不通就直接弹友好提示而不是让程序假死。4. NI OPC Server替代方案盘点4.1 为什么大家都在找NI OPC的替代品NI OPC Server在十年前几乎是LabVIEW与西门子PLC通讯的标准配置但这几年越来越多项目开始绕开它。原因不外乎三点一是授权费用不低而且变量点数有限制超了还得加钱二是DCOM配置太磨人尤其Windows防火墙一开各种权限报错能折腾你半天三是当一个系统只需要读几十个变量为了通讯就装一个重型OPC服务后续维护和加密都是负担。所以“替代”不是因为它不好而是场景变了轻量化成了刚需。4.2 替代方案对比表替代方案实现方式典型场景成本Snap7直接调用在LabVIEW里通过CLFN调用snap7.dll简单读写、单台PLC免费OPC UA直连PLC启用OPC UA ServerLabVIEW用UA客户端多系统集成、需要符号访问免费DSC模块可能有授权python-snap7中转Python脚本读PLC通过TCP/HTTP转发给LabVIEW复杂数据处理、跨网段免费Node-RED网关Node-RED读取PLC后以MQTT/WebSocket发布多协议汇聚、数据上云免费上表里的四种方案并不是互相排斥的。比如你可以先用Snap7直连PLC做数据校验再通过OPC UA旁路到SCADA也可以让Python脚本作为中转站同时再转发一份JSON到数据库。从我的经验看选型第一原则是看你有多少种PLC协议要对接只有S7-1200时Snap7或UA直连足够了设备很杂时Node-RED这种中台会更占优势。4.3 用OPC UA客户端直接替换NI OPC Server如果已经决定放弃NI OPC Server并且PLC固件支持OPC UA那最平滑的迁移路径就是在PLC上启用OPC UA服务器在LabVIEW中装一个OPC UA Client工具包通过UA client读变量。你甚至可以在一个UA session里同时读多台S7-1200而且连接层面的事情比如证书、安全策略、浏览节点都有现成函数库处理。初看门槛比Snap7高但对大型系统来说这个方案更正规。符号节点浏览能力让变量多了以后还能按结构化方式索引比按地址硬读DB块直观得多。如果不想买NI的DSC模块也可以先用UA Expert或Node-RED验证PLC端是否真的能正常暴露节点再用LabVIEW做集成。4.4 python-snap7做轻量级中转站如果你的LabVIEW只有基础版License连DSC模块都没有那用python-snap7做一个数据桥接是成本最低的方案。原理很简单Python脚本通过snap7库从PLC读数据整理成JSON后通过TCP Socket发给LabVIEWLabVIEW这边只需要一个TCP读取节点按一定周期解析JSON字符串。import snap7 from snap7.util import get_real client snap7.client.Client() client.connect(192.168.0.1, 0, 1) # 读取DB1从偏移0开始的4个字节解释成一个REAL data client.read_area(snap7.types.Areas.DB, 1, 0, 4) value get_real(data, 0) print(value)这个桥接方案最大的好处是所有类型转换、单位换算都放在Python里做LabVIEW的程序框图会清爽很多后续增加数据清洗、报警判断在Python侧扩展也方便。缺点是引入了一个额外进程比直接在LabVIEW里调用DLL多一跳毫秒级延迟在大多数采集场景下可以接受。4.5 Node-RED做多协议汇聚网关如果现场既有S7-1200又有Modbus设备、串口仪表和MQTT传感器设备很杂又希望用LabVIEW统一采集Node-RED是一个很有潜力的中台。通过安装node-red-contrib-s7Node-RED能以S7协议读取多台西门子PLC然后通过MQTT broker把统一格式的JSON发布出来LabVIEW订阅即可。Node-RED最吸引我的是流式编程方式不用写太多代码一个读取节点加一个MQTT输出节点十分钟能搭出一个稳定的数据通道。它可以直接运行在一台旧电脑或树莓派上常年跑也很稳。对于不想背PLC通讯代码包袱的团队这个方案能让LabVIEW端彻底摆脱工业协议细节只管收数据。不过Node-RED毕竟是Node.js生态和LabVIEW之间没有原生绑定主要通过网络协议沟通。所以它更适合那些最终要把数据送进数据库或云平台的综合性项目如果只是纯PLC与PC点对点采集Snap7反而更直接。5. 常见问题与排查技巧实录5.1 S7-1200连接失败的排查清单不管用哪种方法连接失败是大家遇到最多的问题。我整理了一个速查表现象可能原因排查方法连不上IPPLC和PC不在同一网段检查IP/子网掩码先Ping通能Ping通但S7连不上CPU属性没勾PUT/GET重新下载硬件配置连接被拒绝防火墙阻止102端口关闭防火墙或在入站规则放行102连接超时Rack/Slot不对或者PLC负载过高用Cli_SetConnectionType换成PG类型能连但读不到DBDB是优化访问块改用OPC UA符号访问或确认地址有效读数不稳定网线/交换机故障或PDU分块过大检查物理层缩小单次读取量还有一个容易忽略的点S7-1200默认的PUT/GET功能在部分固件上只支持特定DB区域如果DB放在某个内部存储区域可能即使普通地址也读取不到。遇到这种情况最快的办法是用TIA监控表在线核查变量的实际地址再用Snap7按地址读。5.2 字节顺序和数据类型映射最容易踩的坑这是几乎每个项目都会踩的坑。S7 PLC的数据存储是大端模式而PC上的x86处理器是小端模式。用Snap7读回一个4字节的REAL数组如果不做字节交换读出来的数值大概率是一个天文数字。解决思路很简单但很考验细心最好一次性按字节读回多个变量LabVIEW里用“Reverse String”按4字节一组的顺序翻转或者用Unflatten From String并选择Big-EndianREAL和INT都遵循同样的规则但STRING类型需要考虑首字节长度字段。如果使用OPC UA方式客户端会自动处理字节序这也是为什么数据复杂度上来以后我更青睐UA直连。5.3 保持长期稳定运行的三个建议第一个建议不要用100ms的固定周期去循环读一个大型DB尽量把读取周期放在500ms以上或者使用“数据变化事件”驱动读取。S7-1200毕竟是小控制器把通讯资源让给PLC自身的控制逻辑会避免很多隐患。第二个建议给LabVIEW程序加一个“心跳”检测。可以定时读取PLC里某个固定M区地址如果连续几次读不到就触发报警并尝试重连。我在两个项目里都用了这个策略连续运行一年多都没有掉线。第三个建议老固件和新固件行为有差异。尤其是OPC UA功能上线后TIA软件版本、PLC固件和LabVIEW侧的证书体系要一起升级避免半新半旧的环境导致安全策略不一致。从我个人的实际项目经验看如果PLC固件是4.0以上我会优先选OPC UA如果是老固件Snap7基本稳定可靠。实在遇到特别偏门的环境裸写S7报文也不是不行但除非时间充裕否则不推荐。最后再分享一个小技巧无论用哪种方法先在TIA里把CPU的“允许PUT/GET访问”勾上好并确保在LabVIEW里用PG模式连接这一条能让90%的新手少走很多弯路。愿你的上位机程序永远不黑屏、连接永不掉线。
返回列表