文章目录

ST预测性维护:在ST中基于运行时长触发保养提醒

发布于 2026-03-19 06:46:46 · 浏览 7 次 · 评论 0 条

ST预测性维护:在ST中基于运行时长触发保养提醒

在工业自动化现场,设备突发停机常源于润滑失效、轴承老化或皮带磨损等可预见问题。传统“定期保养”存在明显缺陷:要么过早更换尚可使用的部件,增加备件成本;要么因周期固定而错过真实劣化节点,导致故障漏检。ST(Structured Text)作为IEC 61131-3标准下的高级文本编程语言,天然适合实现基于真实运行时长的预测性维护逻辑——它不依赖外部数据库或上位系统,直接在PLC内完成计时、阈值判断与状态输出,响应快、可靠性高、部署轻量。

以下为完整实操指南,所有步骤均在标准ST编辑器(如TIA Portal V18、Codesys 3.5或OpenPCS)中验证通过,无需额外库或插件。


一、明确核心需求与变量定义

预测性维护的核心是:当某台电机累计运行时间达到预设阈值(如2000小时),自动触发保养提醒,并锁定后续操作直至人工复位。整个过程必须满足:

  • 运行时间仅在电机处于RUN状态时累加,停机、故障、待机期间暂停;
  • 时间单位统一为“秒”,避免浮点运算误差;
  • 提醒信号为边沿触发(仅在达标瞬间置位1个扫描周期),防止误读;
  • 支持手动复位,且复位后计时继续(非清零),体现“累计寿命”本质;
  • 具备防抖逻辑,避免因启停抖动造成误触发。

据此定义ST全局变量(在VAR_GLOBALVAR块中声明):

// 设备运行状态输入(来自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逻辑代码

将以下代码粘贴至主程序组织块(如OB1MAIN)中。每行逻辑均有明确作用,无冗余分支:

// 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上清晰呈现并支持复位,配置原则如下:

  1. 提醒显示

    • 创建一个标签控件,绑定变量bMaintAlert
    • 设置其文本为"⚠️ 电机保养提醒:累计运行已达2000小时"
    • 仅当bMaintAlert = TRUE时显示该文本(设置可见性表达式为bMaintAlert);
    • 同时添加一个闪烁动画(频率1Hz),强化视觉警示。
  2. 复位按钮

    • 创建按钮控件,动作设为“写入变量”;
    • 目标变量为bResetAlert,写入值为TRUE
    • 必须勾选“脉冲输出”或“单次触发”选项,确保每次点击仅产生1个扫描周期的TRUE,否则会持续复位。
  3. 运行时间监控

    • 添加数值显示控件,绑定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”属性。


五、测试与验证方法

不依赖仿真器,用三步实机验证:

  1. 计时精度验证

    • 断开电机,强制bMotorRun := TRUE
    • 用手机秒表计时60秒,观察dwTotalRunSec增加值是否为60;
    • 若偏差>±2,检查PLC循环周期是否稳定(TIA Portal中查看“诊断缓冲区”→“更新时间”)。
  2. 提醒触发验证

    • 手动修改dwTotalRunSec := 7199999
    • 下载程序,触发一次bMotorRun上升沿(模拟开机);
    • 观察bMaintAlert是否在下一周期变为TRUE
    • 点击HMI复位按钮,确认bMaintAlert归零且bAlerted变为FALSE
  3. 边界压力测试

    • 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检测下降沿复位

九、部署清单(检查项)

在交付前逐项确认:

  • [ ] dwTotalRunSecbAlerted变量均已声明RETAIN
  • [ ] bMotorRun输入已通过R_TRIG去抖;
  • [ ] HMI提醒标签的可见性表达式正确绑定bMaintAlert
  • [ ] 复位按钮属性设为“脉冲输出”;
  • [ ] 阈值常量dwMaintThresholdSec已按实际需求换算为秒(如3000小时 = 10800000);
  • [ ] 代码中无REAL类型参与时间累加运算;
  • [ ] 变量名无中文、空格或特殊字符(符合ST命名规范)。

将此逻辑固化到PLC后,设备真正实现了“用多少时间,就提醒多少次”的精准维护。无需额外硬件、不增加网络负载、不依赖上位软件,所有决策在毫秒级完成。运维人员收到提醒时,看到的不是模糊的“建议检查”,而是确凿的“已连续运行7200000秒”,维护动作自然从被动救火转向主动规划。

评论 (0)

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

扫一扫,手机查看

扫描上方二维码,在手机上查看本文