Hallo.
habe auf dem 750-837 etwas ähnliches realisiert. Bei meiner Lösung werden die Pumpen und Ventilatoren "Reihe um" angewählt. Die absolute Betriebsdauer ist dabei allerdings nicht ausschlaggebend.
Alles weitere kannst Du dem Code entnehmen.
Viele Grüße
Jürgen
FUNCTION_BLOCK zKaskade_7
VAR_INPUT
Required : INT;
Ready_01, Ready_02, Ready_03, Ready_04, Ready_05, Ready_06, Ready_07: BOOL;
END_VAR
VAR_OUTPUT
ReadyCount : INT;
Out_01, Out_02, Out_03, Out_04, Out_05, Out_06, Out_07: BOOL;
END_VAR
VAR_INPUT CONSTANT
CycleTime: UINT;
OverlapTime: UINT; (*Überlappungszeit*)
END_VAR
VAR
Oscillator :TON;
CycleTimeCount: UINT;
OverlapTimeCount: UINT; (*Überlappungszeit Zähler*)
Ready : ARRAY [1..7] OF BOOL := FALSE;
Out : ARRAY [1..7] OF BOOL := FALSE;
RequiredExt : INT;
OutOnTime : ARRAY [1..7] OF UINT;
OutOffTime : ARRAY [1..7] OF UINT;
ForCount : INT;
OverlapFlag: BOOL;
OldValueTime: UINT;
SearchRes: INT;
OutCount : INT;
END_VAR
(*Beginn: Pumpenabschalten wenn nicht bereit-----------------------------*)
FOR ForCount:=1 TO 7 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;
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;
OutCount := 0;
ReadyCount := 0;
FOR ForCount:=1 TO 7 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 (*Bei zu langer Laufzeit abschalten*)
CycleTimeCount := 0;
OverlapFlag := TRUE;
END_IF
IF ((OverlapFlag = TRUE) AND (Required>0)) 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 7 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 7 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 7 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];