You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

519 lines
16 KiB

FUNCTION_BLOCK IJ_EAFGroup
VAR_EXTERNAL
BS_Schedule_Str_W :STRING;
BS_Schedule_Str_R :ARRAY[0..60] OF BYTE;
END_VAR
VAR_INPUT
Enable :bool; (*联动启用*)
LinkageValue:ARRAY[0..10] of real;(*传感器输入数组*)
Dead_Band :real:=10.0; (*联动死区*)
MaxRange :real:=1000.0; (*上限切除值*)
MinRange :real:=10.0; (*下限切除值*)
LinkageSet :real; (*联动目标设定值,平均值大于设定值时动作*)
HoldDelay :time:=t#60s; (*波动稳定时间*)
EnableNum :INT; (*启用时间段数量 1~4*)
SCH_str :STRING;
ALLDAY :BOOL;
END_VAR
VAR_OUTPUT
LinkageOut :ARRAY[0..10] of bool;
END_VAR
VAR
OUT_Z :BOOL;
TempSum :REAL;
TempCount :INT;
ValueSum :REAL;
ValueCount :INT;
ValueAverage:REAL;
LinkageEN :BOOL;
ton1 :ton;
ton2 :ton;
i,j,k :INT:=0;
TimeSw1 :BOOL;
TimeSw2 :BOOL;
TimeSw3 :BOOL;
TimeSw4 :BOOL;
Enable1th :BOOL;
Enable2th :BOOL;
Enable3th :BOOL;
Enable4th :BOOL;
OnH1th :INT:=0;
OnM1th :INT:=0;
OffH1th :INT:=0;
OffM1th :INT:=0;
OnH2th :INT:=0;
OnM2th :INT:=0;
OffH2th :INT:=0;
OffM2th :INT:=0;
OnH3th :INT:=0;
OnM3th :INT:=0;
OffH3th :INT:=0;
OffM3th :INT:=0;
OnH4th :INT:=0;
OnM4th :INT:=0;
OffH4th :INT:=0;
OffM4th :INT:=0;
Clock : NW_DateTimeGet;
HOUR :byte;
YEAR :word;
MON :byte;
DAY :byte;
MI :byte;
SEC :byte;
WEEK :byte;
WD_HOUR :INT;
WD_MI :INT;
SetCompare1th :BOOL; (*开启设定时间大于关闭设定时间为1,反之为0*)
TrueSetCloseCompare1th :BOOL; (*关闭设定时间大于实际时间为1,反之为0*)
TrueSetOpenCompare1th :BOOL; (*开启设定时间大于实际时间为1,反之为0*)
SetCompare2th :BOOL; (*开启设定时间大于关闭设定时间为1,反之为0*)
TrueSetCloseCompare2th :BOOL; (*关闭设定时间大于实际时间为1,反之为0*)
TrueSetOpenCompare2th :BOOL; (*开启设定时间大于实际时间为1,反之为0*)
SetCompare3th :BOOL; (*开启设定时间大于关闭设定时间为1,反之为0*)
TrueSetCloseCompare3th :BOOL; (*关闭设定时间大于实际时间为1,反之为0*)
TrueSetOpenCompare3th :BOOL; (*开启设定时间大于实际时间为1,反之为0*)
SetCompare4th :BOOL; (*开启设定时间大于关闭设定时间为1,反之为0*)
TrueSetCloseCompare4th :BOOL; (*关闭设定时间大于实际时间为1,反之为0*)
TrueSetOpenCompare4th :BOOL; (*开启设定时间大于实际时间为1,反之为0*)
p1,p2 : pointer;
v2v : NW_MemCopy;
ini :BOOL;
str_ini :STRING;
END_VAR
(*
时 间:20200807
版 本:1.1
作 者:
名 称:排风机组联动程序功能块
说 明:
输入变量
Enable :bool; 联动启用
LinkageValue:ARRAY[0..10] of real; 传感器输入数组
Dead_Band :real:=10.0; 联动死区
MaxRange :real:=1000.0; 上限切除值
MinRange :real:=10.0; 下限切除值
LinkageSet :real; 联动目标设定值,平均值大于设定值时动作
HoldDelay :time:=t#60s; 波动稳定时间 默认60s
EnableNum :INT; 启用时间段数量 1~4
SCH_str :STRING; 定时字符串
ALLDAY :BOOL; 全天候模式 0定时时段内运行,1全天候
输出变量
LinkageOut :ARRAY[0..10] of bool; 输出控制数组
1.支持最多4时段或全天候联动设置
2.支持10组数据输入平均取值作为联动依据
3.支持10组设备输出作为联动结果
4.联动值可设置死区范围,上下限切除值,稳定时间
备 注:适配C4版本CPU
依赖块:
BS_Runtime;
BS_DevC;
*)
if Enable=1 then
if SCH_str<>'' then
(*暂通过数组整理字符串,数组读到的值为ASCII码,需通过BS_ASCII2INT进行整理,后期指针功能上线后优化外部引用*)
BS_Schedule_Str_W :=SCH_str;
(* C2版本
v2m1(EN :=1 , DW_MEM_ADDR :=2000 , W_MAXNUM :=32 , STR_FILENAME :='OPCDA1' , STR_VARNAME :='BS_Schedule_Str_W' );
m2v1(EN :=1 , DW_MEM_ADDR :=2000 , W_MEM_LEN :=32 , STR_FILENAME :='OPCDA1' , STR_VARNAME :='BS_Schedule_Str_R' );
*)
(* C4版本 *)
p1:=&BS_Schedule_Str_W;
p2:=&BS_Schedule_Str_R;
v2v(DEST :=p2 , SRC :=p1 , LENGTH :=32 , IQM :=0 );
(*时间数据赋值及限值处理*)
if BS_ASCII2INT(BS_Schedule_Str_R[ 0],BS_Schedule_Str_R[ 1])<0 then OnH1th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[ 0],BS_Schedule_Str_R[ 1])>23 then OnH1th:=23; else OnH1th:=BS_ASCII2INT(BS_Schedule_Str_R[ 0],BS_Schedule_Str_R[ 1]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[ 2],BS_Schedule_Str_R[ 3])<0 then OnM1th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[ 2],BS_Schedule_Str_R[ 3])>59 then OnM1th:=59; else OnM1th:=BS_ASCII2INT(BS_Schedule_Str_R[ 2],BS_Schedule_Str_R[ 3]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[ 4],BS_Schedule_Str_R[ 5])<0 then OffH1th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[ 4],BS_Schedule_Str_R[ 5])>23 then OffH1th:=23; else OffH1th:=BS_ASCII2INT(BS_Schedule_Str_R[ 4],BS_Schedule_Str_R[ 5]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[ 6],BS_Schedule_Str_R[ 7])<0 then OffM1th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[ 6],BS_Schedule_Str_R[ 7])>59 then OffM1th:=59; else OffM1th:=BS_ASCII2INT(BS_Schedule_Str_R[ 6],BS_Schedule_Str_R[ 7]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[ 8],BS_Schedule_Str_R[ 9])<0 then OnH2th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[ 8],BS_Schedule_Str_R[ 9])>23 then OnH2th:=23; else OnH2th:=BS_ASCII2INT(BS_Schedule_Str_R[ 8],BS_Schedule_Str_R[ 9]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[10],BS_Schedule_Str_R[11])<0 then OnM2th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[10],BS_Schedule_Str_R[11])>59 then OnM2th:=59; else OnM2th:=BS_ASCII2INT(BS_Schedule_Str_R[10],BS_Schedule_Str_R[11]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[12],BS_Schedule_Str_R[13])<0 then OffH2th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[12],BS_Schedule_Str_R[13])>23 then OffH2th:=23; else OffH2th:=BS_ASCII2INT(BS_Schedule_Str_R[12],BS_Schedule_Str_R[13]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[14],BS_Schedule_Str_R[15])<0 then OffM2th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[14],BS_Schedule_Str_R[15])>59 then OffM2th:=59; else OffM2th:=BS_ASCII2INT(BS_Schedule_Str_R[14],BS_Schedule_Str_R[15]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[16],BS_Schedule_Str_R[17])<0 then OnH3th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[16],BS_Schedule_Str_R[17])>23 then OnH3th:=23; else OnH3th:=BS_ASCII2INT(BS_Schedule_Str_R[16],BS_Schedule_Str_R[17]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[18],BS_Schedule_Str_R[19])<0 then OnM3th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[18],BS_Schedule_Str_R[19])>59 then OnM3th:=59; else OnM3th:=BS_ASCII2INT(BS_Schedule_Str_R[18],BS_Schedule_Str_R[19]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[20],BS_Schedule_Str_R[21])<0 then OffH3th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[20],BS_Schedule_Str_R[21])>23 then OffH3th:=23; else OffH3th:=BS_ASCII2INT(BS_Schedule_Str_R[20],BS_Schedule_Str_R[21]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[22],BS_Schedule_Str_R[23])<0 then OffM3th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[22],BS_Schedule_Str_R[23])>59 then OffM3th:=59; else OffM3th:=BS_ASCII2INT(BS_Schedule_Str_R[22],BS_Schedule_Str_R[23]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[24],BS_Schedule_Str_R[25])<0 then OnH4th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[24],BS_Schedule_Str_R[25])>23 then OnH4th:=23; else OnH4th:=BS_ASCII2INT(BS_Schedule_Str_R[24],BS_Schedule_Str_R[25]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[26],BS_Schedule_Str_R[27])<0 then OnM4th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[26],BS_Schedule_Str_R[27])>59 then OnM4th:=59; else OnM4th:=BS_ASCII2INT(BS_Schedule_Str_R[26],BS_Schedule_Str_R[27]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[28],BS_Schedule_Str_R[29])<0 then OffH4th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[28],BS_Schedule_Str_R[29])>23 then OffH4th:=23; else OffH4th:=BS_ASCII2INT(BS_Schedule_Str_R[28],BS_Schedule_Str_R[29]); end_if;
if BS_ASCII2INT(BS_Schedule_Str_R[30],BS_Schedule_Str_R[31])<0 then OffM4th:=0; elsif BS_ASCII2INT(BS_Schedule_Str_R[30],BS_Schedule_Str_R[31])>59 then OffM4th:=59; else OffM4th:=BS_ASCII2INT(BS_Schedule_Str_R[30],BS_Schedule_Str_R[31]); end_if;
end_if;
(* 有效时间范围内程序执行*)
if EnableNum =1 then Enable1th :=1; Enable2th :=0; Enable3th :=0; Enable4th :=0; end_if;
if EnableNum =2 then Enable1th :=1; Enable2th :=1; Enable3th :=0; Enable4th :=0; end_if;
if EnableNum =3 then Enable1th :=1; Enable2th :=1; Enable3th :=1; Enable4th :=0; end_if;
if EnableNum =4 then Enable1th :=1; Enable2th :=1; Enable3th :=1; Enable4th :=1; end_if;
if ALLDAY=0 then
(*定时控制主程序 4段排程*)
Clock( EN:=1 , B_TWELVE_HOUR:=0 | YEAR:= W_YEAR, MON:= BY_MONTH, DAY:= BY_DAY, HOUR:= BY_HOUR,MI := BY_MIN, SEC:= BY_SEC,WEEK := BY_WDAY );
WD_HOUR:=BYTE_TO_int(HOUR);
WD_MI:=BYTE_TO_int(MI);
if Enable1th=TRUE and (not(OnH1th=OffH1th and OnM1th=OffM1th)) then(*开关时间一致则无效*)
(*1判断开关设定时间之间的大小*)
if OnH1th>OffH1th then
SetCompare1th := 1;
end_if;
if OnH1th<OffH1th then
SetCompare1th := 0;
end_if;
if OnH1th=OffH1th then
if OnM1th>OffM1th then
SetCompare1th := 1;
else
SetCompare1th := 0;
end_if;
end_if;
(*1判断开设定时间与实际时间之间的大小*)
if OnH1th>WD_HOUR then
TrueSetOpenCompare1th := 1;
end_if;
if OnH1th<WD_HOUR then
TrueSetOpenCompare1th := 0;
end_if;
if OnH1th=WD_HOUR then
if OnM1th>=WD_MI then
TrueSetOpenCompare1th := 1;
else
TrueSetOpenCompare1th := 0;
end_if;
end_if;
(*1判断关设定时间与实际时间之间的大小*)
if OffH1th>WD_HOUR then
TrueSetCloseCompare1th := 1;
end_if;
if OffH1th<WD_HOUR then
TrueSetCloseCompare1th := 0;
end_if;
if OffH1th=WD_HOUR then
if OffM1th>=WD_MI then
TrueSetCloseCompare1th := 1;
else
TrueSetCloseCompare1th := 0;
end_if;
end_if;
(*1控制输出*)
if SetCompare1th then(*开启设定时间大于关闭设定时间为1*)
if TrueSetOpenCompare1th and not (TrueSetCloseCompare1th) then
TimeSw1:=0;
else
TimeSw1:=1;
end_if;
else
if TrueSetCloseCompare1th and not (TrueSetOpenCompare1th) then
TimeSw1:=1;
else
TimeSw1:=0;
end_if;
end_if;
else
TimeSw1:=0;
end_if;
if Enable2th=TRUE and (not(OnH2th=OffH2th and OnM2th=OffM2th)) then(*开关时间一致则无效*)
(*2判断开关设定时间之间的大小*)
if OnH2th>OffH2th then
SetCompare2th := 1;
end_if;
if OnH2th<OffH2th then
SetCompare2th := 0;
end_if;
if OnH2th=OffH2th then
if OnM2th>OffM2th then
SetCompare2th := 1;
else
SetCompare2th := 0;
end_if;
end_if;
(*2判断开设定时间与实际时间之间的大小*)
if OnH2th>WD_HOUR then
TrueSetOpenCompare2th := 1;
end_if;
if OnH2th<WD_HOUR then
TrueSetOpenCompare2th := 0;
end_if;
if OnH2th=WD_HOUR then
if OnM2th>=WD_MI then
TrueSetOpenCompare2th := 1;
else
TrueSetOpenCompare2th := 0;
end_if;
end_if;
(*2判断关设定时间与实际时间之间的大小*)
if OffH2th>WD_HOUR then
TrueSetCloseCompare2th := 1;
end_if;
if OffH2th<WD_HOUR then
TrueSetCloseCompare2th := 0;
end_if;
if OffH2th=WD_HOUR then
if OffM2th>=WD_MI then
TrueSetCloseCompare2th := 1;
else
TrueSetCloseCompare2th := 0;
end_if;
end_if;
(*2控制输出*)
if SetCompare2th then(*开启设定时间大于关闭设定时间为1*)
if TrueSetOpenCompare2th and not (TrueSetCloseCompare2th) then
TimeSw2:=0;
else
TimeSw2:=1;
end_if;
else
if TrueSetCloseCompare2th and not (TrueSetOpenCompare2th) then
TimeSw2:=1;
else
TimeSw2:=0;
end_if;
end_if;
else
TimeSw2:=0;
end_if;
if Enable3th=TRUE and (not(OnH3th=OffH3th and OnM3th=OffM3th)) then(*开关时间一致则无效*)
(*3判断开关设定时间之间的大小*)
if OnH3th>OffH3th then
SetCompare3th := 1;
end_if;
if OnH3th<OffH3th then
SetCompare3th := 0;
end_if;
if OnH3th=OffH3th then
if OnM3th>OffM3th then
SetCompare3th := 1;
else
SetCompare3th := 0;
end_if;
end_if;
(*3判断开设定时间与实际时间之间的大小*)
if OnH3th>WD_HOUR then
TrueSetOpenCompare3th := 1;
end_if;
if OnH3th<WD_HOUR then
TrueSetOpenCompare3th := 0;
end_if;
if OnH3th=WD_HOUR then
if OnM3th>=WD_MI then
TrueSetOpenCompare3th := 1;
else
TrueSetOpenCompare3th := 0;
end_if;
end_if;
(*3判断关设定时间与实际时间之间的大小*)
if OffH3th>WD_HOUR then
TrueSetCloseCompare3th := 1;
end_if;
if OffH3th<WD_HOUR then
TrueSetCloseCompare3th := 0;
end_if;
if OffH3th=WD_HOUR then
if OffM3th>=WD_MI then
TrueSetCloseCompare3th := 1;
else
TrueSetCloseCompare3th := 0;
end_if;
end_if;
(*3控制输出*)
if SetCompare3th then(*开启设定时间大于关闭设定时间为1*)
if TrueSetOpenCompare3th and not (TrueSetCloseCompare3th) then
TimeSw3:=0;
else
TimeSw3:=1;
end_if;
else
if TrueSetCloseCompare3th and not (TrueSetOpenCompare3th) then
TimeSw3:=1;
else
TimeSw3:=0;
end_if;
end_if;
else
TimeSw3:=0;
end_if;
if Enable4th=TRUE and (not(OnH4th=OffH4th and OnM4th=OffM4th)) then(*开关时间一致则无效*)
(*4判断开关设定时间之间的大小*)
if OnH4th>OffH4th then
SetCompare4th := 1;
end_if;
if OnH4th<OffH4th then
SetCompare4th := 0;
end_if;
if OnH4th=OffH4th then
if OnM4th>OffM4th then
SetCompare4th := 1;
else
SetCompare4th := 0;
end_if;
end_if;
(*4判断开设定时间与实际时间之间的大小*)
if OnH4th>WD_HOUR then
TrueSetOpenCompare4th := 1;
end_if;
if OnH4th<WD_HOUR then
TrueSetOpenCompare4th := 0;
end_if;
if OnH4th=WD_HOUR then
if OnM4th>=WD_MI then
TrueSetOpenCompare4th := 1;
else
TrueSetOpenCompare4th := 0;
end_if;
end_if;
(*4判断关设定时间与实际时间之间的大小*)
if OffH4th>WD_HOUR then
TrueSetCloseCompare4th := 1;
end_if;
if OffH4th<WD_HOUR then
TrueSetCloseCompare4th := 0;
end_if;
if OffH4th=WD_HOUR then
if OffM4th>=WD_MI then
TrueSetCloseCompare4th := 1;
else
TrueSetCloseCompare4th := 0;
end_if;
end_if;
(*4控制输出*)
if SetCompare4th then(*开启设定时间大于关闭设定时间为1*)
if TrueSetOpenCompare4th and not (TrueSetCloseCompare4th) then
TimeSw4:=0;
else
TimeSw4:=1;
end_if;
else
if TrueSetCloseCompare4th and not (TrueSetOpenCompare4th) then
TimeSw4:=1;
else
TimeSw4:=0;
end_if;
end_if;
else
TimeSw4:=0;
end_if;
if TimeSw1 or TimeSw2 or TimeSw3 or TimeSw4 then
OUT_Z:=1;
else
OUT_Z:=0;
end_if;
if OUT_Z=0 and ALLDAY =0 then
LinkageEN:=0;
end_if;
end_if;
(* 定时范围内动作 *)
if OUT_Z=1 or ALLDAY =1 then
(* 组数据联动组设备 *)
(*数据处理 过滤超过max,min范围的值,计数有效数据,算出平均值, 取总和*)
for i:= 0 to 9 by 1 do
if LinkageValue[i]>=MinRange and LinkageValue[i]<=MaxRange then
TempSum:=LinkageValue[i]+TempSum;
else
TempCount:=TempCount+1;
end_if;
end_for;
if i>=9 then
i:=0;
ValueCount:=10-TempCount;
TempCount :=0;
ValueSum :=TempSum;
TempSum :=0.0;
end_if;
if ValueCount<>0 then
ValueAverage:=ValueSum/int_to_real(ValueCount);
end_if;
(*比较设定值,稳定有效时间后动作*)
ton1(pt:=HoldDelay);
ton2(pt:=HoldDelay);
if ValueAverage<>0.0 then
if (LinkageSet-Dead_Band)-ValueAverage>=0.0 then
ton1.in:=1;
else
ton1.in:=0;
end_if;
if ton1.q=1 then
LinkageEN:=0;
end_if;
if (LinkageSet+Dead_Band)-ValueAverage<0.0 then
ton2.in:=1;
else
ton2.in:=0;
end_if;
if ton2.q=1 then
LinkageEN:=1;
end_if;
else
LinkageEN:=0;
end_if;
end_if;
(*联动绑定风机*)
for j:= 0 to 9 by 1 do
LinkageOut[j]:=LinkageEN;
end_for;
end_if;
END_FUNCTION_BLOCK