
1. 为什么我坚持做零成本仿真一条产线的测试困境去年接到一个新能源电池PACK装配线的项目PLC程序在办公室里写了将近三周自认为逻辑天衣无缝。结果到了现场设备一上电就发现传感器信号乱跳摄像头死活取不到流PLC和视觉系统之间的握手协议对不上光排查通讯就把一个下午耗进去了。返工成本摆在那儿从那以后我就养成了一个习惯——凡是成套设备项目发到现场之前先在办公室把虚拟产线跑通。做自动化测试的人都有这种体会现场调试最怕的不是逻辑写错而是等到设备装好才发现错。设备装好了线缆接错了要拆气缸装歪了要调PLC程序下载进去了才发现IO映射错了要改。这些问题如果在办公室里提前用仿真手段发现省下来的时间不是一天两天而是一个星期起步。零成本模拟工业设备说到底就是把试错这个动作从现场挪到办公室。这个方案具体能做什么一是把PLC梯形图逻辑放进仿真器里跑不买真PLC二是用软件把光电传感器、接近开关、温度传感器、压力变送器这些设备的输出信号模拟出来三是用虚拟摄像头或者本机摄像头替代工业相机测试图像采集和视觉判定流程。三个模块串起来一套完整的虚拟产线就出来了。适合谁自控工程师、视觉工程师、测试工程师都适用尤其是那些工作在项目前期的方案设计和后期现场调试之间的人。哪怕你只是刚入门PLC编程的新手这个思路也能帮你把写程序和调程序这两件事彻底分开——程序写得好不好先在电脑上见真章别带着一堆未知数上现场。为什么强调零成本不是说买不起真实的PLC和传感器而是很多项目在投标和预研阶段根本没有硬件预算或者设备还在机械厂里加工电气柜还没开始装配。这个阶段的测试需求最强烈又最拿不到实物。用纯软件方案先建立一个仿真测试环境成本为零收益却是实打实的。还有一个容易忽略的点仿真不仅试逻辑还试人的操作流程。比如新手工程师第一次去现场面对几十个传感器不知道怎么排查如果在办公室就用仿真环境演练过信号丢失→查地址→找原因这套流程到现场就不会变成无头苍蝇。2. 核心方案选型用什么工具模拟PLC、传感器和摄像头零成本不等于选择一个免费软件硬凑而是要把不同环节的免费工具搭配成一条完整链路。我在实际项目里常用的方案总体思路是PLC逻辑用厂商自带的仿真器传感器信号用通用工业协议模拟软件视觉部分用虚拟摄像头加开源图像处理库。下面这张表是常用的工具组合按模块列出来方便对照选型。模块首选工具替代方案核心作用PLC逻辑仿真西门子TIA Portal S7-PLCSIMCODESYS Control Win PLC、三菱GX Works2仿真运行梯形图、SCL程序模拟PLC内部逻辑PLC通讯仿真S7-PLCSIM自带的虚拟以太网接口CODESYS自带的Modbus TCP服务器让外部软件能读到PLC变量开关量传感器Modbus Slave模拟软件Node-RED node-red-contrib-modbus模拟光电开关、接近开关的ON/OFF信号模拟量传感器Node-RED生成曲线数据Modbus Poll配合手动写值模拟温度、压力、流量等连续变化信号摄像头视频流OBS虚拟摄像头ffmpeg推送RTSP流生成虚拟视频输入替代工业相机图像判定Python OpenCVHalcon试用版模拟视觉检测算法输出OK/NG结果数据编排Node-REDPython脚本把传感器数据、视觉结果和PLC变量串起来选PLC仿真器有个原则用你项目里实际用的那个品牌。西门子项目就用TIA Portal加S7-PLCSIM三菱项目就用GX Works2自带的仿真模式CODESYS项目更简单直接用CODESYS Control Win PLC这个运行时软件包连仿真都不用额外开。这样做的原因是不同品牌PLC的指令集、定时器行为、数据块格式差异很大换一个仿真器等于换了一套行为模型测试出来的结果参考价值会打折扣。TIA Portal的S7-PLCSIM有一点要提前搞清楚它和市场上常见的破解版或第三方模拟器不一样S7-PLCSIM是西门子官方提供的仿真工具随博途软件一起安装。它支持S7-1200/1500、S7-300/400的仿真而且从某几个版本开始支持以太网通讯仿真也就是说外部程序可以像访问真实PLC一样去访问它。这对我们测试传感器和摄像头的联动逻辑非常关键。传感器信号模拟这块我偏好Modbus TCP协议作为统一的数据通道。原因很简单几乎所有PLC都支持Modbus TCP通讯而且Modbus Slave模拟软件到处都是免费的好用的随便挑。你用OPC UA当然更现代但如果只是模拟几个开关量和模拟量Modbus TCP的寄存器模型反而最容易理解排查问题也直观。摄像头的模拟方案要分两层理解第一层是视频流从哪来第二层是图像检测逻辑怎么写。视频流我一般用OBS的虚拟摄像头功能把预先准备好的图片或者循环播放的视频变成一路摄像头信号这样OpenCV或者其他图像库就能直接读到。如果需要模拟工业相机的RTSP取流过程可以用ffmpeg把视频文件推成本地的RTSP流上位机用VLC或者OpenCV去拉流整个过程就像在访问一台真实的网络相机。有了这套选型后面每一步都能落到实处。3. 逐步建立PLC逻辑仿真梯形图、DB数据和虚拟网络通讯3.1 创建仿真实例不是把程序Download进去就行用TIA Portal和S7-PLCSIM仿真最基础的操作是创建一个仿真PLC实例然后把程序下载进去。但很多人第一步就理解偏了S7-PLCSIM不是简单按一下开始仿真按钮就完事你需要先在设备配置里确认CPU型号再在仿真窗口里选择对应的固件版本下载的整个过程和真实PLC几乎一样。在S7-PLCSIM里建立仿真PLC之后它会出现在TIA Portal的项目树里和真实的PLC条目长得一模一样。这时候要注意Variant变量的对应关系如果你的程序里用了I区直接寻址比如I0.0对应一个光电开关仿真器里照样有I区如果用了数据块DB那DB里的变量在仿真器里也能实时监控和修改。我个人建议项目里尽量用符号寻址比如光电开关到位这个变量而不是绝对地址寻址因为仿真测试中你有时候需要快速修改某个输入来模拟传感器动作符号名比I0.3这种地址直观得多。3.2 网络模式VMware里跑TIA时最容易卡住的一环我习惯把TIA Portal装在VMware虚拟机里主机上跑Modbus模拟软件和OpenCV视觉服务虚拟机里跑博途和S7-PLCSIM。这样做的原因不是博途对宿主机有什么特殊要求而是把整个工程环境隔离起来避免安装一堆运行库把开发电脑搞乱。但虚拟机里跑S7-PLCSIM网络模式必须选对否则外部程序访问不到仿真PLC。我用的是VMware的VMnet8NAT模式然后在虚拟机的网络设置里把网卡改成自定义并勾选VMnet8。关键点在于S7-PLCSIM的PG/PC接口要选成VMware虚拟网卡对应的那个接口而不是默认的None或者ISO。从外部主机访问虚拟PLC里的S7通讯服务时IP地址填虚拟机网卡的IP端口一般不用改S7通讯默认102端口Modbus TCP默认502。如果你的项目和我的场景类似有一个更稳的做法把虚拟机的网络模式改成桥接模式桥接到主机的物理网卡这样虚拟机里的仿真PLC就直接暴露在局域网里外部设备或上位机软件访问它就像访问一台独立PLC一样。3.3 网络通讯测试从只练逻辑到练真实通讯路径PLC逻辑仿真如果只停留在博途内部看变量表意义就只发挥了一半。真正的价值在于让外部软件像操作真实PLC一样读取和写入仿真PLC的变量然后观察PLC逻辑怎么响应。S7-PLCSIM从TIA Portal V14开始支持仿真PLC和外部设备进行以太网通讯具体实现方式是启动仿真后在S7-PLCSIM窗口里勾选允许来自远程对象的通信访问。之后我用Modbus Poll作为主站直接把仿真PLC当成Modbus从站去读它的保持寄存器。但这里有一个前提你要在PLC程序里启用Modbus TCP服务器功能并正确配置Modbus地址和DB地址的映射关系。这一步踩过的坑是很多人以为S7-1200/1500仿真出来之后自带Modbus TCP服务器其实不是你必须调用MB_SERVER指令块并给它指定连接ID、IP端口和数据块地址。仿真器能做的只是提供一个虚拟的以太网口但网络服务本身还是PLC程序实现的。我在程序里放一个MB_SERVER背景DB然后把Modbus保持寄存器指向一个专门做数据交互的DB传感器模拟软件和视觉系统都通过这个DB和PLC对话。3.4 扫描周期差异仿真测试中最该留意的地方S7-PLCSIM跑程序的扫描周期和真实PLC不一样。仿真器在普通电脑上运行扫描周期受CPU性能影响可能比真实PLC快很多也可能因为后台系统调度出现随机抖动。这个差异在定时器、计数器相关的逻辑测试里会暴露出来。比如我写过一个气缸伸出到位检测用TON定时器做超时判断延时设了3秒。仿真环境里跑3秒的定时器行为完全正常但一旦把程序下载到真实PLC现场环境的电磁干扰、程序扫描周期波动对定时器的累计逻辑影响就大了。所以我养成了一个习惯凡是涉及时间相关的逻辑在仿真阶段不仅要测正常情况下能不能按时触发还要手动修改定时器预设值去测极端情况下会不会误动作。4. 传感器信号的仿真从开关量到模拟量的全面覆盖4.1 开关量传感器用手动触发模拟光电开关和接近开关开关量传感器是工业现场最常见的一类光电开关、接近开关、限位开关、按钮本质上都是给PLC输入一个通断信号。仿真阶段我一般用Modbus Slave软件来做这件事。具体操作流程是先在PC上跑一个Modbus Slave模拟器建立一个TCP Server监听502端口然后在这个服务器里创建一串保持寄存器或线圈。这些线圈和PLC程序里的输入映射关系是提前约定好的——比如线圈0对应光电开关1线圈1对应接近开关2。测试的时候直接在Modbus Slave的界面里勾选或取消某个线圈相当于按下或松开了一个物理传感器。这种做法比直接在TIA Portal仿真器里改I区变量要真实得多因为它走的是完整的通讯链路传感器软件→Modbus TCP→PLC的MB_SERVER功能块→程序内部变量。链路里任何一环出问题都能提前发现。比如我曾经遇到过一次Modbus Slave软件能正常读写但PLC程序里映射错了寄存器起始地址导致线圈状态怎么刷新都不起作用这个问题如果在现场才排查至少要在电气柜里忙活半天。4.2 模拟量传感器用Node-RED生成温度压力曲线模拟量传感器比开关量复杂一些因为它的信号是连续变化的。我常用的做法是Node-RED配合Modbus节点以一定的时间周期往PLC里写入不同的数值模拟温度升高、压力波动这些过程。比如要模拟一个温度传感器真实的工业过程里温度不会突然从25度跳到80度而是一个逐渐上升的过程。我在Node-RED里写一个简单的函数节点每500毫秒计算一次当前温度值按照设定的斜率比如每分钟上升2度递增然后通过Modbus TCP写入PLC的模拟量输入寄存器。用同样的方法还可以模拟压力在一个区间内波动、流量随阀门的开度变化。这些动态的模拟量数据比手动改寄存器值更能暴露PLC程序里模拟量处理的漏洞——比如你有没有对模拟量做滤波有没有做超量程判断量程转换的系数是否写反了。下面是一个Node-RED函数节点的示例模拟一个带波动的压力传感器信号var msg {}; msg.payload 1.6 0.2 * Math.sin(Date.now() / 10000); // 模拟一个在1.4MPa到1.8MPa之间波动的压力值 return msg;4.3 编码器和特殊传感器用寄存器实现位置跟踪如果项目里用了编码器或者视觉引导定位不能只模拟一个简单的通断信号。我处理编码器的办法是在Modbus模拟软件里预先放入一连串按顺序递增的数值模拟编码器旋转时的位置变化。测试时观察PLC程序里的位置计算逻辑是否能正确跟踪有没有出现数值回跳或溢出。这类特殊传感器还要考虑一个共同问题通讯延迟和采样时刻不一致。仿真环境里Modbus TCP的读写延迟通常在1到5毫秒这和真实现场基本一致。但如果你在PLC程序里用读一下寄存器的值这种边沿触发的方式去采样快速变化的位置数据就可能漏掉中间状态。这是个很典型的隐患仿真阶段提前暴露出来后面改进程序结构就从容多了。4.4 传感器断线和故障模拟比正常信号更值得测做传感器仿真不能只模拟正常情况。我在测试流程里专门有一个故障注入环节把传感器的值改成超范围比如温度变成9999把通讯连接断开几秒钟把模拟量的值在半数和满量程之间跳变。目的是测试PLC程序是否有完善的处理机制——报警是否触发、设备是否联锁停机、操作员界面是否显示传感器故障而不是一个离谱的数值。我见过不少项目的PLC程序里根本没有对传感器超量程做判断现场传感器坏了以后程序还拿一个错误值去参与运算导致设备动作完全错乱。仿真阶段多花十分钟做故障注入比现场烧几个传感器划算得多。5. 摄像头视觉测试从虚拟视频流到图像判定5.1 把OBS虚拟摄像头变成工业相机视觉部分的仿真最关键的是先让图像数据能进入检测程序。我的办法是准备一组标准测试图片包括合格品、有缺陷的产品、无产品等不同场景然后循环播放。用OBS的虚拟摄像头功能把这组图片变成一路视频信号OpenCV程序直接打开摄像头索引号就能读到。这和工业相机的区别在哪儿工业相机通常用GigE或USB3.0接口取流方式和普通USB摄像头有差异。但视觉检测算法本身并不是那么依赖具体的取流方式它关心的是图像分辨率、色彩空间、焦距状态和帧率。用OBS虚拟摄像头时我特意把分辨率设为1280x1024帧率设为15fps左右和项目里实际选型的工业相机参数保持一致这样算法开发阶段用的图像数据特征就和现场基本对齐了。如果是模拟网络相机比如海康威视或宇视的IPC可以换成ffmpeg推送RTSP流。同样是拿图片或视频文件作为输入推到本地RTSP地址OpenCV用VideoCapture打开RTSP地址取流。5.2 视觉检测逻辑用Python和OpenCV搭一个伪视觉系统有了视频流以后下一步是开发图像检测算法。如果项目里已经选定了Halcon或者VisionPro可以直接装试用版来测如果是自己写算法我建议用Python加OpenCV免费、上手快、算法验证效率高。用一个实际的例子说明。假设要检测物料是否到位以及物料的方向是否正确。我预先准备了两张标准的模板图片正向和反向运行时取当前帧和模板做模板匹配匹配得分高于阈值就判定OK否则NG。这是最简单的视觉逻辑但足够用来测试PLC和视觉系统之间的交互流程。下面是一个简化版的开源代码用来演示视觉结果如何通过Modbus写回PLCimport cv2 import numpy as np from pyModbusTCP.client import ModbusClient # 连接PLC的Modbus TCP服务 client ModbusClient(host192.168.1.10, port502) client.open() # 打开虚拟摄像头 cap cv2.VideoCapture(0) while True: ret, frame cap.read() if not ret: break # 简单的灰度处理假设用平均灰度做判定 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) mean_value gray.mean() # 判定逻辑物料存在灰度均值应在设定区间 if 80 mean_value 200: result 1 # OK else: result 0 # NG # 结果通过Modbus写入PLC寄存器地址保持约定一致 client.write_single_register(100, result)这段代码的逻辑虽然简单但已经涵盖了关键流程取图→处理→判定→输出结果。实际项目中的算法可能复杂得多但和PLC交互的接口模式是一样的。5.3 视觉结果与PLC的握手不只是写一个寄存器摄像头这块最容易在结果反馈环节出问题。很多视觉工程师习惯直接把OK/NG结果发给PLC但忽略了和PLC之间的时序握手。也就是说PLC要知道什么时候开始检测视觉系统要告诉PLC检测完成PLC要确认结果是不是新的结果。我通常用三个寄存器来完成握手机制Modbus寄存器地址方向含义100PLC→视觉触发信号PLC发出拍照/检测指令101视觉→PLC视觉系统回复检测中102视觉→PLC检测结果0NG, 1OKPLC先给寄存器100写1视觉检测程序检测到这个上升沿之后开始抓帧抓完帧写入寄存器102的结果然后把寄存器101从1改成0表示空闲。PLC端轮询101和102的组合来判断要不要读取结果。这种简单的三次握手流程在真实项目中非常实用而且在仿真测试里就能完整跑通省去了现场联调时反复修改接口协议的麻烦。5.4 测试图像集的重要性视觉仿真最容易被低估的是测试图片集的准备。我要求自己至少准备三类图片正常情况下的合格品、各种缺陷类型的样品、背景噪声特别大的场景比如有油污、有反光、有零件碎屑。每张图片都要标注预期判定结果。这样测的不是算法能不能跑通而是算法在各种变化下稳不稳。有些视觉算法在理想测试图上跑得很漂亮一换到现场光照就崩了而在仿真阶段测试多组极端图片至少能提前发现算法对光照变化特别敏感这类问题。6. 全流程联调一个工位从模型到伪产线的完整走通6.1 搭一个具体的测试场景说了这么多模块怎么把它们串成一个完整的虚似产线我常用一个典型的检测工位来做全流程联调工件进入工位→光电传感器检测到工件到位→PLC启动定位气缸→定位完成→PLC触发视觉拍照→视觉检测工件缺陷→输出OK/NG→PLC根据结果决定放行还是剔除。这个流程覆盖了开关量输入、模拟量采样如果需要的话、视觉检测、PLC逻辑运算、输出动作是工业自动化里一个非常标准的场景。把它完整走通一次等于把整个项目的核心控制循环都验证了一遍。6.2 按时间轴一步一步走通我拆解一下联调过程。整个过程不依赖任何实物所有模块都在一台电脑或虚拟机上跑。先启动虚拟PLC实例确认PLC程序已下载Modbus服务器功能块处于监听状态。启动Modbus Slave模拟软件让开关量传感器和模拟量传感器对应的寄存器处于初始状态。启动OBS虚拟摄像头把测试图片列表作为图像输入源。启动Python视觉检测程序连接虚拟摄像头和PLC的Modbus服务。在Modbus Slave界面手动把工件到位线圈置为1模拟光电开关被触发。观察PLC程序变量到位信号能不能被正确读入定位气缸输出变量能不能自动变为1。在PLC程序里触发视觉检测信号或者用上位机脚本直接向PLC的触发寄存器写1。观察视觉检测程序是否开始抓帧、处理、输出结果。视觉程序把结果寄存器写为1OK或0NGPLC逻辑根据这个结果决定输出变量。在Modbus Slave里把工件到位置为0模拟工件离开观察PLC程序是否完成了这一个周期的全部状态复位。这套流程看着简单但每一步都可能在某个环节卡住。我在实际测试中遇到最多的问题是PLC程序下载之后Modbus服务器没有自动启动外部工具连接被拒绝OBS虚拟摄像头在OpenCV里打开失败原因是摄像头索引号选错了PLC的触发信号和视觉程序的轮询周期不同步导致视觉程序漏掉了触发边沿。6.3 状态监控与分析联调过程中要养成记录的习惯。我在电脑上用一个Excel表格记录每一步的操作时间、变量名称、预期状态、实际状态和备注。比如08:30:05 置位工件到位线圈08:30:07 PLC DB.DBX10.0变为108:30:08 视觉程序收到触发信号。这种时间线记录在排查时序问题的时候特别有价值它能告诉你信号在哪里慢了在哪里丢了。如果发现PLC的输入状态和外部模拟器设置的线圈状态不一致先用Modbus Poll单独读一下PLC的对应寄存器确认通讯链路没问题再检查程序里面变量映射的地址。这个排查思路和现场几乎一模一样只不过把拿万用表量线换成了用软件读状态而这两者解决问题的效率完全不在一个量级。6.4 虚拟HMI和报警系统的联动测试全流程联调除了验证控制逻辑还可以顺便把HMI画面的逻辑验证一遍。我经常用HMI面板软件的仿真模式直接连接虚拟PLC的变量看看画面上的指示灯、按钮、报警窗口是否按预期工作。比如模拟传感器断线观察HMI上报警文本是否弹出来报警确认按钮能不能清除报警状态。这个环节如果放到现场去做耽误的时间不是几分钟而是几小时。7. 踩坑记录与效率建议7.1 虚拟机网络模式相关的坑TIA Portal装在VMware里时默认的NAT模式经常导致外部设备访问不到仿真PLC。最有效的解决办法是用桥接模式并确保虚拟机网卡在VMware网络编辑器里绑定到正确的物理网卡。还有一个细节Windows防火墙可能拦截S7通讯和Modbus通讯实测中我遇到不止一次需要把虚拟机防火墙关闭或添加应用程序白名单。7.2 PLCSIM的仿真精度问题S7-PLCSIM能模拟绝大多数梯形图和SCL指令但它不支持所有硬件特性。比如高速计数器的硬件边沿检测行为、模拟量模块的电气特性这些在仿真环境里是功能等价时序不完全等价的。我在一个项目里用过S7-1212C的高速计数器仿真器显示计数结果完全正常但现场接上真实编码器之后计数不稳定查了半天发现是滤波时间设置的问题启动硬件滤波需要的上升沿时间比较长。仿真阶段这类硬实时问题很难复现只能靠经验提前规避。7.3 Modbus地址映射混乱模块多了以后Modbus寄存器地址映射是最容易乱的地方。传感器模拟软件用寄存器地址0到19视觉程序用寄存器地址100到103PLC程序里MB_SERVER的保持寄存器又指向DB块偏移几十字节的地址。一旦对应关系没理清楚会出现一个令人崩溃的现象在Modbus Slave里改线圈状态PLC程序里的变量没变化在PLC监控表里看到的值用Modbus Poll读出来却是另一个数。我现在的做法是在项目的初期就维护一份变量映射表列清楚每一路传感器信号对应哪个Modbus地址、对应PLC程序里哪个变量、对应HMI上哪个画面元素。表放在共享目录里每次修改都要同步更新。这个习惯帮我在一个多传感器项目中节省了大量排查时间。7.4 实时性能不足的问题如果你的电脑配置不够同时跑虚拟机里的TIA和PLCSIM、主机的OBS虚拟摄像头、Python视觉程序还有Modbus模拟软件CPU占用率很容易达到80%以上。这时候最容易出现的现象是视觉检测的帧率不稳定Modbus通讯超时。我建议一台电脑负荷太重时把PLCSIM单独放到一台虚拟机上跑视觉程序和传感器模拟放主机或者直接把项目拆到两台电脑上通过网络通讯联调效果反而更好。7.5 给新手的一些操作建议如果是第一次尝试这套仿真方案我建议不要贪多按下面这个顺序逐步建立先跑通PLC仿真和Modbus读写把sensor在软件里置位→PLC变量变化这条链路彻底搞定。再加一路模拟量传感器信号测试数据的动态变化。再加虚拟摄像头和视觉程序只做触发→拍照→返回结果这一条最简单的流程。最后把三个模块串成完整场景跑联调。每加一步确认无误后再继续下一步。这样做的好处是出问题的时候排查范围很小不会出现PLC逻辑、传感器通讯、视觉算法全都不对的绝望局面。做零成本模拟这件事最核心的价值是让你在没有设备、没有现场的环境下把一个自动化项目从图纸和程序变成能跑能测、有反馈有结果的验证闭环。这套方法不能替代现场调试但它能把现场调试的风险提前消化掉一大半。我自己在这上面吃过亏也在上面尝到过甜头现在每个项目启动前都要先搭一遍仿真环境。你花在这上面的每一分钟现场都会加倍回报给你。