首页 > 其他分享 >PLC报警消息处理

PLC报警消息处理

时间:2024-04-14 17:33:40浏览次数:16  
标签:AlarmText GetSymbolName 处理 Alarm 报警 PLC HMI size

在TIA Protal中,大致有以下几种方式可以获取报警信息:

  • HMI侧组态报警
  • Program_alarm
  • Prodiag
    第一种方式基本上是最常用和最简单的,基本步骤是先创建报警变量再组态报警文本,由HMI定时去轮询变量,通过监控变量值的变化触发。优点是配置简单,但是效率比较低,工作量比较大(以前项目上我会新建一个报警excel来处理,每次检查报警表的时候就是我头最大的时候,特别是涉及到中英切换报警翻译的时候)。
    第二种方式就是在程序中调用Program_Alarm实现报警推送,PLC中变量值的变化来推送报警消息。好处是处理在PLC侧,所以和HMI的通信负载比较低,另外一方面在PLC侧编程可以一定概率的实现自动化推送,客观降低工作量,增加效率。缺点是对设备有要求,PLC1200就不用想了,它只支持1500;另外报警文本存PLC内部的话其实还是很占PLC数据工作存储器资源的,数据量大了之后PLC可能吃不消(直接导致工作存储器不够用)。
    第三种方式是使用Prodig技术,博图从V14开始就集成了prodiag功能了(它还有很多很好玩的应用,以后我可能单开一篇来写),这种技术极大的提升了编程效率,但是呢,依旧只支持1500。
    所以1200的用户,还是老老实实用第一种方法吧。

1. HMI侧组态报警
以前我遇到很多非标项目,小项目很多人喜欢一个报警条目占用一个bool。最后传给HMI侧的时候HMI变量表里面就传了一大堆bool量的报警信息,这是非常占用HMI的Tag点位的。所以我这里用word来表示最多16条报警(为什么可以这么做,自己体会一下),这样的好处一是报警集中(毕竟一个或者多个word可以单独组合某一个设备单元的报警集合),二是传一个word给HMI只会被看作一个Tag,但是信息量1:16,简直遥遥领先..
废话不多说,开始演示吧。

  • 自己做一个Bool2Word的块,目的是收集在程序里做的报警
#FB_BoolToWord_Instance_Alarm1(In_Alarm00 := "_HolderLoadStation".HoistCylinder.Error_Initial,
                                   In_Alarm01 := "_HolderLoadStation".HoistCylinder.Error_Target,
                                   In_Alarm02 := "_HolderLoadStation".HoistCylinder.Error_Pg,
                                   In_Alarm03 := "_HolderLoadStation".GripCylinder.Error_Initial,
                                   In_Alarm04 := "_HolderLoadStation".GripCylinder.Error_Target,
                                   In_Alarm05 := "_HolderLoadStation".GripCylinder.Error_Pg,
                                   In_Alarm06 := FALSE,
                                   In_Alarm07 := FALSE,
                                   In_Alarm08 := FALSE,
                                   In_Alarm09 := FALSE,
                                   In_Alarm10 := FALSE,
                                   In_Alarm11 := FALSE,
                                   In_Alarm12 := FALSE,
                                   In_Alarm13 := FALSE,
                                   In_Alarm14 := FALSE,
                                   In_Alarm15 := FALSE,
                                   Out_Alarm => "_AlarmDB".HolderLoadStationAlarm1);

.这是外部管脚,具体报警怎么来的取决于你报警逻辑怎么写的

REGION 输入映射
    #Alarm.%X0 := #In_Alarm00;
    #Alarm.%X1 := #In_Alarm01;
    #Alarm.%X2 := #In_Alarm02;
    #Alarm.%X3 := #In_Alarm03;
    #Alarm.%X4 := #In_Alarm04;
    #Alarm.%X5 := #In_Alarm05;
    #Alarm.%X6 := #In_Alarm06;
    #Alarm.%X7 := #In_Alarm07;
    #Alarm.%X8 := #In_Alarm08;
    #Alarm.%X9 := #In_Alarm09;
    #Alarm.%X10 := #In_Alarm10;
    #Alarm.%X11 := #In_Alarm11;
    #Alarm.%X12 := #In_Alarm12;
    #Alarm.%X13 := #In_Alarm13;
    #Alarm.%X14 := #In_Alarm14;
    #Alarm.%X15 := #In_Alarm15;
