FUNCTION_BLOCK "FB_SepPrio"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      xInSepReq1 : Bool;   // Anforderung von Sep1
      xInSepReq2 : Bool;   // Anforderung von Sep2
      xInSepReq3 : Bool;   // Anforderung von Sep3
      xInSepRelease1 : Bool;   // Sep 1 hat rausgelassen
      xInSepRelease2 : Bool;   // Sep 2 hat rausgelassen
      xInSepRelease3 : Bool;   // Sep 3 hat rausgelassen
      xInActive : Bool;   // Freigabe grundsätzlich für Separatoren
      xInCarRun : Bool;   // NIU Motor läuft
      tInTime3 : Time;   // Zeit die Sep 3 braucht
      tInTime2 : Time;   // Zeit die Sep 2 braucht
   END_VAR

   VAR_OUTPUT 
      xOutSepGo1 : Bool;   // Freigabe für einzelnen Sep 1
      xOutSepGo2 : Bool;   // Freigabe für einzelnen Sep 2
      xOutSepGo3 : Bool;   // Freigabe für einzelnen Sep 3
   END_VAR

   VAR_IN_OUT 
      InOutJam : "stJamData";
   END_VAR

   VAR 
      fbStateManager : "FB_StateManager";
      nState : Int;   // Schritt
      tTime3 {InstructionName := 'TOF_TIME'; LibVersion := '1.0'} : TOF_TIME;   // Timer von Sep 3
      tTime2 {InstructionName := 'TOF_TIME'; LibVersion := '1.0'} : TOF_TIME;   // Timer von Sep 2
      tTime1 {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
      rTrigNotActive {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
      rTrig2 {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
      fTrig3 {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG;
      fTrig2 {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG;
      xTimeBit3 : Bool;   // Merker für Timer falls unterbrochen wird
      xTimeBit2 : Bool;   // Merker für Timer falls unterbrochen wird
   END_VAR

   VAR_TEMP 
      tmpActUnivTon : Bool;
   END_VAR

   VAR CONSTANT 
      cOff : Int := 0;
      cWaitAll : Int := 1;
      cWaitFor3 : Int := 30;
      cWaitFor2 : Int := 20;
      cOnlySep1 : Int := 10;
   END_VAR


BEGIN
	(*
	_______________________<==
	   |      |      |
	   |      |      |
	    \      \      \
	     \      \      \
	______3______2______1_____==>
	
	3 hat vor 2 und 1 Vorfahrt
	2 hat vor 1 Vorfahrt aber muss Zeit 3 abwarten
	1 muss Zeit 3 und 2 abwarten
	
	*)
	
	
	REGION Schrittkette
	    CASE #nState OF
	        #cOff:
	            REGION 000: Off
	                #xOutSepGo3 := FALSE;
	                #xOutSepGo2 := FALSE;
	                #xOutSepGo1 := FALSE;
	                
	                // IF #xInActive THEN
	                #nState := #cWaitAll;
	                // END_IF;
	            END_REGION
	        #cWaitAll:
	            REGION 001: Wait All
	                #xOutSepGo3 := FALSE;
	                #xOutSepGo2 := FALSE;
	                #xOutSepGo1 := FALSE;
	                //***************NEU***********
	                #nState := 005;
	                //*************NEU ENDE*******
	                
	                
	                (*IF NOT #xInActive THEN
	                    #nState := #cOff;*)
	                    // //********************Kombinationen mit Sep3*************************************************    
	                    // IF #xInSepReq3 AND #xInSepReq2 AND #xInSepReq1 THEN
	                    //     #xOutSepGo3 := TRUE;
	                    //     #xOutSepGo2 := false;//TRUE;
	                    //     #xOutSepGo1 := false;//TRUE;
	                    //     #nState := #cWaitFor3;
	                    // ELSIF #xInSepReq3 AND (#xInSepReq2 OR NOT #xInSepReq1) THEN
	                    //     #xOutSepGo3 := TRUE;
	                    //     #xOutSepGo2 := false;//TRUE;
	                    //     #xOutSepGo1 := FALSE;
	                    //     #nState := #cWaitFor3;
	                    // ELSIF #xInSepReq3 AND (NOT #xInSepReq2 OR #xInSepReq1) THEN
	                    //     #xOutSepGo3 := TRUE;
	                    //     #xOutSepGo2 := FALSE;
	                    //     #xOutSepGo1 := false;//TRUE;
	                    //     #nState := #cWaitFor3;
	                    // ELSIF #xInSepReq3 AND (NOT #xInSepReq2 AND NOT #xInSepReq1) THEN
	                    //     #xOutSepGo3 := TRUE;
	                    //     #xOutSepGo2 := FALSE;
	                    //     #xOutSepGo1 := FALSE;
	                    //     #nState := #cWaitFor3;
	                    // //********************Kombinationen ohne Sep3************************************************   
	                    // ELSIF NOT #xInSepReq3 AND (#xInSepReq2 AND #xInSepReq1) THEN
	                    //     #xOutSepGo3 := FALSE;
	                    //     #xOutSepGo2 := TRUE;
	                    //     #xOutSepGo1 := false;//TRUE;
	                    //     #nState := #cWaitFor2;
	                    // ELSIF NOT #xInSepReq3 AND (#xInSepReq2 AND NOT #xInSepReq1) THEN
	                    //     #xOutSepGo3 := FALSE;
	                    //     #xOutSepGo2 := TRUE;
	                    //     #xOutSepGo1 := FALSE;
	                    //     #nState := #cWaitFor2;
	                    // //********************Nur Sep1 alleine***************************************************    
	                    // ELSIF NOT #xInSepReq3 AND (NOT #xInSepReq2 AND #xInSepReq1) THEN
	                    //     #xOutSepGo3 := FALSE;
	                    //     #xOutSepGo2 := FALSE;
	                    //     #xOutSepGo1 := TRUE;
	                    //     #nState := #cOnlySep1;
	                    // END_IF;
	                END_REGION
	            005:
	                REGION 005: NEU Zwischenschritt
	                    #xOutSepGo3 := FALSE;
	                    #xOutSepGo2 := FALSE;
	                    #xOutSepGo1 := FALSE;
	                    
	                    IF #fbStateManager.tOutTimeInStep > T#6s THEN
	                        IF #xInSepReq1 THEN
	                            #nState := 006; // Embi
	                            // #nState := 010;
	                        ELSIF #xInSepReq2 THEN
	                            #nState := 16; // Embi
	                           // #nState := 020;
	                        // ELSIF #xInSepReq3 THEN
	                        //     #nState := 26; // Embi
	                           // #nState := 030;
	                        END_IF;
	                    END_IF;
	                END_REGION
	                
	            006:
	                REGION 006: Warten auf freie Ausfahrt
	                    #xOutSepGo3 := FALSE;
	                    #xOutSepGo2 := FALSE;
	                    #xOutSepGo1 := FALSE;
	                    IF #InOutJam.Status.nCount = 0 OR #fbStateManager.tOutTimeInStep > T#24s THEN
	                        #nState := #cOnlySep1;
	                    END_IF;
	                END_REGION
	            #cOnlySep1:
	                REGION 010: Only Sep 1
	                    #xOutSepGo3 := FALSE;
	                    #xOutSepGo2 := FALSE;
	                    #xOutSepGo1 := TRUE;
	                    
	                    //***************NEU***********
	                    IF #fbStateManager.tOutTimeInStep > T#10s THEN
	                        #nState := 015;
	                    END_IF;
	                    //*************NEU ENDE*******
	                    
	                    // IF (#xInSepReq2 OR #xInSepReq3) AND #tTime1.Q THEN //Wird sofort von 2 oder 3 unterbrochen
	                    //     #xOutSepGo3 := FALSE;
	                    //     #xOutSepGo2 := FALSE;
	                    //     #xOutSepGo1 := FALSE;
	                    //     #nState := #cWaitAll;
	                    // END_IF;
	                END_REGION
	            015:
	                REGION 015: NEU Zwischenschritt
	                    #xOutSepGo3 := FALSE;
	                    #xOutSepGo2 := FALSE;
	                    #xOutSepGo1 := FALSE;
	                    
	                    IF #fbStateManager.tOutTimeInStep > T#4s THEN
	                        IF #xInSepReq2 THEN
	                            #nState := 16; // Embi
	                            // #nState := 020;
	                        // ELSIF #xInSepReq3 THEN
	                        //     #nState := 26; // Embi
	                            // #nState := 030;
	                        ELSIF #xInSepReq1 THEN
	                            #nState := 6; // Embi
	                           // #nState := 010;
	                        END_IF;
	                    END_IF;
	                END_REGION
	                
	            016:
	                REGION 16: Warten auf freie Ausfahrt
	                    #xOutSepGo3 := FALSE;
	                    #xOutSepGo2 := FALSE;
	                    #xOutSepGo1 := FALSE;
	                    IF #InOutJam.Status.nCount = 0 OR #fbStateManager.tOutTimeInStep > T#26s THEN
	                        #nState := #cWaitFor2;
	                    END_IF;
	                END_REGION
	                
	            #cWaitFor2:
	                REGION 020: Wait for 2
	                    #xOutSepGo3 := FALSE;
	                    #xOutSepGo2 := TRUE;
	                    #xOutSepGo1 := FALSE;
	                    
	                    //***************NEU***********
	                    IF #fbStateManager.tOutTimeInStep > T#11s THEN
	                        // #nState := 025;
	                        #nState := 5;
	                    END_IF;
	                    //*************NEU ENDE*******
	                    
	                    (*IF NOT #xInActive THEN
	                        #nState := #cOff;*)
	                        // IF #fTrig2.Q THEN //Bis Sep 2 fertig....
	                        //     #xOutSepGo3 := FALSE;
	                        //     #xOutSepGo2 := FALSE;
	                        //     #xOutSepGo1 := FALSE;
	                        //     #nState := #cWaitAll;
	                        // ELSIF #xInSepReq3 THEN //...oder sofort durch Sep 3  unterbrochen
	                        //     #xOutSepGo3 := TRUE;
	                        //     #xOutSepGo2 := FALSE;
	                        //     #xOutSepGo1 := FALSE;
	                        //     #nState := #cWaitFor3;
	                        // END_IF;
	                    END_REGION
	                025:
	                    REGION 025: NEU Zwischenschritt
	                        #xOutSepGo3 := FALSE;
	                        #xOutSepGo2 := FALSE;
	                        #xOutSepGo1 := FALSE;
	                        
	                        IF #fbStateManager.tOutTimeInStep > T#5s THEN
	                            IF #xInSepReq3 THEN
	                                #nState := 26; // Embi
	                               // #nState := 030;
	                            ELSIF #xInSepReq1 THEN
	                                #nState := 6; // Embi
	                               // #nState := 010;
	                            ELSIF #xInSepReq2 THEN
	                                #nState := 16; // Embi
	                                // #nState := 020;
	                            END_IF;
	                        END_IF;
	                    END_REGION
	                    
	                026:
	                    REGION 26: Warten auf freie Ausfahrt
	                        #xOutSepGo3 := FALSE;
	                        #xOutSepGo2 := FALSE;
	                        #xOutSepGo1 := FALSE;
	                        IF #InOutJam.Status.nCount = 0 OR #fbStateManager.tOutTimeInStep > T#25s THEN
	                            #nState := #cWaitFor3;
	                        END_IF;
	                    END_REGION
	                    
	                #cWaitFor3:
	                    REGION 030: Wait for 3
	                        #xOutSepGo3 := TRUE;
	                        #xOutSepGo2 := FALSE;
	                        #xOutSepGo1 := FALSE;
	                        
	                        //***************NEU***********
	                        IF #fbStateManager.tOutTimeInStep > T#11s THEN //war 8s
	                            #nState := 005;
	                        END_IF;
	                        //*************NEU ENDE*******
	                        
	                        (*IF NOT #xInActive THEN
	                            #nState := #cOff;*)
	                            // IF #fTrig3.Q THEN //Bis Sep 3 fertig ist
	                            //     #xOutSepGo3 := FALSE;
	                            //     #xOutSepGo2 := FALSE;
	                            //     #xOutSepGo1 := FALSE;
	                            //     #nState := #cWaitAll;
	                            // END_IF;
	                        END_REGION
	                    ELSE
	                        ;
	                END_CASE;
	END_REGION
	
	REGION State Manager
	    #fbStateManager.stInSettings.nStartState := 0;
	    #fbStateManager.stInSettings.xActUnivTOn := TRUE;
	    #fbStateManager.stInSettings.xRestartAtStartState := FALSE;
	    #fbStateManager(xInFunctionEnabled:=TRUE,
	                    xInRunUnivTOn:=#tmpActUnivTon,
	                    nInOutState:=#nState);
	END_REGION
END_FUNCTION_BLOCK

