ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Codesys报警系统实战:REF与ACK机制详解及配置避坑指南

2026/9/21 5:14:19 拓冰建站 浏览量
Codesys报警系统实战:REF与ACK机制详解及配置避坑指南 1. 报警系统在Codesys项目中的真实定位很多人第一次接触Codesys 3.5的报警功能会下意识把它当成一个弹窗提示来用——变量超限了屏幕上跳个红框操作工点一下关掉完事。如果只做到这一步那这套报警系统基本等于白做。我在几个实际交付的项目里踩过最深的坑就是前期把报警当成UI层的装饰后期设备出了故障翻遍历史记录找不到任何有效线索客户追责的时候只能干瞪眼。Codesys的报警配置本质上是一套状态机加事件记录系统。它要解决的核心问题有三个第一什么条件下算报警触发第二报警发生后系统如何记录、如何呈现第三操作人员确认之后报警状态如何流转。这三个问题分别对应了变量定义、报警配置、确认机制三个层面。标题里提到的REF和ACK恰好就是第三层里最容易混淆的两个概念。这篇文章面向的是已经能跑通Codesys基础工程、但对报警系统还停留在能用就行阶段的工程师。我会从变量怎么定义开始讲一路讲到REF和ACK到底差在哪中间穿插我自己调试时踩过的坑。看完之后你应该能做到独立配置一套带确认、带记录、带状态区分的报警系统并且知道每个参数为什么这么填。需要提前说明的是Codesys 3.5的报警功能在不同版本、不同目标设备上界面略有差异但底层逻辑是一致的。我下面讲的配置路径以标准SoftPLC和常见ARM平台为例如果你用的是汇川或者其他品牌的Codesys定制版菜单位置可能不同但概念完全通用。2. 报警变量定义别小看这一步2.1 报警变量和普通变量的本质区别在Codesys里定义报警变量很多人直接拿一个BOOL量就往上挂。这样做在简单场景下没问题但一旦报警数量超过二十个或者需要区分报警等级就会乱成一锅粥。报警变量和普通逻辑变量的区别在于它需要承载状态信息而不仅仅是一个真假值。我习惯把报警变量分成三类来管理。第一类是触发源变量就是实际反映设备状态的BOOL量比如电机过载信号、温度超限信号。第二类是报警状态变量用来记录这条报警当前处于什么阶段——是刚触发、还是已被确认但故障仍在、还是故障已消失但未确认。第三类是汇总变量把所有报警按等级或区域聚合供HMI做总览显示。触发源变量建议统一加前缀比如alm_开头这样在变量列表里一眼就能筛出来。状态变量用almSts_开头。这个命名习惯看起来是小事但当你的工程里有三百个变量、报警占了八十个的时候没有前缀你会疯掉。2.2 变量类型的选择逻辑BOOL量是最基础的报警触发源但实际项目里经常遇到需要模拟量超限报警的情况。这时候有两种做法一种是在PLC逻辑里先做比较把结果写到一个BOOL变量上再挂报警另一种是直接把模拟量挂到报警配置里用上下限来触发。我强烈建议用第一种。原因很简单比较逻辑放在PLC代码里你可以随时加死区、加延时、加回差而且调试的时候能在线监控比较结果。如果直接挂模拟量报警配置里的上下限是静态的改一次要重新下载而且没法做复杂的触发条件。举个实际例子。一个温度报警如果直接用模拟量挂报警设定上限80度那么温度在79.9和80.1之间抖动的时候报警会疯狂闪烁。正确的做法是在PLC里写一段带回差的比较逻辑// 温度报警带5度回差 IF rTemp 80.0 THEN bTempAlarm : TRUE; ELSIF rTemp 75.0 THEN bTempAlarm : FALSE; END_IF这样温度必须降到75度以下报警才会消失避免了临界抖动。这个回差值就是你在报警配置里做不到的。2.3 结构体变量在报警中的应用当报警数量多的时候用结构体来组织会清晰很多。比如定义一个报警状态结构体TYPE ST_AlarmStatus : STRUCT bActive : BOOL; // 报警条件当前是否成立 bAcked : BOOL; // 是否已被确认 bLatched : BOOL; // 是否处于锁存状态 tTrigger : TIME; // 触发时间戳 tAck : TIME; // 确认时间戳 iCode : INT; // 报警代码 END_STRUCT END_TYPE然后为每条报警声明一个这样的结构体实例。这样做的好处是所有报警相关的信息都打包在一起HMI那边只需要读结构体就能拿到全部状态不用去翻一堆散落的变量。而且后面做报警记录、做历史查询的时候结构体数组操作起来非常方便。不过要注意Codesys的报警配置界面里直接挂结构体成员有时候会有兼容性问题。我的做法是结构体归结构体但报警配置里挂的还是独立的BOOL变量结构体只是用来做状态管理和HMI交互。这样两边都不耽误。3. 报警配置的核心参数逐个拆解3.1 报警组的划分策略Codesys的报警配置里第一件事是建报警组。很多人随便建一个组把所有报警都塞进去这是给自己挖坑。报警组的作用是控制报警的显示优先级和确认权限。我的划分习惯是按严重程度分三组故障组、警告组、提示组。故障组是必须立即停机的警告组是需要操作工注意但不影响运行的提示组是记录性质的。这三组在HMI上的显示颜色、是否需要确认、确认密码等级都可以分别设置。还有一种划分方式是按设备区域分比如一号线、二号线。这种方式适合产线很长、操作工只负责自己区域的场景。实际项目里我会把两种方式结合先按严重程度分大类再在大类里按区域分子组。Codesys支持报警组的嵌套用好了层次非常清晰。3.2 触发条件的配置细节在报警配置界面里每条报警需要指定一个触发变量。这里有个容易忽略的点触发变量的扫描周期。如果触发变量是在一个快速任务里更新的而报警配置挂在慢速任务上可能会出现报警漏报的情况。Codesys的报警默认是在指定任务里扫描的。你需要在报警配置的属性里确认它挂在哪个任务下。我的经验是报警扫描任务和触发变量的更新任务保持一致或者报警任务比触发任务更慢但至少快于HMI刷新周期。一般设成10ms到50ms之间比较稳妥。另外触发条件支持表达式而不只是单个变量。比如你可以写bMotorRun AND bOverload这样只有电机在运行且过载信号同时成立时才报警。这个功能很实用但表达式太复杂会影响扫描效率建议控制在三个变量以内。3.3 报警文本和帮助信息的写法报警文本不是随便写几个字就行的。操作工在半夜三点看到一条报警他需要从文本里立刻知道三件事哪里出了问题、可能的原因是什么、现在该做什么。所以我的报警文本格式固定为位置 现象 建议动作。比如一号线主电机过载请检查负载是否卡阻确认后复位。这句话里位置是一号线主电机现象是过载建议动作是检查负载并复位。操作工看完就知道该干嘛不用去翻手册。Codesys的报警配置支持多语言文本如果你的设备要出口记得把英文和中文都填上。帮助信息字段可以填更详细的排查步骤HMI上做一个按钮弹出来显示。这个字段很多人空着其实它是减少售后电话的最有效手段。4. REF和ACK报警确认机制的核心4.1 ACK到底确认了什么ACK是Acknowledge的缩写中文叫确认。它的作用只有一个告诉系统操作工已经看到这条报警了。注意ACK不改变报警的触发条件也不让报警消失。如果故障还在报警依然存在只是状态从未确认变成了已确认。这个区分非常重要。我见过不少项目操作工按了确认按钮报警从屏幕上消失了但设备其实还在故障状态。这是把ACK和复位搞混了。ACK只是心理上的我知道了不是物理上的问题解决了。在Codesys里ACK操作通常通过HMI上的一个按钮触发调用报警确认功能块。确认之后报警的状态字里对应的ACK位会置位。你可以在PLC代码里读这个位来做后续逻辑比如所有报警都已确认且故障已消失才允许重新启动。4.2 REF在报警系统里的角色REF这个词在Codesys报警语境下通常指Reference也就是引用或者关联。它和ACK不是同一层面的概念。ACK是动作REF是关系。具体来说REF在报警系统里有两种常见用法。第一种是报警引用一条报警可以引用另一条报警作为它的触发条件或者关联条件。比如变频器故障这条报警可以引用变频器通讯超时和变频器过流两条子报警只要子报警任意一条触发父报警就触发。这样做的好处是HMI上可以折叠显示操作工先看父报警需要细节再展开子报警。第二种是变量引用报警配置里挂的触发变量实际上是对PLC变量的一个引用。这意味着如果你在PLC代码里改变了这个变量的值报警状态会立即跟着变。这个机制听起来理所当然但实际调试时经常有人困惑为什么我在HMI上改了报警变量PLC里没反应因为HMI改的是HMI本地的副本不是对PLC变量的引用。要改PLC变量必须通过写操作而不是改HMI显示。4.3 ACK和REF的配合使用实际项目里ACK和REF经常配合使用来实现报警锁存。所谓锁存就是报警触发之后即使触发条件消失了报警依然保持在屏幕上直到操作工确认。实现方式是报警触发时置位一个锁存变量ACK操作时如果触发条件已经消失则复位锁存变量如果触发条件还在锁存变量保持但ACK位置位。这样HMI上就能区分三种状态触发未确认红色闪烁、触发已确认红色常亮、已消失未确认黄色闪烁、已消失已确认消失或灰色。Codesys的报警配置里有一个锁存选项勾上之后报警会自动锁存。但自动锁存有时候不够灵活比如你希望某些报警不锁存某些锁存。这时候就需要用PLC代码手动管理锁存变量配合ACK和REF来实现。下面是一个手动管理锁存和确认的示例逻辑// 报警触发与锁存管理 IF bOverload THEN stAlarm.bActive : TRUE; stAlarm.bLatched : TRUE; stAlarm.tTrigger : TIME(); END_IF // 触发条件消失 IF NOT bOverload THEN stAlarm.bActive : FALSE; END_IF // ACK操作 IF bAckButton AND stAlarm.bLatched THEN stAlarm.bAcked : TRUE; stAlarm.tAck : TIME(); // 如果触发条件已消失清除锁存 IF NOT stAlarm.bActive THEN stAlarm.bLatched : FALSE; END_IF END_IF这段代码里bActive反映的是实时触发条件bLatched反映的是报警是否还在屏幕上bAcked反映的是操作工是否确认过。三个状态组合起来就能覆盖所有报警场景。5. 报警记录与历史查询的落地方法5.1 报警记录存到哪里Codesys本身提供报警记录功能但默认的存储方式是在内存里循环缓冲。这意味着断电之后记录就没了。对于需要追溯的设备这显然不够。我的做法是把报警记录写到文件或者数据库里。Codesys支持文件操作功能块可以把报警事件按行追加到CSV文件。每条记录包含时间戳、报警代码、报警文本、触发或消失、确认或未确认。这个CSV文件放在PLC的存储卡或者网络共享目录上HMI做一个历史查询页面来读取。如果设备联网更好的方式是通过OPC UA或者MQTT把报警事件推送到上位机数据库。Codesys 3.5对OPC UA的支持很完善配置好之后报警事件可以实时上传。这样多台设备的数据可以集中管理做统计分析也方便。5.2 历史查询的HMI设计HMI上的历史查询页面我一般做三个筛选条件时间范围、报警等级、确认状态。操作工选好条件点查询下面用表格列出结果。表格列包括时间、代码、文本、状态。这里有个性能上的坑如果报警记录很多一次性读出来会卡死HMI。正确的做法是分页读取每页显示50条翻页的时候再读下一页。Codesys的文件读取功能块支持指定偏移量和长度实现分页不难。另外查询结果要支持导出。操作工或者工程师可以把查询结果导成CSV发给厂家分析。这个功能在售后阶段能省很多事。5.3 报警统计的实用价值除了查询报警统计也很有用。比如统计每条报警在过去一周内触发了多少次、平均确认时间是多少。这些数据能帮你发现哪些报警是频繁误报的哪些报警操作工响应很慢。Codesys本身不做统计但你可以用PLC代码来算。维护一个报警计数数组每次报警触发时对应计数加一。确认时间的话记录触发时间戳和确认时间戳两者相减就是响应时间。这些数据可以定期上传到上位机用Excel或者更专业的工具做分析。我有个项目就是通过报警统计发现某条报警平均每天触发四十多次但每次都是同一个原因——传感器安装位置不对导致误报。调整传感器位置之后报警次数降到每周一两次。如果没有统计这个问题可能永远被当成正常现象。6. 调试阶段最容易踩的五个坑6.1 报警闪烁但抓不到调试时经常遇到报警一闪而过HMI上根本看不清。这通常是触发条件抖动导致的。解决办法是在PLC代码里加延时确认触发条件成立后持续一段时间才真正报警。// 延时报警持续500ms才触发 TON_Alarm(IN : bRawAlarm, PT : T#500MS); bAlarm : TON_Alarm.Q;这个延时时间根据信号特性来定。温度、压力这类慢变量可以设长一点急停、限位这类快变量设短一点或者不设。6.2 确认按钮按了没反应ACK按钮没反应最常见的原因是按钮的变量没有正确关联到报警确认功能。Codesys的报警确认不是自动的你需要在HMI按钮的事件里调用确认功能或者在PLC代码里检测按钮上升沿然后调用确认功能块。另一个原因是报警已经被确认过了再按当然没反应。调试的时候可以在HMI上显示报警的ACK状态位这样一眼就能看出是按钮问题还是状态问题。6.3 报警文本显示乱码中文报警文本乱码通常是字符编码问题。Codesys的报警文本默认可能是ASCII或者Latin-1需要改成UTF-8。在报警配置的文本属性里找编码设置改成UTF-8之后重新下载。如果HMI那边还是乱码检查HMI的字体是否支持中文。6.4 报警记录时间戳不对时间戳不对一般是PLC系统时间没有同步。Codesys的TIME()函数返回的是PLC运行时间不是真实时间。要记录真实时间需要用RTC功能块读取实时时钟或者通过NTP同步网络时间。我的做法是在PLC启动时从HMI或者上位机同步一次时间之后用RTC维持。如果设备联网配置NTP自动同步最省事。6.5 报警数量多了之后性能下降报警数量超过一百条之后如果配置不当PLC扫描周期会明显变长。原因是报警扫描占用了太多CPU时间。解决办法是分组扫描把不重要的报警放在慢速任务里扫描重要的放在快速任务里。另外报警触发条件尽量用简单的BOOL变量少用复杂表达式。还有一个技巧是报警抑制。设备停机的时候很多报警会同时触发这时候可以临时抑制非关键报警只保留最重要的几条。Codesys支持报警抑制功能可以在PLC代码里控制。7. 一套完整报警系统的配置清单把上面讲的内容串起来一套完整的报警系统配置流程是这样的定义变量按alm_前缀定义触发源BOOL变量按almSts_前缀定义状态结构体模拟量报警先在PLC里做带回差的比较。建报警组按严重程度分故障、警告、提示三组组内再按区域分子组。配置报警每条报警挂对应的触发变量填位置加现象加建议动作格式的文本设置扫描任务和锁存选项。实现确认逻辑用PLC代码管理bActive、bLatched、bAcked三个状态HMI按钮触发ACK操作。配置记录报警事件写入CSV文件或上传数据库HMI做分页历史查询。加统计维护报警计数和响应时间数组定期上传分析。调试优化加延时防抖检查编码同步时间分组扫描配置抑制。这套流程我在三个不同行业的项目里用过从包装机到水处理到立体库基本不需要大改。区别只在于报警数量和分组方式核心逻辑是一样的。最后说一个我自己的习惯每次项目交付前我会故意制造几条报警然后走一遍完整的触发、确认、消失、查询流程确认每个环节都正常。这个测试花不了十分钟但能避免现场调试时的手忙脚乱。报警系统这种东西平时没人注意出问题的时候就是救命稻草值得多花点时间把它做扎实。