FUNCTION_BLOCK zKaskade
VAR_INPUT
Required : INT;
Ready_01, Ready_02, Ready_03, Ready_04, Ready_05, Ready_06, Ready_07, Ready_08, Ready_09, Ready_10 : BOOL;
CycleTime: UINT;
OverlapTime: UINT; (*Überlappungszeit*)
END_VAR
VAR_OUTPUT
Out_01, Out_02, Out_03, Out_04, Out_05, Out_06, Out_07, Out_08, Out_09, Out_10 : BOOL;
END_VAR
VAR
Oscillator :TON;
CycleTimeCount: UINT;
OverlapTimeCount: UINT; (*Überlappungszeit Zähler*)
Ready : ARRAY [1..10] OF BOOL := FALSE;
Out : ARRAY [1..10] OF BOOL := FALSE;
ReadyCount : INT;
OutCount : INT;
RequiredExt : INT;
OutOnTime : ARRAY [1..10] OF UINT;
OutOffTime : ARRAY [1..10] OF UINT;
ForCount : INT;
OverlapFlag: BOOL;
OldValueTime: UINT;
SearchRes: INT;
END_VAR
(*Beginn: Pumpenabschalten wenn nicht bereit-----------------------------*)
FOR ForCount:=1 TO 10 BY 1 DO
IF (Ready[ForCount] = FALSE) THEN
Out[ForCount] := FALSE;
END_IF
END_FOR;
(*Ende: Pumpenabschalten wenn nicht bereit-------------------------------*)
Oscillator(IN := NOT Oscillator.Q, PT:= T#1s);
IF Oscillator.Q = TRUE THEN
(*Beginn: Bestandsaufnahme----------------------------------------------------*)
Ready[1] := Ready_01;
Ready[2] := Ready_02;
Ready[3] := Ready_03;
Ready[4] := Ready_04;
Ready[5] := Ready_05;
Ready[6] := Ready_06;
Ready[7] := Ready_07;
Ready[8] := Ready_08;
Ready[9] := Ready_09;
Ready[10] := Ready_10;
Out[1] := Out_01;
Out[2] := Out_02;
Out[3] := Out_03;
Out[4] := Out_04;
Out[5] := Out_05;
Out[6] := Out_06;
Out[7] := Out_07;
Out[8] := Out_08;
Out[9] := Out_09;
Out[10] := Out_10;
OutCount := 0;
ReadyCount := 0;
FOR ForCount:=1 TO 10 BY 1 DO
IF (Out[ForCount] = TRUE) THEN
OutCount := OutCount + 1;
OutOnTime[ForCount] := OutOnTime[ForCount] + 1;
OutOffTime[ForCount] := 0;
ELSIF (Ready[ForCount] = TRUE) THEN
OutOffTime[ForCount] := OutOffTime[ForCount] + 1;
OutOnTime[ForCount] := 0;
ELSIF (Ready[ForCount] = FALSE) THEN
OutOnTime[ForCount] := 0;
OutOffTime[ForCount] := 0;
END_IF
IF (Ready[ForCount] = TRUE) THEN
ReadyCount := ReadyCount + 1;
END_IF
END_FOR;
(*Ende: Bestandsaufnahme------------------------------------------------------*)
CycleTimeCount := CycleTimeCount + 1;
IF CycleTimeCount >= CycleTime THEN
CycleTimeCount := 0;
OverlapFlag := TRUE;
END_IF
IF (OverlapFlag = TRUE) THEN
OverlapTimeCount := OverlapTimeCount + 1;
RequiredExt := Required + 1;
ELSE
RequiredExt := Required;
END_IF
IF OverlapTimeCount >= OverlapTime THEN
OverlapTimeCount := 0;
OverlapFlag := FALSE;
END_IF
IF (ReadyCount > RequiredExt) THEN
WHILE (OutCount < RequiredExt) DO
OldValueTime := 0;
SearchRes := 1;
FOR ForCount:=1 TO 10 BY 1 DO
IF ((OutOffTime[ForCount] > OldValueTime)
AND (Ready[ForCount] = TRUE) AND (Out[ForCount] = FALSE)) THEN
OldValueTime := OutOffTime[ForCount];
SearchRes := ForCount;
END_IF
END_FOR;
IF (Ready[SearchRes] = TRUE) THEN
Out[SearchRes] := TRUE;
OutCount := OutCount + 1;
END_IF
END_WHILE
ELSE
FOR ForCount:=1 TO 10 BY 1 DO
IF (Ready[ForCount] = TRUE) THEN
Out[ForCount] := TRUE;
END_IF
END_FOR;
END_IF
WHILE (OutCount > RequiredExt) DO
OldValueTime := 0;
SearchRes := 1;
FOR ForCount:=1 TO 10 BY 1 DO
IF ((OutOnTime[ForCount] > OldValueTime)
AND (Ready[ForCount] = TRUE) AND (Out[ForCount] = TRUE)) THEN
OldValueTime := OutOnTime[ForCount];
SearchRes := ForCount;
END_IF
END_FOR;
Out[SearchRes] := FALSE;
OutCount := OutCount - 1;
END_WHILE
END_IF
Out_01 := Out[1];
Out_02 := Out[2];
Out_03 := Out[3];
Out_04 := Out[4];
Out_05 := Out[5];
Out_06 := Out[6];
Out_07 := Out[7];
Out_08 := Out[8];
Out_09 := Out[9];
Out_10 := Out[10];