电机主备互投功能优化_多台设备均衡运行
文章目录
- 前言
- 一、功能概述
- 二、程序编写
- 1.需求分析
- 2.编写运行时间累计功能块
- 3.新增数据类型
- 1.时间排序数据类型
- 2.水泵控制数据类型
- 3.水泵切换数据类型
- 4.编程
- 1.新建DB块
- 2.新建FB块
- 3.调用FC块“运行时间累计”
- 4.计算每台水泵的运行时间
- 5.计算不同运行时间对应的序号
- 6.根据序号启动水泵
- 7.赋值
- 总结
前言
在上一篇文章西门子PLC常用底层逻辑块分享_电机主备互投中,提出了一种基于西门子SCL语言实现的两台电机主备互投的方法。本文旨在对该方法进行优化,应用场景由2台电机,增加到5台电机,并且要保证每台电机运行时间均衡,基于此,本文提出了基于运行时间自动切换电机的解决方案。
一、功能概述
现场有5台水泵,5台水泵具体的运行过程如下:
- 每次只有一台水泵运行,运行时需要记录电机的运行时间;
- 为了确保每台水泵的运行时间均衡,每次启动时,启动运行时间最少的水泵;
- 每台水泵都有故障信号,当水泵出现故障时能自动切换到下一台运行时间最少的水泵运行;
- 每台水泵需要有“启动允许”功能,当操作人员允许某台水泵启动时,该水泵才能按要求启动,否则跳过该水泵;
- 故障出现后,水泵的运行时间需要保持不变,不能丢失。
二、程序编写
1.需求分析
- 可以根据时间从小到大的顺序,计算出5台电机的运行时间对应的序号,遍历1-5,每次启动都启动序号1对应的电机;
- 故障信号或不允许启动信号触发后,可将该水泵的运行时间设置为最大值,故障解除后,自动设置为之前记录的正常时间。
2.编写运行时间累计功能块
可参考文章西门子PLC常用底层逻辑块分享_设备运行时间统计
根据该文章可编写FC块“运行时间累计”,并新建数据类型“时钟”。具体步骤这里不再赘述。
3.新增数据类型
1.时间排序数据类型
图1
2.水泵控制数据类型
图2
3.水泵切换数据类型
图3
4.编程
1.新建DB块
新建DB块“水泵控制数据块”,用来存放水泵状态及运行时间等数据。
图4
新建DB块“水泵切换数据块”,用来存放水泵启动顺序等数据。
图5
2.新建FB块
新建FB块“电机根据时间切换”,添加如下变量:
图6
3.调用FC块“运行时间累计”
"运行时间累计"(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);
4.计算每台水泵的运行时间
为方便计算,将运行时间的天、时、分、秒数据合计为秒。
注意,只有在没有故障且允许运行的状态下,时间累计才是正常的。
FOR #PumpSwitch.N := 1 TO 5 DO
IF NOT #PumpControl[#PumpSwitch.N].Flt
AND NOT #PumpControl[#PumpSwitch.N].StaAllowed
THEN
#PumpSwitch.Set[#PumpSwitch.N]."Time"
:= #PumpControl[#PumpSwitch.N].RunTime.Day * 24 * 60 * 60
+ #PumpControl[#PumpSwitch.N].RunTime.Hour * 60 * 60
+ #PumpControl[#PumpSwitch.N].RunTime.Min * 60
+ #PumpControl[#PumpSwitch.N].RunTime.Second;
END_IF;
END_FOR;
5.计算不同运行时间对应的序号
// 初始化序号数组
FOR #PumpSwitch.I := 1 TO 5 DO
#PumpSwitch.Set[#PumpSwitch.I].Sequence := 1; // 初始序号为1
END_FOR;
// 计算每个元素的序号
FOR #PumpSwitch.I := 1 TO 5 DO
FOR #PumpSwitch.J := 1 TO 5 DO
IF #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;
6.根据序号启动水泵
这里的编程思路参考了文章十、SCL核心应用课项目实战_油漆配料混合工艺控制程序设计(一)
IF NOT #PumpSwitch.StpCmd THEN
CASE #PumpSwitch.Step OF
0:
IF #PumpSwitch.StaCmd 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:
IF NOT #PumpControl[1].Run AND NOT #PumpControl[2].Run AND NOT #PumpControl[3].Run AND NOT #PumpControl[4].Run AND NOT #PumpControl[5].Run THEN
FOR #PumpSwitch.N1 := 1 TO 5 DO
IF #PumpSwitch.Set[#PumpSwitch.N1].Sequence = 1 THEN
EXIT; // 找到序号为1的运行时间对应的第N1台水泵
END_IF;
END_FOR;
END_IF;
IF NOT #PumpControl[#PumpSwitch.N1].Flt AND NOT #PumpControl[#PumpSwitch.N1].StaAllowed THEN
#PumpSwitch.Pump[#PumpSwitch.N1] := 1;
ELSE
#PumpSwitch.Pump[#PumpSwitch.N1] := 0;
#PumpSwitch.Step := 2;
END_IF;
2:
IF #PumpControl[#PumpSwitch.N1].Flt OR #PumpControl[#PumpSwitch.N1].StaAllowed THEN
#PumpSwitch.Set[#PumpSwitch.N1]."Time" := 4294967295; // 数据类型UDInt的最大值为4294967295
END_IF;
#PumpSwitch.Step := 1;
END_CASE;
ELSE
#PumpSwitch.Pump[1] := 0;
#PumpSwitch.Pump[2] := 0;
#PumpSwitch.Pump[3] := 0;
#PumpSwitch.Pump[4] := 0;
#PumpSwitch.Pump[5] := 0;
#PumpSwitch.Step := 0;
END_IF;
7.赋值
#PumpControl[1].Run := #PumpSwitch.Pump[1];
#PumpControl[2].Run := #PumpSwitch.Pump[2];
#PumpControl[3].Run := #PumpSwitch.Pump[3];
#PumpControl[4].Run := #PumpSwitch.Pump[4];
#PumpControl[5].Run := #PumpSwitch.Pump[5];
IF #PumpSwitch.Clear THEN
#PumpControl[1].RunTime.Clear := 1;
#PumpControl[2].RunTime.Clear := 1;
#PumpControl[3].RunTime.Clear := 1;
#PumpControl[4].RunTime.Clear := 1;
#PumpControl[5].RunTime.Clear := 1;
ELSE
#PumpControl[1].RunTime.Clear := 0;
#PumpControl[2].RunTime.Clear := 0;
#PumpControl[3].RunTime.Clear := 0;
#PumpControl[4].RunTime.Clear := 0;
#PumpControl[5].RunTime.Clear := 0;
END_IF;
//按钮自复位,其中"AlwaysFALSE"为CPU默认变量%M1.3
IF NOT "AlwaysFALSE" THEN
#PumpSwitch.StaCmd := 0;
#PumpSwitch.StpCmd := 0;
#PumpSwitch.Clear := 0;
END_IF;
程序编写完毕后,在主程序中调用即可
总结
该程序实现了多台设备的启动顺序根据运行时间的不同,自动切换,且不受设备故障影响。具体项目中可根据设备实际数量进行调整,具有一定的参考价值。