END_REGION

.这是内部程序,为了直观,我把报警一个一个赋值给了Word对应的bit.
.其实有一种叫做AT的指令,可以在变量定义的时候直接把Array[0..15] of bool映射给一个Word。这样可以做到零代码映射,但是对FB有要求(FB不能被优化,想想为什么),感兴趣的朋友可以去玩一下。

完事之后再去HMI的HMI报警里面,把你定义好的报警文本和报警变量对应上,Ctrl+C/Ctrl+V吧。

.报警文本自己手动定义。你写个Hello World都行
.报警类别需要定义,不同的报警类别在HMI的报警控件中有不一样的处理显示规则
.触发变量和触发位配合使用,一个Word有16个位
触发器地址根据你的触发变量和触发位自动填入。

最后去画面上做出你的报警控件来,HMI选择报警视图。拽到画面上就OK。

.在HMI里面,选择记录,再选择报警记录,新增一个报警日志,设置名字记录数存储位置。然后你就得到一个历史记录报警。
.选中报警视图当前报警状态,然后你就得到一个实时报警记录。

  • 至此,第一种方法就已经实现了,但是在开始第二种方法之前我对一种方法做了一个更深的探索,用来提高我写报警文本的效率(甚至可以说我压根就不想手动写报警文本)。
    这里依旧简单记录一下:
    我在上面的Bool2Word块里面加了一坨新的程序段,如下:
REGION 数值变化记忆
    // Statement section REGION
    IF #In_FirstScan THEN
        #AlarmMemory := #Alarm;
    END_IF;
    #plus(CLK:=(#AlarmMemory<>#Alarm));
    IF #plus.Q THEN
        #ValueChange := TRUE;
        #AlarmMemory := #Alarm;
    END_IF;
END_REGION

REGION 读取变量符号名做为报警文本
    // Statement section REGION
   IF #In_FirstScan OR TRUE = #ValueChange THEN
        #AlarmText[0] := GetSymbolName(variable := #In_Alarm00, size := 0);
        #AlarmText[1] := GetSymbolName(variable := #In_Alarm01, size := 0);
        #AlarmText[2] := GetSymbolName(variable := #In_Alarm02, size := 0);
        #AlarmText[3] := GetSymbolName(variable := #In_Alarm03, size := 0);
        #AlarmText[4] := GetSymbolName(variable := #In_Alarm04, size := 0);
        #AlarmText[5] := GetSymbolName(variable := #In_Alarm05, size := 0);
        #AlarmText[6] := GetSymbolName(variable := #In_Alarm06, size := 0);
        #AlarmText[7] := GetSymbolName(variable := #In_Alarm07, size := 0);
        #AlarmText[8] := GetSymbolName(variable := #In_Alarm08, size := 0);
        #AlarmText[9] := GetSymbolName(variable := #In_Alarm09, size := 0);
        #AlarmText[10] := GetSymbolName(variable := #In_Alarm10, size := 0);
        #AlarmText[11] := GetSymbolName(variable := #In_Alarm11, size := 0);
        #AlarmText[12] := GetSymbolName(variable := #In_Alarm12, size := 0);
        #AlarmText[13] := GetSymbolName(variable := #In_Alarm13, size := 0);
        #AlarmText[14] := GetSymbolName(variable := #In_Alarm14, size := 0);
        #AlarmText[15] := GetSymbolName(variable := #In_Alarm15, size := 0);
        #ValueChange := FALSE;
    END_IF;
END_REGION

.GetSymbolName具体怎么用,可以按Ctrl+F1,博图帮助系统会告诉你答案。

把你In_Alarm所连接的变量符号名改成的报警文本内容(你可以选择在DB内建Struct或者引用UDT,让你的符号名更有层级)。如图:

现在回到HMI侧,在HMI变量表新建你的AlarmDB_WordAlarmDB_Text(就是在PLC程序里面建立的报警字和对应报警文本数组,数组格式我定义成Array[0..15] of WString[60]);
找到你想处理的AlarmDB_Word对应的离散量报警,在对应报警文本的地方,先双击进入文本编辑框内,再右键,选择插入变量域,弹出过程子窗体,选择需要连接的变量,最后确认。如图:

