FUNCTION_BLOCK "FB_ILS_STRO_Vario_WorkStation"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      stInSettings : "SettingsVario";   // Einstellungen Vario
      xInReleaseEdge : Bool;   // Flanke Carrier rausgelassen
      stInSenConvFingerInPos : "UDT_Sensor";   // Mitnehmerfinger in Position (FingerInPos)
      stInSenJam : "UDT_Sensor";   // Stausensor nach Vario (Jam)
      stInSenLastPos : "UDT_Sensor";   // Letzte Position erreicht (Full)
      stInSenCarrInPos : "UDT_Sensor";   // Carrier in Position (CarrInPos)
      xInRelease : Bool := false;   // Freigabe zum Entleeren
      xInRequest : Bool;   // Anfrage an Vario
      xInMotorProtection : Bool := false;   // Motorschutz
      xInErrorQuit : Bool;   // Fehler quittieren Überwachung Finger
      xInAutomatic : Bool;
      stInStationSensor : "UDT_Sensor";
      xInReleaseStation : Bool;
   END_VAR

   VAR_OUTPUT 
      xOutMotor : Bool := false;   // Antrieb raumgängiger Förderer 
      xOutConveyorReady : Bool := false;   // HFS Schnittstelle: Förderer kann neuen BT aufnehmen
      xOutConveyorReleaseReq : Bool := false;   // Anforderung: Förderer entleeren
   END_VAR

   VAR_IN_OUT 
      arInOutJamFinger : Array[*] of "stCarrier";   // Daten Staubereich Finger
      stInOutHMI : "UDT_Vario";
      stInOutControlUnitCabinet : "UDT_MainState";
   END_VAR

   VAR 
      fbStateManager { ExternalWritable := 'False'; S7_SetPoint := 'False'} : "FB_StateManager";   // Schrittkette Manager
      fbFingerControl : "FB_SupervisionRasterSensor";
      sStateText { S7_SetPoint := 'True'} : String := '';   // Schritt Text (zum Beobachten)
   END_VAR
   VAR RETAIN
      nState { S7_SetPoint := 'True'} : Int := 0;   // Schritt
      nStateLast : Int := 0;   // vorheriger Schritt (für State Manager)
      xRunMotor : Bool := false;   // Motor Start
      xConveyorReady : Bool := false;   // Förderer ist bereit
      tOnAllBtOut {InstructionName := 'TON_TIME'; LibVersion := '1.0'; S7_SetPoint := 'False'} : TON_TIME;   // Timer: Keine Bt mehr auf Vario
      counterCarrier {InstructionName := 'CTU_INT'; LibVersion := '1.0'} : CTU_INT;   // Klinkenzählerfunktion
   END_VAR
   VAR 
      nCounterCatch : Int := 0;   // Zähler Klinke
      xErrorBtNotReaching : Bool := false;
      tOn_ErrorConv {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;   // Zeitverzögerte Fehlermeldung wenn Förderer zu lange zum Entleeren braucht oder zu lange voll
      tOn_WaitForStop {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
      fbMonitoringFinger : "FB_Monitoring";
      xClearDone : Bool;   // Prüffahrt um Finger leer zu fahren abgeschlossen
      "////////" : Bool;
      xTestMode : Bool;
      xSationStop : Bool;
      xReleaseReq : Bool;
      nCarrierCount : Int;
      xReleaseStation : Bool;
      xStartScanBarcode : Bool;
      xReadyForScan : Bool;
      xReadingDone : Bool;
      xHandShakeScan : Bool;
      xBeladenError : Bool;
      xResetBeladen : Bool;
      xResetLed : Bool;
      FB_Blinker { S7_SetPoint := 'False'} : "FB_Blinker";
   END_VAR

   VAR_TEMP 
      tmpActUnivTon : Bool;   // Siehe State Manager
      nArrayMaxFinger : DInt;
   END_VAR

   VAR CONSTANT 
      c0000_StepOff : Int := 0;   // Aus
      c0100_StepUndefined : Int := 100;   // Undefiniert
      c0200_StepReceive : Int := 200;   // Förderer wartet auf Arbeit / Bereit aufzunehmen
      c1200_StepWaitTime : Int := 1200;   // Förderer wartet vor Fahrt
      c2000_StepJog : Int := 2000;   // Förderer eine Position weiter fahren (Jog Fw)
      c2200_StepNormalStop : Int := 2200;
      c2250_StepQuickStop : Int := 2250;
      c2500_StepCheckVario : Int := 2500;   // Prüfen ob wirklich leer
      c3000_StepEmptying : Int := 3000;   // Förderer entleeren
      c5000_StepEnding : Int := 5000;   // Förderer Ablauf beenden
      c8000_StepScan : Int := 8000;
      c8001_WaitingForRelease : Int := 8001;
   END_VAR


BEGIN
	REGION Arraygrößen
	    #nArrayMaxFinger := UPPER_BOUND(ARR := #arInOutJamFinger, DIM := 1);
	END_REGION
	
	REGION State Machine
	    // Off
	    // Idle (keine Daten und Prüffahrt abgeschlossen)
	    //      Anforderung MTRO / Separator 
	    //      -> Entleeren
	    // Entleeren (Fahre bis Stau oder keine Daten) 
	    //      1. Anforderung MTRO / Separator
	    //      -> Entleeren Pausieren
	    //      2. Keine Daten mehr 
	    //      -> Idle
	    // Entleeren Pausieren
	    // 
	    
	    
	    CASE #nState OF
	        #c0000_StepOff:
	            REGION 0000: Off
	                
	                // Aktueller Zustand
	                #sStateText := 'OFF';
	                
	                // Statics
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                
	            END_REGION
	            
	        #c0100_StepUndefined:
	            REGION 0100: Undefined
	                
	                // Aktueller Zustand
	                #sStateText := 'UNDEFINED';
	                
	                // Statics
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                
	                #nState := #c0200_StepReceive;
	            END_REGION
	            
	        #c0200_StepReceive:
	            REGION 0200: Receive
	                
	                // Aktueller Zustand
	                #sStateText := 'RECEIVE';
	                
	                // Statics
	                #xReleaseReq := FALSE;
	                #xRunMotor := FALSE;
	                
	                
	                
	                
	                #xConveyorReady := #xInMotorProtection;
	                
	                // Transition
	                // 
	                IF #xTestMode OR #stInOutHMI.stControl.xTestMode THEN
	                    #xConveyorReady := FALSE;
	                    #nState := #c2000_StepJog;
	                ELSE
	                    
	                    IF (#xConveyorReady AND #counterCarrier.QU) OR ((* #arInOutJamFinger[1].bStatus.%X0 AND *)NOT #xInRequest AND NOT #xClearDone AND #fbStateManager.tOutTimeInStep > T#5000ms) THEN
	                        #nState := #c1200_StepWaitTime;
	                        
	                        // ELSIF (#arInOutJamFinger[1].stCarrData.xOnline AND NOT #xClearDone AND NOT #xInRequest AND #fbStateManager.tOutTimeInStep > T#5000ms) AND
	                        //     (NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms) THEN
	                        //     #nState := #c2500_StepCheckVario;
	                        // ELSIF #arInOutJamFinger[1].stCarrData.xOnline AND NOT #xInRequest AND #fbStateManager.tOutTimeInStep > T#5000ms THEN
	                        //     #nState := #c3000_StepEmptying;
	                    END_IF;
	                END_IF;
	                
	            END_REGION
	            
	        #c1200_StepWaitTime:
	            REGION 1200: Wait
	                // Aktueller Zustand
	                #sStateText := 'WAIT FOR TIMER';
	                #xSationStop := FALSE;// PRÜFEN 
	                //  #xReleaseReq := FALSE;
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                #xReleaseStation := FALSE;
	                
	                
	                IF #fbStateManager.tOutTimeInStep > #stInSettings.tWaitForJog (* AND NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms *)THEN
	                    IF #xInRequest THEN
	                        #xClearDone := FALSE;
	                        #nState := #c3000_StepEmptying(* #c2000_StepJog *);
	                        
	                    ELSIF NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#2s  THEN
	                        #nState := #c3000_StepEmptying;
	                        (* ELSE
	                             #nState := #c3000_StepEmptying; *)
	                    END_IF;
	                END_IF;
	            END_REGION
	            
	            
	             #c2000_StepJog:
	                 REGION 2000: Jog
	                     
	                    
	                     
	                     // Aktueller Zustand
	                     #sStateText := 'JOG';
	                     
	                     // Statics
	                     #xRunMotor := TRUE;
	                     #xConveyorReady := FALSE;
	                     
	                     // IF #stInStationSensor.xDirectSensor AND #stInStationSensor.tDirectChangeLast< T#3000MS  THEN
	                         
	                     //     #xSationStop := TRUE;
	                     //     #xReleaseReq := TRUE;
	                     // END_IF; 
	                     
	                     IF #xTestMode OR #stInOutHMI.stControl.xTestMode THEN
	                         IF #stInSenConvFingerInPos.xDirectEdgePos THEN
	                             #nState := #c2200_StepNormalStop;
	                         END_IF;
	                     // ELSE
	                     //     IF (#fbStateManager.tOutTimeInStep > T#1000ms OR #fbFingerControl.xOutErrorRasterSensor) OR (#stInSenJam.xDirectSensor AND #stInSenLastPos.xDirectSensor)
	                     //         OR   #xSationStop
	                           
	                     //     THEN
	                     //         #nState := #c2250_StepQuickStop;
	                     //     ELSIF (#stInSenJam.xDirectEdgePos AND NOT #stInSettings.xJamSenDelayActive)
	                     //         OR (#stInSettings.xJamSenDelayActive AND #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > #stInSettings.tJamSenDelay)
	                     //     THEN
	                     //         #nState := #c2200_StepNormalStop;
	                     //     ELSIF #stInSenConvFingerInPos.xDirectEdgePos THEN //////EMBI TEST
	                     //         #nState := #c0200_StepReceive;
	                     //     END_IF;
	                     END_IF;
	                     
	                 END_REGION 
	            
	        #c2200_StepNormalStop: //normal anhalten
	            REGION 2200: Normal Stop
	                
	                // Aktueller Zustand
	                #sStateText := 'NORMAL STOP';
	                
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                
	                #xConveyorReady := FALSE;
	                IF #stInStationSensor.xDirectSensor AND #stInStationSensor.tDirectChangeLast < T#3000MS THEN
	                    
	                    // #xSationStop := TRUE;
	                    #xReleaseReq := TRUE;
	                END_IF;
	                
	                
	                IF #xTestMode OR #stInOutHMI.stControl.xTestMode THEN
	                    
	                    IF #tOn_WaitForStop.Q THEN
	                        #nState := #c0200_StepReceive;
	                    END_IF;
	                    
	                ELSE
	                    IF NOT #xReleaseReq THEN
	                        IF (NOT #stInSenLastPos.xDirectSensor AND #stInSenLastPos.tDirectChangeLast > T#2s AND #stInSenJam.xDbncdSensor) OR
	                            (NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms) THEN
	                            #nState := #c5000_StepEnding;
	                        END_IF;
	                    ELSE
	                        IF
	                            ((NOT #stInSenLastPos.xDirectSensor AND #stInSenLastPos.tDirectChangeLast > T#2s AND #stInSenJam.xDbncdSensor) OR
	                            (NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms)) AND #xInReleaseStation THEN
	                            #nState := #c5000_StepEnding;
	                        END_IF;
	                    END_IF;
	                    
	                END_IF;
	                
	                
	            END_REGION
	            
	        #c2250_StepQuickStop:
	            REGION 2250: Quick Stop
	                
	                // Aktueller Zustand
	                #sStateText := 'QUICK STOP';
	                
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	              
	                
	                IF NOT #xSationStop THEN
	                    
	                    IF ((NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms) OR
	                        (NOT #stInSenLastPos.xDirectSensor AND #stInSenLastPos.tDirectChangeLast > T#3000ms)) AND
	                        NOT #fbFingerControl.xOutErrorRasterSensor
	                    THEN
	                        #nState := #c1200_StepWaitTime;
	                        
	                        
	                    END_IF;
	                ELSE
	                    #nState := #c8000_StepScan;
	                    #xReleaseReq := TRUE;
	                    
	                    (*  IF  (NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms)(* OR
	                          (NOT #stInSenLastPos.xDirectSensor AND #stInSenLastPos.tDirectChangeLast > T#3000ms) *) AND
	                        NOT #fbFingerControl.xOutErrorRasterSensor AND #xReleaseStation
	                    THEN
	                        #nState := #c1200_StepWaitTime;
	                        
	                        
	                    END_IF; *)
	                    
	                    
	                END_IF;
	            END_REGION
	            
	        #c3000_StepEmptying:
	            REGION 3000: Emptying
	                
	                IF #stInStationSensor.xDirectSensor AND #stInStationSensor.tDirectChangeLast < T#500MS THEN
	                    
	                    #xSationStop := TRUE;
	                    // #xReleaseReq := TRUE;
	                END_IF;
	                
	                // Aktueller Zustand
	                #sStateText := 'EMPTYING CONVEYOR';
	                
	                // Statics
	                
	                    #xRunMotor := TRUE;
	                    #xConveyorReady := FALSE;
	                
	                
	                /////////////////////                                                   ////TEST ///
	                //
	                
	                
	                IF (#stInSenJam.xDirectSensor AND #stInSenLastPos.xDirectSensor) OR #xSationStop THEN
	                    #nState := #c2250_StepQuickStop;
	                ELSIF #xBeladenError THEN
	                    #nState := 9999;
	                    
	                ELSIF (#stInSenJam.xDirectEdgePos AND NOT #stInSettings.xJamSenDelayActive)
	                    OR (#stInSettings.xJamSenDelayActive AND #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > #stInSettings.tJamSenDelay)
	                THEN
	                    #nState := #c2200_StepNormalStop;
	                ELSIF #xInRequest AND #xReleaseReq THEN
	                    #xClearDone := FALSE;
	                    #nState := #c5000_StepEnding;
	                ELSIF #tOnAllBtOut.Q THEN
	                    #xClearDone := TRUE;
	                    #nState := #c5000_StepEnding;
	                    // ELSIF #tOnAllBtOut.Q THEN // Freigabe zum Entleeren ist wieder/noch da und Carousel-Motor läuft
	                    //     // Wenn nach einer gewissen Zeit nichts mehr kommt --> Alle Bt draußen --> Kette leer
	                    //     #nState := #c5000_StepEnding;                    // Weiter
	                END_IF;
	                ///////////////////
	                
	            END_REGION
	            
	        #c5000_StepEnding:
	            REGION 5000: Ending Step
	                
	                (*Dieser Schritt wird nur nach dem Entleeren angesprungen
	                 damit sich die Kette zum Schluss noch richtig positioniert*)
	                
	                //Aktueller Zustand
	                
	                
	                #sStateText := 'STOPPING CONVEYOR';
	                
	                //Statics
	                #xRunMotor := TRUE;
	                #xConveyorReady := FALSE;
	                #xReleaseReq := FALSE;
	                
	                // Transition
	                IF (#stInSenJam.xDirectSensor AND #stInSenLastPos.xDirectSensor) OR (#fbStateManager.tOutTimeInStep > T#1000ms OR #fbFingerControl.xOutErrorRasterSensor) THEN
	                    #xClearDone := FALSE;
	                    #nState := #c2250_StepQuickStop;
	                ELSIF #stInSenConvFingerInPos.xDirectEdgePos  (* AND #stInStationSensor.xDirectSensor *) (*or #fbStateManager.tOutTimeInStep > T#800ms OR *) (* #stInSenLastPos.xDirectEdgePos *)(* #stInSenConvFingerInPos.xDirectSensor *)THEN
	                    #nState := #c0200_StepReceive;
	                ELSIF (#stInSenJam.xDirectEdgePos AND NOT #stInSettings.xJamSenDelayActive)
	                    OR (#stInSettings.xJamSenDelayActive AND #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > #stInSettings.tJamSenDelay)
	                THEN
	                    #nState := #c2200_StepNormalStop;
	                END_IF;
	                
	            END_REGION
	        #c8000_StepScan: //StartScan 
	            REGION 8000: Start Scan 
	                
	                #sStateText := ' Start Scan';
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                
	                
	                
	                IF #xReadyForScan THEN
	                    
	                    #xStartScanBarcode := TRUE;
	                    #xHandShakeScan := FALSE;
	                    
	                END_IF;
	                
	                
	                IF #xReadingDone THEN
	                    
	                    #xStartScanBarcode := FALSE;
	                    
	                    
	                    
	                    #nState := #c8001_WaitingForRelease;
	                    #xHandShakeScan := TRUE;
	                    
	                    
	                END_IF;
	                
	            END_REGION
	            
	            
	        #c8001_WaitingForRelease:
	            REGION 8001: WaitingForRelease
	                
	                #sStateText := 'Waiting For Release ';
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                
	                IF #xInReleaseStation THEN
	                    #xReleaseStation := TRUE;
	                END_IF;
	                
	                
	                
	                
	                
	                IF (NOT #stInSenJam.xDirectSensor AND #stInSenJam.tDirectChangeLast > T#3000ms)(* OR
	                        (NOT #stInSenLastPos.xDirectSensor AND #stInSenLastPos.tDirectChangeLast > T#3000ms) *)AND
	                    NOT #fbFingerControl.xOutErrorRasterSensor AND #xReleaseStation
	                THEN
	                    
	                    #nState := #c1200_StepWaitTime;
	                END_IF;
	                
	            END_REGION
	            
	            
	            
	            
	            
	            
	            
	        9999: //Beladen Error
	            REGION 9999: Beladen Error
	                
	                #sStateText := 'beladen Error ';
	                #xRunMotor := FALSE;
	                #xConveyorReady := FALSE;
	                #xResetLed := TRUE;
	                
	                IF NOT #xBeladenError AND #xResetBeladen THEN
	                    #xResetLed := FALSE;
	                    #nState := #c3000_StepEmptying;
	                ELSIF
	                    #xBeladenError AND #xResetBeladen THEN
	                    #xResetLed := TRUE;
	                ELSIF
	                    NOT #xBeladenError AND NOT #xResetBeladen THEN
	                    
	                    #xResetLed := #FB_Blinker.xOutput;
	                    
	                END_IF;
	                
	                
	                
	                
	                
	            END_REGION
	            
	            REGION Blinker 
	                #FB_Blinker(tInPeriodicTime := T#500ms,
	                            xInActivate := 1);
	            END_REGION
	            
	            
	            
	            
	    END_CASE;
	END_REGION
	
	REGION Timer
	    
	    //??????????????????????????
	    #tOn_ErrorConv(IN := (#nState = #c0200_StepReceive OR #nState = #c3000_StepEmptying) AND NOT #stInSettings.xContinousEmptying,
	                   PT := T#60s);
	    
	    // Kette wird entleert... wenn nach PT sekunden (z.b. 5 sec) nichts mehr am FullSensor vorbeikommt, wird das Entleeren beendet (die Kette ist also leer)
	    // Jedesmal wenn ein Bt den FullSensor passiert oder das Entleeren pausiert wird, wird der Timer neu gestartet 
	    
	    #tOnAllBtOut(IN := #nState = #c3000_StepEmptying(* AND #xInRelease *),
	                 PT := #stInSettings.tConvEmpty);
	    
	    #tOn_WaitForStop(IN := #nState = #c2200_StepNormalStop,
	                     PT := #stInSettings.tWaitForStop);
	    
	END_REGION
	
	REGION Carrier zählen
	    
	    
	    #counterCarrier(CU := #xInReleaseEdge,
	                    R := #nState > #c0200_StepReceive,
	                    PV := #stInSettings.nCountCarrier,
	                    CV => #nCounterCatch);
	    
	END_REGION
	
	REGION Überwachung Finger
	    
	    #fbFingerControl.stInSettings.xInEnableSupervision := TRUE;
	    #fbFingerControl.stInSettings.tInDelayMotorRun := #stInSettings.tRasterDelayMotorRun;
	    #fbFingerControl.stInSettings.tInRasterHigh := #stInSettings.tRasterHigh;
	    #fbFingerControl.stInSettings.tInRasterLow := #stInSettings.tRasterLow;
	    #fbFingerControl(stInSenRaster := #stInSenConvFingerInPos,
	                     xInErrorQuit := #xInErrorQuit,
	                     xInMotorRun := #xRunMotor);
	    
	END_REGION
	
	REGION StateManager
	    
	    #fbStateManager.stInSettings.nStartState := #c0200_StepReceive;
	    #fbStateManager.stInSettings.xActUnivTOn := TRUE;
	    #fbStateManager.stInSettings.xRestartAtStartState := FALSE;
	    #fbStateManager(xInFunctionEnabled := ((#xInAutomatic AND #stInOutControlUnitCabinet.xRunning) OR #stInOutHMI.stConveyor.xSemiAuto) AND NOT #stInOutHMI.stConveyor.xDisableConveyor AND NOT #fbFingerControl.xOutErrorRasterSensor,
	                    xInRunUnivTOn := #tmpActUnivTon,
	                    nOutStateLast => #nStateLast,
	                    nInOutState := #nState);
	END_REGION
	
	REGION Ausgänge
	    
	    // Das ist der Motor vom Förderer
	    #xOutMotor := #xRunMotor OR #stInOutHMI.stConveyor.xManual;  // Förderer-Motor angefordert und kein Bereichshalt
	    #xOutConveyorReady := #xConveyorReady; //Förderer bereit (aus SK) und kein Bereichshalt Förderer
	    
	    //????????????????????????????
	    #xOutConveyorReleaseReq := #nState = #c3000_StepEmptying OR #nState = #c1200_StepWaitTime;
	    
	END_REGION
	
	REGION Visu
	    #stInOutHMI.stConveyor.nType := 7; // Vario
	    
	    #stInOutHMI.stConveyor.nState := #nState;
	    #stInOutHMI.stConveyor.sStateText := #sStateText;
	    
	    #stInOutHMI.FingerSensor := #stInSenConvFingerInPos;
	    #stInOutHMI.JamSensor := #stInSenJam;
	    #stInOutHMI.LastPosSensor := #stInSenLastPos;
	    
	    REGION Status
	        IF #xInMotorProtection THEN
	            IF #fbStateManager.xInFunctionEnabled THEN
	                CASE #nState OF
	                    #c0000_StepOff:
	                        #stInOutHMI.stConveyor.bStatus := 0; // NOT_AVAILABLE
	                    #c0200_StepReceive, #c1200_StepWaitTime, #c2000_StepJog, #c2250_StepQuickStop, #c2200_StepNormalStop, #c3000_StepEmptying, #c5000_StepEnding:
	                        #stInOutHMI.stConveyor.bStatus := 1; // AVAILABLE
	                    ELSE  //Fallback
	                        #stInOutHMI.stConveyor.bStatus := 0; // NOT_AVAILABLE
	                END_CASE;
	            ELSE
	                #stInOutHMI.stConveyor.bStatus := 0; // NOT_AVAILABLE
	            END_IF;
	        ELSE
	            #stInOutHMI.stConveyor.bStatus := 2; // ERROR
	        END_IF;
	    END_REGION
	    REGION Modes
	        // Int16 Bit-codiert
	        #stInOutHMI.stConveyor.nMode.%X0 := (#nState = #c0000_StepOff) OR (#nState = #c0100_StepUndefined) OR (#nState = #c0200_StepReceive) OR (#nState = #c1200_StepWaitTime) OR (#nState = #c2200_StepNormalStop) OR (#nState = #c2250_StepQuickStop); // The device is turned off
	        #stInOutHMI.stConveyor.nMode.%X1 := (#nState = #c2000_StepJog) OR (#nState = #c3000_StepEmptying) OR (#nState = #c5000_StepEnding);
	        #stInOutHMI.stConveyor.nMode.%X2 := #stInOutHMI.stConveyor.xDisableConveyor OR #stInOutHMI.stConveyor.xManual OR #stInOutHMI.stConveyor.xSemiAuto OR #xTestMode OR #stInOutHMI.stControl.xTestMode (* OR #xViSuManualMode OR #xViSuSemiAutoMode *); // The device is being manually operated
	        #stInOutHMI.stConveyor.nMode.%X3 := FALSE;//(#nState = #STOPPED); //The device only is on when the device is needed (like standby)
	        #stInOutHMI.stConveyor.nMode.%X10 := FALSE; // Overflow Error is set for this device
	    END_REGION
	    #stInOutHMI.stConveyor.xIsInAutomatic := #stInOutControlUnitCabinet.xRunning;
	    #stInOutHMI.stConveyor.xEnergySaveReq := FALSE;
	    #stInOutHMI.stConveyor.xPowerContactor := #xOutMotor;
	    #stInOutHMI.stConveyor.xPluggedChainBreak := FALSE;
	    #stInOutHMI.stConveyor.xStatusChainBreak := TRUE;
	    #stInOutHMI.stConveyor.xStatusMotorProtect := #xInMotorProtection;
	    #stInOutHMI.stConveyor.xConveyorFull1 := FALSE;
	    #stInOutHMI.stConveyor.xConveyorFull2 := FALSE;
	    #stInOutHMI.stConveyor.xReady2Receive := TRUE;
	    #stInOutHMI.stConveyor.xNextConveyorReady := TRUE;
	    
	END_REGION
	
	REGION Monitoring
	    
	    #fbMonitoringFinger.stSettings.nErrorType := 1;
	    #fbMonitoringFinger.stSettings.xErrLedIfMachineIsOff := TRUE;
	    #fbMonitoringFinger.stSettings.xSelfQuit := TRUE;
	    #fbMonitoringFinger.stSettings.tDelay := T#1s;
	    #fbMonitoringFinger(sInFctnName := #stInOutHMI.stConveyor.sConveyorName,
	                        sInPrefix := 'Fingerueberwachung',
	                        sInSuffix := #stInOutHMI.FingerSensor.sName,
	                        wInTextListId_Function := 300,
	                        wInTextListId_Message := 301,
	                        xInQuitError := #stInOutControlUnitCabinet.xQuitError OR #xInErrorQuit,
	                        xInSignal := NOT #fbFingerControl.xOutErrorRasterSensor,
	                        sInAlarmMessage := 'Fingerfehler',
	                        InOutMachineState := #stInOutControlUnitCabinet);
	END_REGION
END_FUNCTION_BLOCK

