做视觉检测设备的工程师都知道,一套项目真正决定运行稳不稳的,往往不是相机本身有多贵,而是PLC怎么跟相机打交道、画面怎么让人看得清。最近我整理了一套三菱FX5U配合CCD视觉控制器做产品检测的设备程序,包括PLC侧逻辑和触摸屏画面,正好把里面一些设计思路和踩坑过程记录下来,给正在做类似项目的同行做个参考。整套系统核心其实就是三件事:FX5U做主控,负责发触发、收结果、跑分选逻辑;CCD视觉控制器负责检测;触摸屏负责状态监控和参数调整。适合刚接触视觉集成的电气工程师,也适合手里有旧设备想改成FX5U控制的同事。
1. 项目方案选型:为什么用FX5U做视觉控制中枢
1.1 控制器的选型考量
先说控制器。三菱FX系列里,FX3U在很多老设备上还在用,FX5U算是新一代主力。做视觉项目时我优先选FX5U,最重要的原因是它内置以太网口。现在的CCD视觉控制器基本都带网口,走TCP协议传结果比串口省心太多,不用转接头,不用纠结232和485的电平兼容问题,插根网线就能把数据拿回来。
其次是运算性能。FX5U的指令处理速度比FX3U快不少,基本指令在纳秒级别,虽然做视觉项目的瓶颈很少在PLC扫描速度上,但碰上需要在短时间内处理多路IO和大量D寄存器数据的场合,5U明显更从容。而且FX5U支持ST语言编程,数据结构化程度高。传统梯形图写逻辑没问题,但处理通信帧校验、数组移位这类算法型需求时,用ST写起来简洁很多,后期维护也轻松。
扩展能力也要提。设备通常有十几个输入点、十几个输出点,FX5U本体加一块扩展模块基本够用;如果后续要加气缸、加传送带节拍控制、加伺服轴,5U的扩展槽和高速脉冲口也能扛住。综合性价比来看,同配置下比Q系列便宜不少,又比FX3U更符合未来维护需求,所以我一般定的配置是FX5U-64MT/ES加一块16点输入输出扩展模块,电源看负载情况配个开关电源。
1.2 CCD与PLC的分工和通信方式
很多人刚接触视觉项目时有个误区,以为PLC要处理相机的图像算法。实际上CCD视觉控制器是独立运算的设备,它自己带镜头、光源、图像处理单元,甚至内置了UI界面。PLC和它之间的交互逻辑很清晰:PLC负责"什么时候拍"和"拍完怎么处理",CCD负责"拍出来长什么样、怎么判断合格"。
通信方式一般有三种。第一种是单纯的IO方式:PLC输出一个脉冲给相机的触发输入,相机检测完成后输出OK或者NG信号给PLC输入点。这种方式简单可靠,但对复杂应用不够用,比如相机需要把测量值、坐标偏移量、字符识别结果传给PLC,IO就传不过来了。
第二种是串口方式,RS232或RS485,相机把结果打包成字符串发给PLC,PLC解析后使用。优点是稳定,缺点是速度慢,适合检测节拍不高、数据量不大的场景。第三种是以太网TCP方式,相机作为服务器,PLC作为客户端主动连接,或者反过来。速度快、数据量大,可以传图像、传检测数据、传自定义报文。
我的习惯是,不管用不用数据通信,IO触发和IO结果一定要保留。IO触发作为硬联锁信号保证每次拍照可靠触发,IO结果作为安全冗余,万一通信异常时至少能靠IO结果跑基本的OK/NG判定。通信数据则用于记录检测具体数值和产品追溯信息。这套双冗余结构在项目调试和后期维护时非常有用,通信出了问题不至于整条线停下来。
1.3 程序架构与运行状态划分
程序架构上,我没有把逻辑都堆在一个主程序里,而是按设备运行状态拆成状态机。
用一个简单的检测工位举例:产品到位传感器亮 -> 顶升气缸动作 -> PLC发触发给相机 -> 相机拍照检测 -> 结果数据返回 -> PLC判定OK放行或者NG推料 -> 计数加一 -> 气缸复位等待下一件。
这个流程如果写成一个大梯形图,看起来会很乱,也不方便查故障。我把它拆成待机状态、触发状态、等待结果状态、判定执行状态,用M继电器做状态标志位,每个状态只处理自己该干的事。程序扫描周期短,视觉处理时间长,两者天然是异步关系。PLC不会卡在那里干等相机,而是发完触发之后继续跑状态机,靠"超时定时器"兜底:一旦超过设定时间没收到结果,就报警提示相机异常或者通信超时。
1.4 软元件规划表,先把地址定死
做这套程序之前,我花了将近一个小时规划软元件地址。地址规划看起来是杂活,实际上直接影响后面写程序和连触摸屏的效率。我见过有同事临时想起哪用哪,最后D寄存器从D0用到D3000,中间还夹杂着大量已经不用但没删干净的地址,触摸屏一崩都不知道去哪里查。
我的规划思路是分区块:M区负责状态和报警,D区负责数据和参数。给一套当时用过的表参考:
| 区域 | 用途 | 备注 |
|---|---|---|
| M0~M9 | 模式标志 | 手动、自动、调试模式 |
| M10~M29 | 自动流程状态 | 状态机各节点 |
| M30~M59 | 报警标志位 | 每个报警独立地址 |
| M100~M119 | CCD通信状态 | 触发请求、结果到达、通信超时 |
| D0~D9 | 生产计数 | 总数、OK数、NG数、节拍数 |
| D10~D29 | 相机运行参数 | 曝光、亮度、判定阈值镜像值 |
| D100~D149 | 通信接收缓冲区 | 存放CCD返回的数据帧 |
| D150~D199 | 通信解析结果 | 解析后的坐标、测量值 |
| D300~D399 | 配方存储区 | 每个配方占用一段连续区域 |
这套规划的好处是,触摸屏画面直接照着这个表去对应软元件,不用满程序翻地址。后面加功能的时候也清晰,哪里缺就往对应区段补。尤其是报警区,一个报警一个M,触摸屏上的报警履历直接按M地址关联文本,哪一段出问题一目了然。
2. PLC程序核心模块:从地址规划到视觉逻辑落地
2.1 触发信号与通信接收的实现
先说触发信号的实现。相机对触发脉宽有要求,通常在5ms到20ms之间,具体看相机的说明书。PLC用输出点给相机,程序上不能只是一个扫描周期的高电平,因为5U的扫描周期有可能只有1ms左右,脉冲太窄相机可能不识别。
我的做法是用定时器做一个固定宽度的脉冲:
LD X0 // 产品到位传感器 OR M100 // 触发请求标志 ANI M101 // 防止重复触发 SET M100 // 置位触发请求 LD M100 OUT T0 K2 // 10ms定时器 * 2 = 20ms脉宽 LD T0 OUT Y0 // 相机触发输出实际上更完整的写法是到位信号下降沿复位M100,再配合状态机防重入。20ms的脉宽对绝大多数视觉控制器都足够了。如果现场对触发抖动比较敏感,我会在X0输入端加一个滤波时间常数,用FX5U输入响应时间设定把它调整到1ms左右,防止传感器抖动导致重复触发。
通信接收这部分才是整个项目的重头戏。FX5U通过内置以太网和相机通信时,一般用Socket通信功能。PLC先向相机发起TCP连接,建立连接后相机把检测结果实时推送过来,PLC侧把接收到的字节存到D寄存器缓冲区。
实际工程里我不太喜欢在PLC里做太复杂的字符串解析,因为D寄存器处理ASCII码会消耗不少扫描时间,但帧格式解析又是绕不开的。举一个我的解析逻辑,假设相机返回的帧格式是:
帧头 0x5A + 地址 0x01 + 数据类型 0x10 + 数据长度 + 数据段 + 校验和
在ST里可以写成:
IF RCV_DONE THEN // 判断帧头 IF D100 = H5A AND D101 = H01 THEN // 累加校验,除数据段外所有字节累加和 CHK_SUM := D100 + D101 + D102 + D103 + D104; FOR i := 1 TO 10 DO CHK_SUM := CHK_SUM + D104 + i; END_FOR; // 比较校验和是否一致 IF CHK_SUM AND HFF = D150 THEN // 校验通过,取数据段 RESULT_OK := D151; MEASURE_VALUE := D152; END_IF; END_IF; END_IF;这个代码只是演示思路,不是直接抄就能用,因为不同相机的帧格式差别很大。但重点是两个原则:第一,必须判断帧头,防止一个字节错位导致整帧解释错误;第二,必须做校验,累加和或者CRC都行,否则现场电磁干扰导致偶发一个字节异常,你根本查不出来。我用串口调试助手对比过,没有校验的情况下,通信10万次可能只有1次错误,但这1次足以造成一台NG品没被剔掉,后果很严重。
2.2 结果判定与分选逻辑
收到CCD的检测结果后,PLC要根据结果执行分选动作。这里有个基础但重要的点:收到结果和实际判别之间有延迟,必须考虑剔除气缸动作的时序。
假设检测工位完成后,传送带把产品送到剔除工位需要2秒,而相机结果0.5秒就返回了。如果把结果直接存到一个固定的M继电器里,等产品到了剔除工位再判断,结果可能已经被下一个产品覆盖了。所以核心思路是用一个"结果队列",让检测结果跟着产品在传送带上走一段距离,到剔除点再取用。
实现方法有两个。一个是硬件方法:把剔除气缸放在检测位正下方,检测结束马上判别,NG就地在传送带空档推掉,不用等产品移动。这种方法时序最稳,前提是检测工位和剔除工位物理位置上重合或者离得非常近。
另一种是软件方法:用一组D寄存器,做成移位寄存器。产品每移动一个等距步进(比如每过一个编码器脉冲),整个数组移动一位,最前面的数据就是当前剔除位的检测结果。
梯形图里用BMOV指令就能实现:
LD 步进信号 BMOV D5010 D5009 K20 // 数组后移一位 MOV 检测结果寄存器 D5029 // 新结果放到队尾用BMOV做重叠传送时,从高地址往低地址移动可以安全避免数据覆盖问题。注意这里K20是数据点数的最大长度,具体长度取决于剔除工位延迟时间对应多少个步进周期。比如传送带每个步进周期是100ms,剔除延迟是1.5秒,那就是15个周期,那么队列至少要16个点左右,留点余量,设成20更稳妥。
这个移位寄存器方案在触摸屏上还有一个方便之处,可以把队列内容实时显示出来,调试时直接观察结果有没有跟着产品走,不用靠猜。
2.3 NG品剔除和超时保护
NG品剔除我一般用气缸配合中间继电器实现。PLC收到NG结果后,输出点给电磁阀,气缸推出,把NG品推落,气缸到位信号反馈后缩回。程序逻辑上要注意复位问题,剔除动作不能一直持续,推完要自动复位,避免下一件合格品被误推。
这里我吃过一次亏。当初在程序里用SET指令保持剔除输出,结果气缸推出之后由于限位信号偶发未检测到位,输出一直保持,后一个合格品被直接推掉了。后来改成置位后加延时复位,不管是否检测到气缸到位信号,超过1.5秒强制复位输出,并附带一个"剔除气缸未到位"报警提示。这样即使气缸传感器故障,也能把故障暴露出来,而不是让生产线悄悄跑飞。
超时保护也是必不可少的。视觉控制器偶尔会死机、通信偶尔会掉线,如果没有超时逻辑,PLC会一直傻等结果,整个工位停在那里不报警,操作工也不知道发生了什么。我在触发请求置位之后启动一个定时器,比如10秒,10秒内没有收到结果到达标志,就复位触发请求并置位通信超时报警,触摸屏弹窗提示"相机通信超时,请检查相机状态"。
类似地,剔除动作执行后也做一个超时监控:气缸应在1秒内到达,如果2秒还没到位,置位气缸异常报警。有了这层保护,夜间无人值守时出现故障,至少不会被连续NG品堆满整个传送带。
2.4 配方管理和掉电处理
同一个设备检测不同型号产品时,相机参数和PLC参数都会变。比如产品A的OK判定阈值是85,产品B的阈值是60;产品A的剔除气缸执行位置可能和产品B不一样。这些参数如果每次生产前靠人工在触摸屏上一个个改,又慢又容易错。
我的做法是做配方管理。触摸屏上有产品型号选择画面,操作工选好型号后,PLC根据配方号用BMOV把配方区数据批量传送到运行参数区:
LD 配方选择触发 BMOV D300 D10 K20 // 配方1区传到运行区每个配方区分配连续20个D寄存器,里面预先存放好对应的相机参数镜像值和PLC逻辑阈值。运行区D10开始也单独占20个,程序只读运行区的值,不直接改配方区。这样切配方时只要一键完成,PLC内部所有参数同步更新。配方区数据用触摸屏上的数值输入控件配合密码保护写入,防止操作工误改。
调完这套系统后,我还花了不少心思处理掉电保持的问题。配方区、生产计数、报警履历这些必须掉电保持,选到锁存区;而通信缓冲区、状态标志、临时变量上电必须清零。如果这两类搞混,上电后可能出现的结果是:设备解锁瞬间,残留的"检测结果"还把剔除气缸误触发一次。所以我在程序起始阶段统一做了初始化,把所有不需要掉电保持的D区用填充指令清零,同时把状态标志M区复位,确保每次上电都是从干净的待机状态开始跑。
3. 触摸屏程序与画面设计:让设备状态一眼看懂
3.1 画面结构与用户权限
触摸屏程序我用的是三菱GOT系列配套的工程软件来组态,整体画面结构从一开始就定了,不临时加。主要画面分为:主监控画面、手动操作画面、参数设定画面、报警履历画面、IO监控画面、产量报表画面。
画面导航的逻辑是:主画面放六个按钮,对应六个子画面,返回按钮统一放在右上角。这个布局看起来简单,实际使用中操作工很吃这套,因为不管在哪一页,想回主画面抬手就能点到,不需要记住复杂的层级关系。
权限管理也建议从一开始就做进去。我分了三级:操作员只能看监控、启动停止设备;调试员可以改相机参数和PLC阈值;管理员可以改配方、格式化SD卡、重置计数。这个在GOT里用用户等级功能实现,每个按钮和数值输入控件指定最低操作等级。省下来的麻烦是,现场操作工误改参数导致的批量不良,基本能从根源上杜绝。
3.2 主监控画面设计
主监控画面是最常看的画面,一定要做到让操作工扫一眼就知道设备状态。布局我通常分为三个区块:
左上区块是设备状态指示灯区。使用PLC的M0模式标志、M1运行标志映射到画面上三个大灯:手动模式显示黄色,自动运行显示绿色,设备故障或者报警显示红色闪烁。颜色规范统一约定,不要今天红色是运行明天红色是停机,否则现场会看得晕。
中间区块是产量看板。总数、OK数、NG数三个大字显示,下面还有一个当前节拍显示。节拍的计算方式是用秒为单位,PLC里用D8039?实际上FX5U的扫描周期和节拍不是一回事,我一般是在程序里用实时时钟计算两个产品到位信号的间隔,算完显示在触摸屏上。这里需要注意大数字的刷新速度,GOT默认刷新周期一般设为100ms就够了,太快的刷新反而会造成显示跳动。
右下区块放一个"相机当前检测状态"的小窗口。M100触发请求、M102结果到达、D151检测结果值直接显示为"OK"或者"NG",并用颜色区分。这样操作工不用摸相机显示器,直接看触摸屏就知道相机目前是什么状态,检测出什么结果。
主画面下方留一条窄的报警状态条,显示最新发生的报警文本。点击报警状态条可以直接跳转到报警履历画面,省掉了操作工到处找报警页面的时间。
3.3 参数输出和双保险机制
参数设定画面是程序的核心交互页面,也是最容易出事的地方。直接在触摸屏上让操作工输入一个值然后写入PLC运行区,这种方案我基本不采用,太容易误触了。想想看,现场人手上有油、戴着棉手套,一个不小心把参数从100改成1000,设备立刻开始出废品,而且往往要等到质检环节才发现。
我的做法是做完双保险。触摸屏数值输入控件输入到临时寄存器D200,D190是当前值的显示。操作工输入完新值后,还要点一下"确认写入"按钮,PLC才会把D200的值传送到D10运行区,并同时校验范围。如果新值超出上下限,PLC拒绝写入并置位参数错误报警。上下限本身也放在触摸屏的数值输入上限下限属性里,两者叠加保护。
"确认写入"这个动作看起来多了一步,但实际上它给了操作工一个确认的机会,也给了系统一个防误触的屏障。实际使用过程中,因为参数输入太随意造成的设备异常,在做了这个机制之后基本归零。
3.4 报警履历和产量追溯
报警履历画面用PLC报M地址关联触摸屏报警文本,这属于GOT的基本功能,但有几个细节值得注意。
报警触发之后,除了画面弹窗显示,还要写入报警时间戳。GOT支持在报警发生时自动记录系统时间,保存到内部存储器。我习惯再加一层:在PLC里把报警代码和发生时的关键数据——比如当时的计数、当前产品型号——组合成一条记录,通过触摸屏的SD卡数据日志功能落盘,存成CSV文件。
产线追溯时导出SD卡里的日志,既能看某段时间的产量节拍,也能看到当时报警和工艺数据的对应关系。有一次客户反馈现场出现疑似的批量不良,上下排查了很久,最后就是靠这个数据日志,把前一天某个时间段内的报警记录和相机测量值明细导出来,定位到是光源闪烁导致的误判。如果没有这个记录机制,这种偶发低概率问题几乎不可能复现。
4. 实操调试顺序与常见问题排查实录
4.1 联调之前必须做的准备清单
视觉项目调试最怕的是"一头扎进程序里乱试",系统的联调顺序能省一半时间。我每次在接通硬件之前都会强制自己先过一遍准备清单:
先核对I/O接线表。PLC输出点、输入点、中间继电器、电磁阀,一个一个对着图纸打勾。这一步尤其要注意PLC输出类型和负载电压的匹配。FX5U晶体管输出是24V DC,如果继电器或者电磁阀线圈是220V,中间继电器就必不可少,直接把PLC输出点接220V负载一定会烧掉。
然后是通信参数核对:相机IP地址、PLC IP地址、子网掩码、端口号,全部在工程软件里和实际设备上逐一确认。工业现场常用的做法是把PLC设为192.168.1.10,相机设为192.168.1.20,触摸屏如果走同一个网就设成192.168.1.30,全部统一网段。看起来简单,但调试时很多人忘了检查端口号,IP通了但端口对不上,TCP连接就是建不起来。
最后是电源和接地的检查。视觉控制器对电源品质比较敏感,如果这个工位正好有伺服驱动器或者变频器,建议相机单独走一路隔离的24V电源,不要和伺服共用开关电源。否则伺服启动瞬间的电压跌落可能让相机重启,现场排查起来非常痛苦。
4.2 分步联调:从IO触发到数据帧解析
联调阶段我建议按四步走,每一步都确认稳定之后再进行下一步。
第一步,先让相机正常工作。用相机自带的调试软件或者PC端工具,手动触发一次拍照,确认图像清晰、光源亮度合适、检测算法跑得通、判定结果正确。这一步如果过不了,后面PLC怎么调都是白搭,因为问题根本不在PLC而在视觉端。
第二步,PLC和相机通过IO点联调。在PLC侧强制输出触发信号,观察相机是否响应拍照,相机的OK/NG输出信号是否回到PLC输入点。我一般会在程序里加一个手动测试页,做一个按钮直接触发相机,这样不用改程序就能反复测试触发时序。
第三步,通信联调。先用电脑端串口助手或者网络调试工具模拟PLC向相机发包,确认能收到相机的响应帧。然后切换到PLC侧,用FX5U的在线监控看接收缓冲区D100到D149的数据,和调试工具收到的内容逐字节对比。这里有个实用习惯:把相机返回的原始报文显示在触摸屏的调试画面里,现场对协议翻来覆去改的时候,不用一直盯着电脑。
第四步,接上触摸屏,把画面上的按钮、数值控件、报警文本全部过一遍。我通常会在设备还没跑起来时,模拟一个NG产品,确认从相机检测、结果通信、PLC判定、触摸屏显示、剔除气缸动作整个链路都正常。这条链路完整走通一次,比空跑一百次都管用。
4.3 典型时序问题的定位思路
视觉项目调试中,时序问题是最难缠的。产品在线上高速移动,哪怕只是气缸慢了100毫秒,或者相机快门延迟了20毫秒,结果就会完全不一样。
漏检问题:检查触发信号脉宽是否满足相机要求,检查相机触发模式是不是上升沿模式,检查CVBS信号是否传输正常。很多时候漏检不是程序逻辑错,而是触发脉冲太窄或者传感器位置偏了。
重复检问题:产品到位信号抖动导致PLC发了两次触发。解决方式是给PLC输入点加滤波时间,或者在程序里做上升沿防抖,保证同一个产品只触发一次。
NG品没被剔掉:优先怀疑剔除气缸动作延时和产品到位信号的位置差。如果剔除位置在检测位下游一段距离,检查移位寄存器队列长度是否匹配,队列太短会导致结果先被挤出队列,NG品到了剔除位时已经没有对应的判断数据了。
判定结果偶尔反了:检查相机和PLC之间的通信数据,重点确认数据帧的字节顺序。曾经遇到过相机返回的测量值有高低字节次序问题,直接显示出来看数值像天文数字,但操作工又看不出逻辑错,最后发现是帧解析时两个字节颠倒了。所以通信数据最好在调试画面上以十六进制原始报文和十进制的解析结果同时显示,方便对比。
4.4 常见问题速查表
把现场最常碰到的问题整理成一张速查表,给接线电工和机械设备调试同事用的,他们拿着表能快速定位一部分问题:
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| 触摸屏和PLC通信不上 | IP地址不在同一网段、通信协议选错、触摸屏通信参数不对 | 检查三处IP设置,确认网口插对,GOT侧设置与PLC一致 |
| 相机不触发 | 触发脉宽太短、触发线接错、相机触发模式是软触发 | 用示波器测PLC输出脉宽,对照说明书调整触发方式 |
| 通信数据偶尔不对 | 帧头判断缺失、校验和错误、电磁干扰 | 增加帧头和校验,通信线远离动力线,必要时加隔离 |
| NG品未剔除 | 移位寄存器长度不够、气缸延时太长、剔除输出被误复位 | 检查队列长度与传送节拍的匹配,调整气缸延时参数 |
| 报警频繁误报 | 输入信号抖动、超时时间设置过短 | 增加输入滤波,延长报警延时,分情况区分瞬时干扰和真实故障 |
| 参数被乱改导致不良 | 无权限管控、直接改运行参数 | 增加用户等级设置,临时寄存器加确认写入机制 |
表格只是最典型的情况,真正现场的问题总是千奇百怪,比如相机光源衰减导致的误判、镜头脏污造成的检测偏差、SD卡异常导致的数据丢失。这类问题需要在设备日常巡检中预留检查机制,触摸屏里加一个光源照度显示或者镜头清洁提醒,虽然简单,但能防住很大一部分偶发不良。
4.5 程序注释和版本管理
调试过程中,程序注释和版本管理容易被人忽视,但等设备交付后吃教训的成本极高。我见过一个项目,调试结束后程序里充满类似"这里改一下试试""先屏蔽"的注释,三个月后设备出问题,接手的人根本不敢动那些没有说明的诡异逻辑。
我现在的习惯是,程序里每个关键逻辑块都加注释,说明触发条件、执行内容、作用对象。ST代码里的变量名也尽量用有含义的英文组合,比如CAM_TRIGGER_REQ、RESULT_OK、NG_SHIFT_REG。版本管理方面,在PLC程序里做一个版本号寄存器,每次修改程序后递增,触摸屏画面同步显示当前程序版本。现场调试时对照版本号,就能确认当前设备里的程序和电脑上的是不是同一版,避免改了一堆东西结果上传下载搞混。
这套程序架构后来我移植到了好几个不同的检测项目里,从螺丝长度检测到二维码读取,再到现在做字符识别追溯,整体框架改动不大,主要就是通信帧格式和配方内容不同。最大的体会是,做视觉项目不要急着写代码,先把软元件表、通信协议、画面清单这三样东西定下来,再动手写程序,效率会高很多,后期也不会被各种临时需求牵着鼻子走。另一个心得是参数尽量全部做到触摸屏上,哪怕是相机曝光值,也要映射到PLC寄存器,让调试的时候不用电脑连着相机去改,直接在屏上就能调。这个习惯帮我在现场节省了非常多的调试时间。