.当然你也可以选连接文本列表,这又是其他玩法了,感兴趣可以玩一玩。

至此,我们就实现了用符号名来代替我们要手动键入的报警文本,是不是很神奇。
但是你反过头来再来想想,这个柔性报警有什么缺点:还记得我使用了GetSymbolName吗,最后输出要求的格式是WSTRING,这是个什么概念我们来算一算,一个string[60]占用62个byte长度。那么一个WString[60]就要占用124个byte长度,我们一个报警word一共产生了Array[0..15] of WString[60]也就是124*16=1984个byte,接近2KB,如果多用几个就更多了,回头看一下我们的PLC数据存储器才多大,我用的1215也就125KB工作寄存器(代码+数据)。

上面的题外话说多了,那么下面我们接着做Program_Alram。

2. Program_Alarm
这个操作方法比较简单,简单描述就行。

  • 如图,在FB里面建立一个(或多个)和报警相关的参数

  • 在FB代码编辑界面引用Program_Alarm

//增加报警块
#Program_Alarm(SIG:=#statAlarm.trigger,
               TIMESTAMP:=_ldt_in_,
               SD_1:=#statAlarm.text,
               SD_2:=_variant_in_,
               SD_3:=_variant_in_,
               SD_4:=_variant_in_,
               SD_5:=_variant_in_,
               SD_6:=_variant_in_,
               SD_7:=_variant_in_,
               SD_8:=_variant_in_,
               SD_9:=_variant_in_,
               SD_10:=_variant_in_,
               Error=>_bool_out_,
               Status=>_word_out_);

.我只简单填写了trigger和一个报警text,其他更多的信息可以按Ctrl+F1获取博图帮助。

.在PLC的PLC监控的报警中选择报警,填入报警文本(这是HMI弹出报警页面的的报警内容),填入信息文本(这是点入报警文本之后的详细帮助信息。)
.在HMI上拖拽一个报警视图出来,把确认信息和这里的对应好

就这么简单就可以自动生成一个Program_alarm了,记得要去HMI侧拖一个报警视图出来并选择相关确认信息,这一步工作还是要做的。
它的问题还是会占用一部分数据寄存器的内存,但是当我们使用1500的时候,就算1511应该也是1MB的工作寄存器起步了,所以影响应该还好。
再次提醒,这个块仅支持1500。

3. Prodiag

  • prodiag的基本使用方法其实很容易,这里先对基本使用做一个简易过程描述。

在1500的PLC里面,对你想使用的的变量右键(不一定非的是DB,对于FB的基本数据类型IO等等一样可以右键),我这里在FB里面新建了一个静态变量。如图:

.新建后,右边监控列会出现一个监控的小图标,如图不想监控了,右键这个小图标选择删除就行。

点完后的界面如下:

.监控类型可以选择操作数互锁动作,还有一些其他的。(比如当你选择互锁之后,就会多出一个条件让你填写),我们就拿操作数为例,右边可以选择触发器,下面可以选择延时监控类别,等等很多,有兴趣可以自己玩一玩。
.报警文本的格式是
<类别> : <监控类型> : <ProDiag FB 的名称> : <监控 ID> : <实例名称> : <参数名称> : <变量地址> : <变量名称> : <变量注释>,注意,这意味着它甚至可以把你的变量符号变量地址变量注释当作报警文本的一部分输出出来。
.详细文本域用来帮你添加你想添加的详细文本内容。

做完上面的之后,我们的选择触发器是FALSE,意味着当该变量为假的时候PLC就会给HMI推送一条报警信息,这甚至不需要去HMI界面做任何的配置。因为它的技术是PLC推送技术,不需要HMI去轮询或者监控的。

  • 在一些稍微大一点的项目中,可能会专门建立一个Prodiag_FB来做专门的监控管理。

在这种情况下,监控内容就具有了更多的结构化属性,也更利于程序分类。
如下:

.选择添加新块,语言选择PRODIAG(含IDB),就可以建立一个ProdiagFB,图是建立完成并监控了一个数据后的样子。
.具体什么时候该建立什么样的监控PRODIAG(含IDB),监控的内容应该是什么,监控类别的分类应该怎么划分。这就是项目上用来做结构化和标准化分类所需要考虑的了,这里就不详细谈论了。

