尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

PLC程序能运行≠写得好:从“能用”到“好用”的工程规范之路

PLC程序能运行≠写得好:从“能用”到“好用”的工程规范之路 1. 先从能运行说起这背后藏着的真实差距做PLC编程这行久了你会发现一个特别有意思的现象很多项目验收的时候程序能跑、设备能动、产量能达到大家都觉得这活干得不错。可一旦设备正式投产或者哪天半夜两点设备突然停机你被一个电话从被窝里叫到现场面对屏幕上那一行行闪烁的报警和梯形图的时候才会真正意识到——这程序到底写得好不好。我先抛个问题给各位同行你们有没有接手过别人写好的程序打开编程软件CPU在线程序一调出来满屏的符号和地址注释几乎没有FB块里面套着三层嵌套程序段号排得乱七八糟。关键是设备现在正跑得好好的产量稳定你也就不敢随便动它。但接下来的三个月里每次故障排查你都得对着监控表逐条对地址、看时序、翻说明书甚至要靠猜来判断某一段程序当初为什么要这么写。这种体验我相信很多人不陌生。所以说PLC程序能运行和PLC程序写得好之间隔着的不是一星半点而是维护成本、故障响应速度、团队协作效率甚至是一个工厂能不能长期稳定运转。站在一个干了十来年现场调试和程序维护的工程师角度我想认真聊聊这个问题。这篇文章不是什么教科书也不打算讲太高深的理论只是想把我看到的、踩过的、后来想明白的一些经验好好拆开来说一说。我尽量讲得实在一点适合刚入行的新工程师也适合那些想做程序规范化的老手。看完之后你至少能建立一个自己的判断标准什么样的程序算好什么样的程序只是勉强能跑。2. 好程序的衡量标准不是代码量而是这几个维度2.1 可读性三个月后的你自己也是陌生人能运行的程序可能连写代码的人自己过三个月再看都要挠头。我记得有次维护一台老设备的程序原作者早就不在公司了。程序里有一段逻辑用了一个M中间继电器名字叫M100.3下面挂了一串常开常闭触点。我对着图纸和监控表看了整整一下午才猜出来这个是抓取气缸伸出使能。这就是典型的可读性差。可读性不是说变量名写得多花哨而是别人包括未来的你自己能不能在尽量短的时间内看懂这段逻辑的意图。我习惯的做法是每一个输入信号、输出信号、中间变量都赋予一个能直接说明物理含义的符号比如气缸抓取_伸出到位、传送带_启动指令而不是X0、Y1、M3这种纯地址。另外程序段组织要有逻辑顺序。我见过很多程序把设备的启动、停止、报警、手动、自动的逻辑全塞在OB1里从头到尾三十多个程序段像一锅粥。好的程序程序段的顺序应该是跟设备的工艺流程走的比如上料→输送→定位→夹紧→加工→下料→互锁→报警每个环节在程序里都有清晰的边界。哪怕只是梯形图排序清楚和排序混乱维护效率差出两三倍很正常。还有一点注释。很多工程师觉得程序能跑就懒得写注释等到后面别人来问才对着屏幕拼命回忆。我个人的体会是注释不是写给现在看的是写给三个月后忘了上下文的人看的包括你自己。关键逻辑、状态转换条件、安全联锁的意图这些地方必须有注释。2.2 可维护性改一行代码要动多少地方能运行的程序往往为了赶工期东拼西凑逻辑散落在各个程序块里全局变量满天飞。新的需求下来比如客户说增加一个条件只有在气压达到0.5兆帕以后夹爪才能允许松开你会发现要想改得干净几乎要重写一遍逻辑。可维护性高的程序是什么样它模块划分清楚每个功能独立成块接口明确改一个功能不牵连别的功能。比如把气缸控制统一封装成一个FB块管伸出、缩回、到位检测、超时报警调用的时候只要给不同的背景数据块填充不同的参数就行。要增加气压联锁只需要在FB块里加一个输入参数允许松开_联锁条件接上对应的BOOL变量所有用到这个FB的地方就都生效了。这种设计前期要多花一点时间来规划但后期每一次改动都是在省时间。我做项目的时候宁可在程序架构阶段多跟工艺工程师沟通半小时把功能块划分清楚也不愿意后面连续加班三晚上去改程序。这是被现实教育出来的经验。2.3 可诊断性出故障的时候报警信息能告诉你什么这是能运行和写得好之间区别最直观的地方之一。有的程序设备报警就笼统地弹一条设备故障操作工看到了只能喊电工电工来了之后还得对着I/O表一个个查信号查半天才发现是某个接近开关掉了。好的程序报警信息应该能精准到具体的中文描述比如2工位夹爪伸出超时I0.7无反馈、料仓缺料且已经持续30秒、急停回路断开系统进入安全停止状态。报警信息还应该区分故障等级——提示类、一般故障类、紧急停机类不同等级对应的处理方式完全不同。更进阶一点程序应该记录故障发生时刻的关键数据比如当时的设备状态字、变频器频率、温度值这样事后分析原因会轻松很多。我在好些项目里会把关键参数实时上传到触摸屏或者上位机里保存趋势故障发生时自动记录一段时间的快照。这种设计前期无非是多写几个数据块、几条传送指令但用到的时候真是救命。2.4 安全性不光是设备安全还有程序逻辑的兜底能运行的程序可能正常运行工况下什么问题都没有。但设备不一定总在正常工况下跑传感器会有信号抖动急停会随时按下两个气缸可能会因为气路问题同时误动作。好的程序必须考虑故障安全fail-safe。比如两个互斥的执行机构输出信号必须做硬件互锁之外程序内部也要做软互锁不能只靠外部继电器。比如气缸动作超时之后不仅要报警还要自动切断该气缸的输出防止一直顶着气。再比如模式切换的时候要保证先回到安全初始状态才能执行自动启动。这里我的经验是不要盲信正常情况要主动想着万一不正常了怎么办。程序里多条互锁、多个超时判断看起来繁琐但这才是真正意义上的写得好。2.5 可扩展性留不留余地区别很大这个维度经常被忽略。程序写完设备调试完验收通过看着万事大吉。但是工厂的生产需求是会变的今天加一个工位明天换一种料型后天增加一套自动统计产量。可扩展性好的程序在架构上预留了余量。比如使用的是基于数据块参数的地址而不是把设备号写死在程序里比如功能块设计时有扩展参数接口比如程序里有一个专门的定义区以后加设备、改参数只需要修改数据块内容不用动程序逻辑主体。不具备可扩展性的程序每一次小改动都要动刀改一处就担心破一处最后维护成本高得吓人。3. 从能用到好用我在项目里实践过的改进路径3.1 架构先行写代码之前先画一张逻辑草图我刚入行那会儿接到项目就是打开软件新建工程直接对着电气原理图开始写程序想到哪儿写到哪儿。结果往往是前面写得很顺后面发现变量不够用、程序段顺序混乱、FB块和FC块的关系理不清最后不得已推翻重写。后来我学到一个特别笨但特别有效的方法写程序之前先花两三个小时把整个设备的工艺流程从头到尾走一遍梳理清楚有几个模式手动、单步、自动、调试每种模式下设备应该怎么动作哪些信号之间有关联哪些动作之间需要互锁。然后画一张简单的逻辑框图——纸上的就行不用软件——把各个功能模块之间的关系画出来。这张草图就是程序的骨架。有了骨架之后再往里面填充具体的逻辑思路会清晰非常多。而且这张图还可以拿来讲给同事听、做交接、后期维护的时候也是最好的导航图。我们团队现在做项目的强制流程就是必须先有逻辑架构图评审通过以后才允许写代码。3.2 变量与命名的规范这不是小事是基础很多新手不重视变量定义觉得能用梯形图搞定的就不需要那么讲究。但是一个大型项目动辄上千个变量如果命名混乱后期找信号就是一场灾难。我惯用的变量命名规则一般是模块名_设备名_信号类型_动作内容比如Station1_Clamp_Feedback_Extended——一看就知道是一工位夹爪伸出的反馈信号。又比如Conveyor_Start_Cmd、Alarm_NoPart_1Station。在博图TIA Portal里面我会把变量表按工艺段分组每段一个分区添加备注说明。每个输入输出模块的地址映射到符号表的时候同步把设备位号、传感器名称、位置都写清楚。这样的话哪怕是从来没碰过这套设备的工程师拿到变量表看三分钟就能找到自己需要的信号。还有一点中间变量和系统变量一定要分类存放。定时器、计数器不要随意使用每个定时器的用途要明确最好让定时器名字直接表示它的作用比如T_Clamp_Extended_Timeout。3.3 结构化编程FB和FC的正确用法有些工程师写程序很豪迈一个OB1从头写到尾几百条程序段全局变量满天飞。程序确实能跑但调试的时候修一个变量可能引起十个地方连锁变化险象环生。我强烈推荐使用FBFunction Block函数块来封装重复使用的逻辑。比如气缸控制、电机控制、阀站控制、模拟量处理、报警管理这些在设备里会反复出现的逻辑都应该封装成FB块生成多个背景数据块实例来用。FB有个好处自带存储区背景数据块每次调用的状态数据是互相独立的。你写一个电机控制的FB里面处理启停、故障、反馈、启动超时报警、允许条件然后给输送电机、液压站电机、冷却风机电机各建一个背景数据块调用同一个FB各自的状态互不干扰。改FB里的逻辑所有调用它的实例都跟着更新这能省下大把的调试时间。FCFunction函数适合做一些纯计算、转换、通信的数据处理任务它不带存储功能适合做报警字符串拼接、模拟量工程量转换、速度曲线计算这一类的功能。程序块的数量不是越少越好合理地模块化让每个块承担一个清晰的职责才是质量提升的正道。3.4 状态机让下一步干什么明明白白设备控制里最怕的事情之一是状态模糊。比如一个全自动设备该不该允许启动什么时候从空闲状态进入启动状态哪个步骤没完成就不允许进入下一个步骤如果这些逻辑散落在各处每次排查问题都要从头理一遍。我后来在关键设备尤其是流程连续、步骤明确的设备上普遍采用状态机State Machine的方式来组织程序。用一个INT变量来代表当前状态比如0空闲10自动运行20暂停30故障40急停恢复中然后用CASE指令SCL或者跳转比较梯形图来编写不同状态下的动作逻辑。状态机的优势特别明显程序执行路径一目了然当前在哪个状态该状态允许做什么不允许做什么边界非常清楚。状态切换条件集中管理只要查状态切换的条件就能理解设备的整个动作流程。故障处理逻辑清晰。比如发生急停后状态跳到40在这个状态里统一做复位、恢复、返回安全的处理不需要到处找急停逻辑。很多朋友说SCL不好上手其实状态机用SCL写比梯形图要清晰得多代码量也少很多。S7-1200/1500系列以及市面上主流的欧姆龙、三菱、基恩士、Codesys平台都支持结构化文本我非常推荐在偏逻辑、偏流程控制的程序里用SCL来写状态机。3.5 报警系统不只是一个输出点报警这块我见过很多能运行的程序处理方式极其原始——报警触发一个M点然后在触摸屏上绑定一个指示灯。报警消失就灭了没人知道报警发生了什么、什么时候发生的、持续了多久、操作员看到了没有、怎么恢复的。真正规范的做法是这样的层次报警的触发条件、信息描述、优先级全部集中在一个报警管理FB里统一处理。报警触发后不仅要给HMI发送显示信息还要生成一条报警记录包含发生时间、恢复时间、当前值、报警级别。多个报警同时发生的时候要有排队显示机制HMI上能有实时列表和历史记录。重要的报警要求操作员确认确认之后才能复位。这样做操作工能在HMI上看到非常具体的故障内容和处理提示电工去现场排查的效率会大幅提升设备停机时间会显著缩短。报警系统可以说是可诊断性最好的落地载体。4. 带着问题去复盘我这几年踩过的坑和排过的障4.1 变量乱命名引发的三小时排查前年做一个项目接手之前写了一半的程序。作者习惯用M0.0、M0.1、M1.3这种地址直接编程序不加任何注释。设备调试的时候已经能动作了但后来因为客户增加了一条安全需求——防护门没关到位设备不允许自动启动需要修改启动逻辑。这个需求本来很简单在自动启动条件里加一个安全门到位信号就好。但我硬是折腾了三个多小时才改对因为程序里根本不知道哪些中间继电器代表什么含义哪一段逻辑是自动启动的使能链哪一段又是允许自动启动的置位路径。最后没办法我只能把整个OB1从头逐段看了一遍画出每个M点的置位复位关系图才找到下刀的位置。这件事之后我给徒弟定了一条铁规矩不允许在程序里出现没有符号名的裸地址变量除了系统保留的中断、系统状态等不允许在变量注释里写临时变量三个字完事必须标注具体的用途。4.2 互锁缺失导致的设备撞机另一个更严重的例子是一个装配设备的两个工位共用同一段直线滑台。程序是外包工程师写的滑台在两个工位之间往返理论上两个工位的压装气缸不该同时在位运行。但外包工程师省了两条互锁逻辑觉得反正动作时序是交替的不会同时压。结果有一次因为传感器信号异常两个工位的夹紧气缸同时动作虽然动作幅度不大没有机毁人亡但工件被挤压变形模具受损停机两天。这事教训太深了。程序能跑不等于它对的。特别是涉及到多轴运动、多个执行机构、存在空间干涉的设备互锁逻辑宁可多到冗余也不可少到刚好。我的程序里任何两个有可能产生物理干涉的动作之间一定有三层保护PLC程序软互锁、传感器硬联锁比如两个检测到位信号都触发才能允许下一步、电气回路硬互锁外部继电器。这三层缺一不可。4.3 报警信息说文解字式的排查困境有一次深夜客户打电话说设备报了液压压力低故障操作工不敢继续干活。我远程连过去查看报警确实是压力低但具体是哪个压力开关低、压力值是多少、是持续低还是瞬时闪了一下报警记录里通通没有。然后我给客户打电话让现场看看液压站那排压力表问问是不是哪个阀在切换过程中压力波动了一下。客户找了半天才发现是蓄能器压力开关信号在电磁阀切换瞬间有个几十毫秒的抖动刚好被PLC的扫描周期采样到触发报警。如果这个程序在报警触发时记录了当时的压力模拟量值、当时的设备状态字我远程一看就能定位问题根本不用让客户在大半夜折腾。这就是可诊断性对日常维护的真实影响。后来我写报警程序除了显示报警文本一定会附带触发时刻的关键过程值HMI上能看到当前值xxx设定值xxx这些一目了然的数据。4.4 程序版本管理混乱带来的灾难性升级还有一个真实的场景某设备和某工程师协作他改程序总是在现场直接改改完不更新程序备份也不写修改记录。有一次出一个问题他改了一个定时器的PT值然后下载运行当天确实好了。过了两周同样的故障又出现他忘了之前改过这个定时器又从备用的旧程序里重新下载了一遍把这个修改覆盖回去了。结果故障再次出现他还一头雾水。这个事给团队提了个醒PLC程序的管理应该和软件开发一样要有一套版本管理的意识。现在很多平台比如TIA Portal配合团队中心的版本管理支持程序版本对比但哪怕没有这些工具我在项目中也会强制要求每一次修改必须导出一份带日期和修改说明的备份文件命名规则统一。最简单的做法就是对每一个版本建立单独的文件夹里面放项目备份、修改说明、导出的设备参数。这是一个极其简单但能救命的好习惯。5. 实操中提升程序质量的几个具体习惯5.1 写代码之前先写程序说明书有人可能觉得写程序说明书是给文档工程师干的事。但我自己的体会是一份简单的程序说明书哪怕只有两三页纸对理清思路非常有帮助。说明书里写什么设备概述和工艺流程模式定义手动、自动、调试等以及切换逻辑核心的互锁清单报警目录清单关键参数的设定值和取值范围写这份说明的过程其实就是在脑子里把程序跑一遍。你会发现很多原本模糊的细节比如手动模式下手动按钮按一下应该动作到什么程度自动模式启动后如果上一个工位有料但下一个工位还没准备好应该等还是报警这些都需要明确下来程序才能写得干净。我见过一些工程师一上来就猛写梯形图写得飞快但调试时间特别长问题就在于很多边界条件没想清楚。说明书就是把这些边界条件逼到台面上的一种办法。5.2 仿真测试不是可选项是必选项很多PLC编程软件自带的仿真功能比如S7-PLCSIM或者欧姆龙、三菱的仿真器其实都非常好用。但很多工程师觉得仿真麻烦不如直接上电调试快。我用仿真模拟过水泵、输送带、机器人辅助设备等多种类型的程序控制发现仿真至少能帮你提前抓到三分之一以上的逻辑问题。比如状态切换的边界条件、定时器的比较逻辑、模拟量报警的阈值这些问题在现场上电之前通过仿真改掉的话不知道省多少现场调试时间。特别是碰到一些安全联锁逻辑你可以在仿真里模拟各种极端情况比如急停按下、传感器断线、供气压力不足验证程序是否能可靠地进入安全状态。这些场景在现场复现很困难但是仿真里就是一分钟的事。所以我的建议是任何程序改动都先在仿真环境里跑一轮基础工况确认没有低级逻辑错误之后再下载到真机调试。现场调试成本太高尽量把粗糙的部分留在电脑上解决。5.3 程序注释的境界从写名字到写意图注释的分级我自认为可以分为三层。第一层变量级注释。给每个变量写清楚它代表什么物理信号装在哪个位置。这一层是基本功做不到的谈不上规范。第二层程序段级注释。在每一段程序前面写清楚这段逻辑做什么有什么前置条件输出给谁用。这一层能保证别人按顺序读完你的程序不会迷路。第三层意图级注释。在关键的、容易让人疑惑的逻辑旁边写清楚为什么要这么做。比如启动前延迟2秒是为了等液压压力稳定后再动作否则会出现前两秒推力不足导致压装深度不够这比干巴巴地写延时2秒有用一万倍。我现在写的程序第三层注释越来越多。不为别的就是不想再看到别人对着我的程序反复皱眉。写第三层注释会花一些时间但长期算账节省的时间远超投入。5.4 模拟量处理的细节工程的量纲和滤波模拟量是很多程序出问题的重灾区。传感器零漂、信号波动、接线干扰都会导致模拟量值不稳定。我处理的思路是模拟量原始值通过标准化转换比如0~27648对应0~100%或者对应实际工程值在数据块里保存工程量值不要到处用原始码去比较。重要模拟量信号比如温度、压力做限幅滤波或者滑动平均滤波滤掉高频噪声。滤波的时间常数根据工艺需要来不要太长否则响应变慢也不要太短否则滤波白做。模拟量报警不要只设置一个越限值建议设置报警迟滞hysteresis比如压力低于2.0兆帕报警高于2.3兆帕才复位避免在临界值附近反复报警操作工看了想砸屏。模拟量这块程序能不能写好很直观。5.5 定期做代码走查让团队一起把脉我现在带的项目组每完成一个阶段的程序编写都会组织一次代码走查。不需要搞很正式的评审流程就是几个人坐在一起把关键的程序块从头到尾过一遍互相问问题这个状态什么时候跳变的这个变量还有别的写入点吗这个定时器的PT值如果改到2秒会有什么影响。这个过程往往能发现非常多的隐患。每个人看程序的视角不同逻辑漏洞、命名问题、边界情况往往在走查环节都会浮出水面。代码走查不需要花很多时间但对程序质量的提升比起闷头自己查效率高出太多。6. 实操心得我对好程序的最后几点感受6.1 好程序自己会说话好的程序就像一本排版清楚的书。翻开变量表每个名字都像是设备的零件清单打开程序块每个段落的逻辑都像工艺流程的文字版看到报警目录操作工知道设备在说什么。这样的程序不需要原作者的过多解释就能被后来者接手、理解、维护。我常说一句话如果你写的程序需要另一个人坐在你旁边对着屏幕讲三个小时才能懂那这程序就算不上好。当然这不绝对复杂的工艺肯定需要交流但好的程序能把必须口传心授的部分压缩到最小。6.2 关于运行就知道好的迷思有人可能觉得设备的动作都是正常的那程序肯定没问题。这个思路我非常不认同。程序运行正常只是某一组输入条件下的正常表现不代表程序完整覆盖了所有工况且具备纠错能力。设备故障往往发生在你意想不到的那一个路径上——一个多出来的扫描周期、一个传感器抖动、一个气缸卡在半程、一个人手误操作——真正检验程序质量的是这些边角料工况。所以我特别建议在程序调试结束之前的最后阶段人为地制造一些坏工况看看程序会不会做出合理反应。比如拔掉一个传感器看设备是报警停机还是瞎跑比如让物料在某个位置卡住看看超时判断能不能正常触发比如急停之后看重新启动要不要按固定的复位顺序。这些坏事如果程序都能兜住那才是真的可以交给现场。6.3 工具和技术始终是辅助思维方式才是根本现在的编程软件越来越强大SCL、结构化编程、在线监控、版本对比工具链非常完善。但工具再强大如果脑子里没有程序质量这根弦依然会写出能跑但难维护的程序。写程序的质量意识和思维模式才是根本。核心就是三句话第一总想着别人会怎么读我的程序。第二总想着如果这个信号异常了会怎么样。第三总想着三个月之后我怎么快速想起来这段逻辑的意义。有了这三条很多技术细节都会自然而然地做好。6.4 好的交接是程序的最后一道工序很多项目干到最后交程序就像拷一个文件U盘往桌上一放说一句都试过了没问题就算完成了。但我现在做交接一定会配一份完整的交接文档包括程序架构说明、变量表说明、报警清单、关键参数表、版本历史、备份文件。这看起来是小事但对使用方未来的维护影响比想象中大得多。程序本身再优秀没有交接文档就像一台好设备没有说明书好也发挥不出来。相反哪怕程序有些糙交接文档写得清清楚楚后面的人也能很快上手。7. 最后回到最初的问题PLC程序能运行就算写得好吗答案当然是否定的。能运行只是程序满足了下限要求真正写得好是要在功能满足的前提下做到可读、可维护、可诊断、安全可靠、可扩展顺手还要留足交接空间。我自己的体会是每一次写程序目标都不应该是让设备跑起来而是让设备稳定地跑、让问题容易被找到、让后人能接手、让自己以后不后悔。这句说起来简单做起来需要每一行逻辑、每一个变量名、每一条注释都用心对待。如果这篇文章能在你下次写程序的时候多提醒你一次我这样的写法三个月后我自己看得懂吗我就觉得值了。再啰嗦一句程序不只是写给机器看的更是写给下一个工程师看的。这个下一个工程师很多时候就是我们自己。
返回列表