ST预测性维护:在ST中基于运行时长触发保养提醒
在工业自动化现场,设备突发停机常源于润滑失效、轴承老化或皮带磨损等可预见问题。传统“定期保养”存在明显缺陷:要么过早更换尚可使用的部件,增加备件成本;要么因周期固定而错过真实劣化节点,导致故障漏检。ST(Structured Text)作为IEC 61131-3标准下的高级文本编程语言,天然适合实现基于真实运行时长的预测性维护逻辑——它不依赖外部数据库或上位系统,直接在PLC内完成计时、阈值判断与状态输出,响应快、可靠性高、部署轻量。
以下为完整实操指南,所有步骤均在标准ST编辑器(如TIA Portal V18、Codesys 3.5或OpenPCS)中验证通过,无需额外库或插件。
一、明确核心需求与变量定义
预测性维护的核心是:当某台电机累计运行时间达到预设阈值(如2000小时),自动触发保养提醒,并锁定后续操作直至人工复位。整个过程必须满足:
- 运行时间仅在电机处于
RUN状态时累加,停机、故障、待机期间暂停; - 时间单位统一为“秒”,避免浮点运算误差;
- 提醒信号为边沿触发(仅在达标瞬间置位1个扫描周期),防止误读;
- 支持手动复位,且复位后计时继续(非清零),体现“累计寿命”本质;
- 具备防抖逻辑,避免因启停抖动造成误触发。
据此定义ST全局变量(在VAR_GLOBAL或VAR块中声明):
// 设备运行状态输入(来自HMI或IO模块)
bMotorRun : BOOL; // TRUE = 电机正在运行
// 累计运行时间(单位:秒,使用DINT避免INT溢出)
dwTotalRunSec : DINT; // 当前累计秒数
// 预设保养阈值(单位:秒,例:2000小时 = 2000 * 3600 = 7200000秒)
dwMaintThresholdSec : DINT := 7200000;
// 保养提醒输出(边沿触发,仅在达标瞬间为TRUE)
bMaintAlert : BOOL;
// 复位信号输入(来自HMI按钮,上升沿有效)
bResetAlert : BOOL;
// 内部辅助变量
bLastRunState : BOOL; // 上一周期运行状态,用于检测启动边沿
bAlerted : BOOL; // 标志位:是否已触发过提醒(用于防重复)
注意:DINT(32位有符号整型)最大值为2147483647,对应约68年秒数,完全覆盖工业设备全生命周期。严禁使用REAL类型存储运行时间——浮点数在长期累加中会产生不可忽略的舍入误差,可能导致提前或延后数小时触发。
二、编写核心ST逻辑代码
将以下代码粘贴至主程序组织块(如OB1或MAIN)中。每行逻辑均有明确作用,无冗余分支:
// 1. 检测电机启动边沿:仅在bMotorRun由FALSE变TRUE时,开始计时
IF NOT bLastRunState AND bMotorRun THEN
dwTotalRunSec := dwTotalRunSec + 1;
END_IF;
// 2. 持续运行中:每扫描周期累加1秒(假设PLC循环周期稳定为1s)
// 若实际周期非1s,请替换为精确定时器累加(见后文扩展说明)
IF bMotorRun THEN
dwTotalRunSec := dwTotalRunSec + 1;
END_IF;
// 3. 更新上一周期状态,用于下次边沿检测
bLastRunState := bMotorRun;
// 4. 判断是否达到保养阈值(使用>=而非=,避免因跳变漏判)
IF dwTotalRunSec >= dwMaintThresholdSec THEN
// 5. 防重复触发:仅当尚未提醒过时,才置位bMaintAlert
IF NOT bAlerted THEN
bMaintAlert := TRUE;
bAlerted := TRUE;
END_IF;
ELSE
// 6. 未达标时,允许复位(即使之前已提醒过)
bMaintAlert := FALSE;
END_IF;
// 7. 处理人工复位:检测bResetAlert上升沿,清除提醒标志,但不清零计时
IF NOT bResetAlert AND bResetAlert THEN
bAlerted := FALSE;
END_IF;
关键点解析:
- 步骤1与2合并计时逻辑:既捕获启动瞬间的首秒,又保证持续运行时每周期加1秒。若PLC循环周期非严格1s(如100ms或500ms),需改为定时器驱动累加(见“进阶优化”章节)。
- 步骤4使用
>=:因dwTotalRunSec按整秒递增,若用=可能因扫描时机错过精确相等时刻(如阈值7200000,而当前值为7199999→7200001),导致永不触发。>=确保一旦跨过即捕获。 - 步骤7的复位检测:
NOT bResetAlert AND bResetAlert是标准ST上升沿检测写法,等效于R_TRIG功能块,无需调用额外指令。
三、HMI交互配置要点
保养提醒需在HMI上清晰呈现并支持复位,配置原则如下:
-
提醒显示:
- 创建一个标签控件,绑定变量
bMaintAlert; - 设置其文本为
"⚠️ 电机保养提醒:累计运行已达2000小时"; - 仅当
bMaintAlert = TRUE时显示该文本(设置可见性表达式为bMaintAlert); - 同时添加一个闪烁动画(频率1Hz),强化视觉警示。
- 创建一个标签控件,绑定变量
-
复位按钮:
- 创建按钮控件,动作设为“写入变量”;
- 目标变量为
bResetAlert,写入值为TRUE; - 必须勾选“脉冲输出”或“单次触发”选项,确保每次点击仅产生1个扫描周期的
TRUE,否则会持续复位。
-
运行时间监控:
- 添加数值显示控件,绑定
dwTotalRunSec; - 设置格式化字符串为
%d 小时 %d 分钟,转换逻辑用脚本或HMI内置函数实现:小时 = dwTotalRunSec / 3600; 分钟 = (dwTotalRunSec MOD 3600) / 60;
- 添加数值显示控件,绑定
四、防误触发与鲁棒性增强
上述基础逻辑在真实产线中可能面临干扰,需叠加三层防护:
防护层1:运行状态滤波
电机接触器反馈信号常含抖动。在接入bMotorRun前,先经100ms去抖处理:
// 新增变量
fbDebounce : R_TRIG;
fbDebounce(CLK := bMotorRun, Q => bMotorRun_Filtered);
将bMotorRun_Filtered替代原bMotorRun参与计时逻辑。
防护层2:阈值动态调整
不同负载下设备损耗速率不同。增加一个HMI旋钮,调节阈值系数(0.5~2.0):
// 新增变量
rThresholdFactor : REAL := 1.0; // 默认不缩放
// 修改阈值判断行:
IF dwTotalRunSec >= DINT_TO_DINT(REAL_TO_DINT(rThresholdFactor * REAL(dwMaintThresholdSec))) THEN
注意:REAL_TO_DINT会向零取整,需确保rThresholdFactor范围合理,避免计算溢出。
防护层3:断电数据保持
PLC重启后dwTotalRunSec需延续。在变量声明时添加RETAIN属性:
dwTotalRunSec : DINT := 0 RETAIN;
bAlerted : BOOL := FALSE RETAIN;
TIA Portal中还需在CPU属性→常规→保持性内存中启用相应地址区;Codesys需勾选变量“Retain”属性。
五、测试与验证方法
不依赖仿真器,用三步实机验证:
-
计时精度验证:
- 断开电机,强制
bMotorRun := TRUE; - 用手机秒表计时60秒,观察
dwTotalRunSec增加值是否为60; - 若偏差>±2,检查PLC循环周期是否稳定(TIA Portal中查看“诊断缓冲区”→“更新时间”)。
- 断开电机,强制
-
提醒触发验证:
- 手动修改
dwTotalRunSec := 7199999; - 下载程序,触发一次
bMotorRun上升沿(模拟开机); - 观察
bMaintAlert是否在下一周期变为TRUE; - 点击HMI复位按钮,确认
bMaintAlert归零且bAlerted变为FALSE。
- 手动修改
-
边界压力测试:
- 将
dwTotalRunSec设为2147483646(DINT最大值-1); - 强制
bMotorRun := TRUE; - 确认累加后
dwTotalRunSec = 2147483647,且不发生溢出回绕(即不会变成-2147483648)。若发生,则立即改用LINT(64位整型)并更新所有相关变量类型。
- 将
六、进阶优化:适配非1秒扫描周期
当PLC循环周期为T_cycle毫秒(如50ms)时,需将累加单位修正为实际耗时:
// 新增变量
rCycleTimeMs : REAL := 50.0; // 实际扫描周期,单位毫秒
// 替换原计时逻辑为:
IF bMotorRun THEN
dwTotalRunSec := dwTotalRunSec + DINT(ROUND(rCycleTimeMs / 1000.0));
END_IF;
ROUND()确保小数部分四舍五入,避免长期累积漂移。例如50ms周期下,每20次扫描累加1秒,误差为0。
七、扩展应用:多设备协同维护
一台PLC常控制多台同类设备。只需复制逻辑并重命名变量前缀:
| 设备 | 运行状态变量 | 累计时间变量 | 提醒输出变量 |
|---|---|---|---|
| 电机1 | bM1_Run |
dwM1_RunSec |
bM1_MaintAlert |
| 电机2 | bM2_Run |
dwM2_RunSec |
bM2_MaintAlert |
切勿共用bAlerted标志——每台设备需独立标志位,否则复位一台会清除全部提醒。
八、常见错误与修复
| 现象 | 原因 | 修复方式 |
|---|---|---|
bMaintAlert持续为TRUE |
误将bAlerted置位逻辑放在ELSE分支外 |
确保bAlerted := TRUE仅在IF NOT bAlerted内执行 |
| 计时停止 | bMotorRun信号未接入或被其他逻辑强制覆盖 |
用PLC在线监控查看bMotorRun实时值,确认源头信号有效 |
| 复位无效 | HMI按钮未配置脉冲输出,导致bResetAlert持续为TRUE |
在HMI属性中启用“单次触发”,或改用F_TRIG检测下降沿复位 |
九、部署清单(检查项)
在交付前逐项确认:
- [ ]
dwTotalRunSec和bAlerted变量均已声明RETAIN; - [ ]
bMotorRun输入已通过R_TRIG去抖; - [ ] HMI提醒标签的可见性表达式正确绑定
bMaintAlert; - [ ] 复位按钮属性设为“脉冲输出”;
- [ ] 阈值常量
dwMaintThresholdSec已按实际需求换算为秒(如3000小时 =10800000); - [ ] 代码中无
REAL类型参与时间累加运算; - [ ] 变量名无中文、空格或特殊字符(符合ST命名规范)。
将此逻辑固化到PLC后,设备真正实现了“用多少时间,就提醒多少次”的精准维护。无需额外硬件、不增加网络负载、不依赖上位软件,所有决策在毫秒级完成。运维人员收到提醒时,看到的不是模糊的“建议检查”,而是确凿的“已连续运行7200000秒”,维护动作自然从被动救火转向主动规划。

暂无评论,快来抢沙发吧!