4. 总结
虽然笔者对西门子PLC报警应用的总结虽然就到这了,但技术在不断的发展和更新,很多新技术值得去尝试,还需要不断的去学习总结才行。

标签:AlarmText,GetSymbolName,处理,Alarm,报警,PLC,HMI,size
From: https://www.cnblogs.com/xiacuncun/p/18134237

相关文章

  • ETL工具-nifi干货系列 第十一讲 处理器UpdateAttribute使用教程
    1、在这里我们重温下nifi里面一个重要的概念FlowFile,如下图所示:FlowFile:FlowFile代表NiFi中的单个数据。nifi数据流中流动的就是flowfile,每个nifi处理器处理的数据也是基于flowfile的。FlowFile由两个组件组成:FlowFile属性(attribute)和FlowFile内容(content)。内容是FlowFile......
  • 项目中统一处理请求中的字符串参数的空格
    测试controller@RestController@RequestMapping("/test")@Slf4jpublicclassTestController{@GetMapping("/testStringParamTrim")publicTestObjectInfotestStringParamTrim(@RequestParamStringgoodsId,StringgoodsName){......
  • 本地升级idea后,不能向github上提交代码问题处理
    问题现象:本人自己电脑之前一直使用idea2018.1商业破解版,之前有简历本地代码仓库,并在github上建立了关联的远程代码仓库。最近本人在本地升级一下idea,从idea2018.1商业版升级到2023.1.5社区版本(idea支持win7的版本基本就到2023.1这个版本了,目前本人尝试安装了2023.1.5和2023.1.3......
  • 在Linux中,如何编写脚本处理命令行参数?
    在Linux中,编写脚本处理命令行参数是编写shell脚本的基本功之一。命令行参数是用户在执行脚本时附加在命令行上的额外信息,这对于增加脚本的灵活性和复用性至关重要。以下是如何在bashshell脚本中处理命令行参数的几种常见方法:1.位置参数bash提供了一系列特殊变量$0至$9用于......
  • js处理大数(超过16位的数字):big-init、bignumber.js
    bigints支持JSON.parse/stringify解析方式。基于DouglasCrockford的JSON.js包和bignumber.js库。本地Bigint最近被添加到JS中,所以我们增加了一个选项来代替bignumber.js。但是,使用本机BigInt进行解析是为了向后兼容虽然大多数JSON解析器假设数值具有与IEEE754double相同的精......
  • Linux架构29 ansible playbook任务标签, 复用文件, 忽略错误, 错误处理
    四、playbook任务标签1.标签的作用默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务,Ansible的标签(tag)功能可以给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务。2.打标签的方式1.对一个tas......
  • 简单处理——FPGA实现图像中心差分变换
    简单处理——FPGA实现图像中心差分变换一、图像中心差分变换算法简介​ 差分图像就是目标场景在连续时间内图像相减所构成的图像,对图像进行中心差分变换的主要目的是计算图像中心每个像素点的梯度,而每个像素点的梯度在图像处理中就可以被用于描述图像中灰度变化的快慢和方向。......
  • Rust教程 – 学习天文图像的多尺度处理
    最近,人们投入了大量精力开发新颖的图像处理技术。其中许多技术都源自于傅里叶和小波变换等数字信号处理方法。这些技术不仅使得各种图像处理技术如降噪、锐化和动态范围扩展成为可能,而且还使得计算机视觉中使用的许多技术如边缘检测、目标检测等成为可能。多尺度分析是相对较新......
  • G2D图像处理硬件调用和测试-基于米尔-全志T113-i开发板
    本篇测评由电子工程世界的优秀测评者“jf_99374259”提供。本文将介绍基于米尔电子MYD-YT113i开发板的G2D图像处理硬件调用和测试。 MYC-YT113i核心板及开发板真正的国产核心板,100%国产物料认证国产T113-i处理器配备2*[email protected],RISC-V外置DDR3接口、支持视频......
  • C++编译器对溢出的默认处理
    C++编译器对溢出的默认处理在算数运算中,有一个比较头疼又必须要处理的事情:“溢出”,当我们有所疏忽,没有对溢出的情况做处理时,在我们不知情下就会产生很诡异的bug!那么当我们没有做溢出处理时,编译器的默认处理方式是什么呢?下面我们探究一下这个问题。测试环境Linux4.15.0#16.0......