『7x24小时有问必答』
题目:
今天写一个很像现场调试时才会冒出来的小问题:模拟量突然跳一下,到底是工艺真的变了,还是传感器、接线、模块或者通信出了毛病。
很多现场工程师都有过这种经历:画面上的压力、液位或温度,前一秒还好好的,下一秒忽然跳出一个离谱的值。PLC 如果没有做判断,很可能立刻触发报警、误停机,甚至把执行机构也带着一起乱动。
更麻烦的是,很多跳变不是持续故障,而是偶发尖峰。它可能只持续一个扫描周期,也可能只是某次采样卡了一下。程序如果不区分“真实变化”和“异常突变”,调试时就会很痛苦。
本例用 SCL 写一个模拟量突变检测器。它不负责滤波,也不负责换算,它只做一件事:当前值和上一次可信值相比,如果变化超过允许步长,就立刻判定为突变并锁存报警。
这个功能块很小,但很适合放进标准库里。项目做多了你会发现,真正拖慢调试的,往往不是复杂算法,而是这些看起来不起眼的诊断细节。
设计分析:
模拟量突变检测和普通限幅不是一回事。
限幅是防止数值超出上下限,突变检测是防止数值变化得太快。前者看绝对值,后者看变化量。一个值在上下限之内,也完全可能是异常跳变。
本例把判断拆成四层:
ValueValid:当前模拟量是否可信,来自模块诊断、通信质量码或上游逻辑。
MaxStep:允许的最大单步变化量。比如 100 ms 扫描一次,压力每个周期不可能跳 10 bar,那就应该报警。
HoldMs:稳定保持时间。即便值没有突变,也不要刚恢复就立刻把输出恢复得太快,给现场留一点确认窗口。
JumpAlarm:突变锁存报警。发生一次就保留痕迹,直到人工或程序复位。
如果你的项目是快速过程控制,比如高速闭环或者高速称重,MaxStep 和 HoldMs 不能照搬本文示例,要按采样周期和工艺动态重新算。
创建功能块:
本例创建一个 FB,命名为:
AnalogJumpMonitor
为什么用 FB?
因为突变检测需要记住上一次可信值、是否已经初始化、报警锁存状态和稳定计时,这些都是状态。用 FB 比用 FC 更自然,也更方便复制给每一路模拟量。
定义接口变量:
定义输入变量:
Enable:功能使能。
Reset:报警复位。
CycleMs:调用周期,单位毫秒。
Value:当前模拟量工程值,类型建议用 LReal。
ValueValid:当前值是否可信。
MaxStep:单步允许变化量。
HoldMs:稳定保持时间。
定义输出变量:
OutputValid:当前值是否可信可用。
JumpAlarm:突变报警锁存。
InvalidAlarm:无效值报警锁存。
JumpPulse:本扫描周期检测到一次突变。
DeltaValue:当前值与上次可信值的差值。
StableElapsedMs:连续稳定累计时间。
Stable:当前值是否已经稳定到可以使用。
LastGoodValue:最后一次可信值。
程序代码:
第一部分:
第二部分:
调用方法:
可以建立一个全局 DB,命名为:
GdbAnalogJump
在 DB 中定义 实参变量:
在 OB1 或循环中断 OB 中调用:
一个小例子:
假设液位变送器正常工作时,每 100 ms 变化不超过 0.05 m,而 MaxStep 设为 0.20 m。
正常上升时,RawValue 从 1.20 变到 1.24,再变到 1.28,DeltaValue 一直小于 MaxStep,OutputValid 保持 TRUE,StableElapsedMs 持续累加。
如果某次采样突然从 1.30 跳到 2.10,DeltaValue 就会瞬间超限,JumpPulse 置位,JumpAlarm 锁存,OutputValid 变 FALSE。
后面即使值恢复到 1.32,也不会立刻当作完全正常,直到执行 Reset。这样维护人员能看见“刚才确实跳过”,而不是让报警悄悄消失。
代码测试:
输入平稳变化,确认 OutputValid 为 TRUE,JumpAlarm 不触发,StableElapsedMs 正常累加。
手动制造一次大跳变,确认 JumpPulse 只在一个扫描周期出现,JumpAlarm 被锁存。
跳变后恢复正常值,确认 OutputValid 仍为 FALSE,直到 Reset 才恢复。
把 ValueValid 置 FALSE,确认 InvalidAlarm 触发,StableElapsedMs 清零。
Enable 置 FALSE,确认所有输出和内部状态都回到初始状态。
工程注意事项:
第一,不要把突变检测当成滤波器。
突变检测是发现异常,滤波器是平滑信号。两个功能的目的不同,混在一起以后,调试的人会很难判断到底是信号真变了,还是被你滤掉了。
第二,MaxStep 要结合扫描周期来定。
同样是 0.20 的步长,100 ms 扫描一次和 1 s 扫描一次,意义完全不同。参数不能只看数值,还得看节拍。
第三,报警最好锁存。
偶发尖峰最容易被忽略。你今天把它自动恢复掉,明天现场又会来问:刚才到底是不是有问题?锁存报警至少能留下痕迹。
第四,不要拿一个阈值照顾所有点位。
温度、压力、液位、流量,变化速度本来就不一样。最稳妥的做法,是每一路模拟量单独给参数,或者按设备类型分组配置。
第五,别拿突变检测去替代模块诊断。
如果模拟量模块本身已经报错,程序应该优先信诊断状态,而不是执着地分析一个已经不可信的工程值。
常见问题:
第一,只看原始值,不看 ValueValid。
原始值哪怕掉成一个正常数字,也可能是假的。先看诊断,再看数值,顺序不能反。
第二,报警一旦出现就立刻自动清掉。
这种做法会让维护人员失去故障痕迹。项目如果要自动恢复,也应该先明确写出恢复条件。
第三,把滤波和报警放在同一个 FB 里乱糊一团。
工程里最好把“采集、换算、滤波、诊断、报警”分开。功能边界越清楚,后面越好维护。
第四,所有点位共用一个 MaxStep。
不同设备的物理量变化速度差异很大,共用一个参数往往不是省事,是把风险往后拖。
老炮儿建议:
如果一个项目里有多路模拟量,建议用 UDT 把 RawValue、ValueValid、MaxStep、HoldMs、OutputValid、JumpAlarm 这些字段统一起来,再逐路实例化。
HMI 上最好显示 DeltaValue、LastGoodValue、JumpPulse 和 StableElapsedMs,调试时比只看一个报警灯有用得多。
对关键过程量,突变检测和限幅最好分层:先诊断,再滤波,最后才进入控制算法。
参数表里把每一路的 MaxStep 和 HoldMs 写清楚,别只留一个“模拟量报警”这种大而空的名字。
如果现场经常出现尖峰,先查接线、屏蔽、接地、模块滤波和采样周期,别一上来就靠程序硬扛。
总结:
本例用 SCL 写了一个模拟量突变检测器。
它的核心很简单:先确认数据可信,再比较当前值和上次可信值的变化量;超过允许步长就报警锁存,没超过就继续作为正常值使用。
这个功能不会让 PLC 更“聪明”,但会让程序更诚实。它能把那些一闪而过、最难查的异常值留下痕迹,让调试和维护少走很多弯路。
PLC 程序做到后面,真正值钱的往往不是把数算出来,而是把不该信的数及时拦下来。
实例分享下载:
https://pan.quark.cn/s/6c2c0521c8c6

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码