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];