文章目录
- 前言
- 一、功能概述
- 二、程序编写
- 1. 需求分析
- 2. 编写运行时间累计功能块
- 3. 创建自定义数据类型
- 1. 时间排序数据类型
- 2. 多备多投数据类型
- 3. 多备多投切换数据类型
- 4. 编程
- 1. 创建DB数据块
- 1. 多备多投数据块
- 2. 多备多投切换数据块
- 2. 创建FB功能块
- 三、程序调用
- 总结
前言
在之前的文章中,我们讨论了通过SCL语言实现电机主备互投《西门子PLC常用底层逻辑块分享_电机主备互投》,和多台电机按时间排序均衡运行《电机主备互投功能优化_多台设备均衡运行》的方法。
但实际现场中,经常会遇见4用1备、3用2备、2用2备、2用3备等复杂情况,如果对每种情况分别编程,会使程序过于冗杂,故本文提供一种多备多投的实现方法,假设现场有5台水泵,可根据现场要求,自由选择主动泵数量和备用泵数量,实现主备泵自由切换。
一、功能概述
假设有5台水泵,5台水泵的运行逻辑如下:
- 具有以下几种情况:4用1备、2用2备、2用3备、3用2备、1用1备、1用4备等任意组合;
- 主泵同时启动,触发切换命令后,按照运行时间由小到大的顺序切换备用泵或主泵;
- 每台水泵都有故障信号,当某台泵出现故障或运行信号丢失时,能自动切换到其它泵;
- 故障出现后,水泵的运行时间需要保持不变,不能丢失;
- 每台水泵有3种状态:1. 作为主泵;2. 作为备用泵;3. 不投用;
- 有故障的水泵自动停止,并且不允许启动,直到故障解除;
- 可选择投用或不投用“多备多投”功能。
二、程序编写
1. 需求分析
- 参考文章《电机主备互投功能优化_多台设备均衡运行》的思路,根据5台电机的运行时间,计算出由小到大对应的序号,遍历1-5,每次启动都启动序号1对应的电机;
- 当水泵处于故障状态、不投用状态、运行状态时,可将该水泵的运行时间设置为最大值,即可跳过该水泵,启动下一台。
2. 编写运行时间累计功能块
可参考文章西门子PLC常用底层逻辑块分享_设备运行时间统计。
根据该文章可编写FC块“运行时间累计”,并新建数据类型“时钟”。具体步骤这里不再赘述。
3. 创建自定义数据类型
1. 时间排序数据类型
图1
2. 多备多投数据类型
图2
3. 多备多投切换数据类型
图3
4. 编程
1. 创建DB数据块
1. 多备多投数据块
图4
2. 多备多投切换数据块
图5
2. 创建FB功能块
新建FB块“水泵多备多投”,添加如下变量。
图6
编写如下程序:
REGION 功能已启用、已停止IF #PumpSwitch.StaCmd THEN#PumpSwitch.Running := 1;ELSIF#PumpSwitch.StpCmd THEN#PumpSwitch.Running := 0;END_IF;END_REGIONREGION 调用程序"运行时间累计"(Start := #PumpControl[1].Run,Clock_1Hz := #Clock_1Hz,"Time" := #PumpControl[1].RunTime);"运行时间累计"(Start := #PumpControl[2].Run,Clock_1Hz := #Clock_1Hz,"Time" := #PumpControl[2].RunTime);"运行时间累计"(Start := #PumpControl[3].Run,Clock_1Hz := #Clock_1Hz,"Time" := #PumpControl[3].RunTime);"运行时间累计"(Start := #PumpControl[4].Run,Clock_1Hz := #Clock_1Hz,"Time" := #PumpControl[4].RunTime);"运行时间累计"(Start := #PumpControl[5].Run,Clock_1Hz := #Clock_1Hz,"Time" := #PumpControl[5].RunTime);END_REGIONREGION 计算运行时间FOR #PumpSwitch.N[0] := 1 TO 5 DO#PumpSwitch.Set[#PumpSwitch.N[0]]."Time" :=#PumpControl[#PumpSwitch.N[0]].RunTime.Day * 86400 +#PumpControl[#PumpSwitch.N[0]].RunTime.Hour * 60 * 60 +#PumpControl[#PumpSwitch.N[0]].RunTime.Min * 60 +#PumpControl[#PumpSwitch.N[0]].RunTime.Second; // 程序判断用时间#PumpSwitch.TimeOut[#PumpSwitch.N[0]] := #PumpSwitch.Set[#PumpSwitch.N[0]]."Time"; // 实际显示时间END_FOR;END_REGIONREGION 计算主泵、备泵、运行泵数量#NumMinPump := 0;FOR #PumpSwitch.N[1] := 1 TO 5 DOIF #PumpControl[#PumpSwitch.N[1]].ControlWord = 1 THEN#NumMinPump := #NumMinPump + 1;END_IF;END_FOR;#PumpSwitch.NumMinPump := #NumMinPump; // 计算主泵数量#NumBackupPump := 0;FOR #PumpSwitch.N[2] := 1 TO 5 DOIF #PumpControl[#PumpSwitch.N[2]].ControlWord = 2 THEN#NumBackupPump := #NumBackupPump + 1;END_IF;END_FOR;#PumpSwitch.NumBackupPump := #NumBackupPump; // 计算备泵数量#NumRun := 0;FOR #PumpSwitch.N[3] := 1 TO 5 DOIF #PumpControl[#PumpSwitch.N[3]].Run THEN#NumRun := #NumRun + 1;END_IF;END_FOR;REGION 泵切换命令IF #NumRun < #PumpSwitch.#NumRun THEN#SwitchPump := 1;ELSE#SwitchPump := 0;END_IF;#SwitchPumpR_TRIG(CLK := #SwitchPump); // 如果此刻运行泵数量小于上一时刻运行泵数量,则说明有泵停机,触发泵切换信号END_REGION#PumpSwitch.#NumRun := #NumRun; // 计算运行泵数量REGION 运行泵数量不足报警IF (#PumpSwitch.#NumRun < #PumpSwitch.NumMinPump) AND #PumpSwitch.Running THEN#PumpSwitch.NumFlt := 1;ELSE#PumpSwitch.NumFlt := 0;END_IF;END_REGIONEND_REGIONREGION 无设备运行时,复位启动命令IF #PumpSwitch.#NumRun = 0 THENFOR #PumpSwitch.N[6] := 1 TO 5 DO#PumpSwitch.Pump[#PumpSwitch.N[6]] := 0;END_FOR;END_IF;END_REGIONREGION 故障停机FOR #PumpSwitch.N[12] := 1 TO 5 DOIF #PumpControl[#PumpSwitch.N[12]].Flt OR(#PumpControl[#PumpSwitch.N[12]].ControlWord = 3)THEN#PumpSwitch.Pump[#PumpSwitch.N[12]] := 0;END_IF;END_FOR;END_REGIONREGION 按时间顺序计算序号REGION 故障处理FOR #PumpSwitch.N[8] := 1 TO 5 DOIF #PumpControl[#PumpSwitch.N[8]].Flt OR(#PumpControl[#PumpSwitch.N[8]].ControlWord = 3) OR#PumpControl[#PumpSwitch.N[8]].RunTHEN#PumpSwitch.Set[#PumpSwitch.N[8]]."Time" := 4294967295; // UDInt的最大值为4294967295END_IF;END_FOR; // 将故障泵和没有投用和正在运行的泵时间设为最大值END_REGION// 初始化序号数组FOR #PumpSwitch.I := 1 TO 5 DO#PumpSwitch.Set[#PumpSwitch.I].Sequence := 1; // 初始序号为1END_FOR;// 计算每个元素的序号FOR #PumpSwitch.I := 1 TO 5 DOFOR #PumpSwitch.J := 1 TO 5 DOIF #PumpSwitch.Set[#PumpSwitch.J]."Time" < #PumpSwitch.Set[#PumpSwitch.I]."Time" THEN#PumpSwitch.Set[#PumpSwitch.I].Sequence := #PumpSwitch.Set[#PumpSwitch.I].Sequence + 1; // 遇到更小的数,序号增加ELSIF(#PumpSwitch.Set[#PumpSwitch.J]."Time" = #PumpSwitch.Set[#PumpSwitch.I]."Time") AND (#PumpSwitch.J < #PumpSwitch.I) THEN#PumpSwitch.Set[#PumpSwitch.I].Sequence := #PumpSwitch.Set[#PumpSwitch.I].Sequence + 1; // 处理相同数值的情况,按顺序递增序号END_IF;END_FOR;END_FOR;FOR #PumpSwitch.N[13] := 1 TO 5 DO// 将启动顺序放入存储区,便于上位机显示#PumpSwitch.SequenceOut[#PumpSwitch.N[13]] := #PumpSwitch.Set[#PumpSwitch.N[13]].Sequence;END_FOR;END_REGIONREGION 根据时间顺序切换IF NOT #PumpSwitch.StpCmd THENCASE #PumpSwitch.Step OF0:IF #PumpSwitch.StaCmd AND #PumpSwitch.EnSwitch THEN#PumpSwitch.Step := 1;END_IF;#PumpSwitch.Pump[1] := 0;#PumpSwitch.Pump[2] := 0;#PumpSwitch.Pump[3] := 0;#PumpSwitch.Pump[4] := 0;#PumpSwitch.Pump[5] := 0;1:FOR #PumpSwitch.N[7] := 1 TO 5 DOIF #PumpControl[#PumpSwitch.N[7]].ControlWord = 1 THEN#PumpSwitch.Pump[#PumpSwitch.N[7]] := 1;END_IF;END_FOR; // 所有主泵同时启动#PumpSwitch.Step := 2;2:REGION 触发泵切换命令IF #SwitchPumpR_TRIG.Q AND #PumpSwitch.EnSwitch THENFOR #PumpSwitch.N[9] := 1 TO 5 DOIF (#PumpSwitch.SequenceOut[#PumpSwitch.N[9]] = 1) ANDNOT #PumpControl[#PumpSwitch.N[9]].Flt ANDNOT #PumpControl[#PumpSwitch.N[9]].Run ANDNOT (#PumpControl[#PumpSwitch.N[9]].ControlWord = 3) THENEXIT; // 找到启动顺序为1对应的泵的序号#PumpSwitch.N[9]END_IF;END_FOR;#PumpSwitch.Pump[#PumpSwitch.N[9]] := 1;END_IF;END_REGIONEND_CASE;ELSE#PumpSwitch.Pump[1] := 0;#PumpSwitch.Pump[2] := 0;#PumpSwitch.Pump[3] := 0;#PumpSwitch.Pump[4] := 0;#PumpSwitch.Pump[5] := 0;#PumpSwitch.N[9] := 0;#PumpSwitch.Step := 0;#PumpSwitch.EnSwitch := 0;END_IF;END_REGIONREGION 赋值FOR #PumpSwitch.N[11] := 1 TO 5 DOIF #PumpSwitch.Clear THEN#PumpControl[#PumpSwitch.N[11]].RunTime.Clear := 1;ELSE#PumpControl[#PumpSwitch.N[11]].RunTime.Clear := 0;END_IF;END_FOR;IF NOT "AlwaysFALSE" THEN#PumpSwitch.StaCmd := 0;#PumpSwitch.StpCmd := 0;#PumpSwitch.Clear := 0;END_IF;END_REGION
三、程序调用
在主程序中调用FB块“水泵多备多投”。
图7
程序分析:
- 实际应用时,#PumpControl[1].Run - #PumpControl[5].Run关联水泵1 - 5的运行反馈信号,#PumpSwitch.Pump[1] - #PumpSwitch.Pump[5]关联水泵1 - 5的启动命令,#PumpControl[1].Flt - #PumpControl[5].Flt关联水泵1 - 5的故障信号;
- 变量EnSwitch作为使能信号,只有EnSwitch置1时,功能才会正常投用,否则就算按下StaCmd启动按钮也不会实现主备互投;
- EnSwitch复位后,主备互投功能取消,此时可自由启停任意水泵;
- 按下StpCmd停止按钮后,所有水泵停止运行,EnSwitch自动复位;
- 当实际运行泵的数量小于应该运行的数量,会触发NumFlt运行泵数量不足报警,提醒操作员及时处理故障;
- 可在上位机画面中为每台泵添加“选择框控件”,关联ControlWord变量,ControlWord=1表示作为主泵,ControlWord=2表示作为备泵,ControlWord=3表示该泵不投用;
- 程序会根据选择的主泵数量和备泵数量,自动判断当前的主备互投模式。
总结
本文提供了一种结构化的水泵多备多投方法,可作为标准块应用于生产实际中。