FUNCTION_BLOCK "FB_MotorSimple_INBOUND"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      stInMachineState : "UDT_MainState";
      stInSettings : Struct
         tInRightAfter : Time := T#0ms;   // Nachlaufzeit rechts
         tInLeftAfter : Time := T#0ms;   // Nachlaufzeit links
      END_STRUCT;
      xInQuitErrorOpt : Bool := false;   // Optionaler Start-Nach-Störungs-Button
      xInSafetyOk : Bool := false;
      xInFuse : Bool := false;   // Alle Sicherung i.O.
      xInMotorOk : Bool := false;   // Statusbit von MoviMot
      sInFctnName : String := '';
      xInDriveRight : Bool := false;
      xInDriveLeft : Bool := false;
   END_VAR

   VAR_OUTPUT 
      xOutRight : Bool := false;
      xOutLeft : Bool := false;
      xOutEnable24V : Bool := false;
      xOutEnable400V : Bool := false;
      xOutError : Bool := false;
      xOutAckReq : Bool := false;
      xOutStatMtrLeft : Bool := false;
      xOutStatMtrRight : Bool := false;
      xOutMotOk : Bool := false;
   END_VAR

   VAR_IN_OUT 
      stInOutControlUnitCabinet : "UDT_MainState";
   END_VAR

   VAR RETAIN
      xRight : Bool := false;
      xLeft : Bool := false;
      tOfTimerRight {InstructionName := 'TOF_TIME'; LibVersion := '1.0'} : TOF_TIME;
      tOfTimerLeft {InstructionName := 'TOF_TIME'; LibVersion := '1.0'} : TOF_TIME;
      tOnMoviMotEnabled {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
      xQuitErrorFlag : Bool := false;
      xErrorQuitPosEdge : Bool := false;
   END_VAR
   VAR 
      fbSetAlarmAndLog : "FB_SetAlarmAndLog";
   END_VAR
   VAR RETAIN
      xError : Bool := false;
   END_VAR


BEGIN
	REGION Fahren
	    #xRight :=
	    #xInFuse AND
	    #xInSafetyOk AND
	    #stInMachineState.xRunning AND
	    NOT #xError AND
	    NOT #stInMachineState.xError AND
	    #tOfTimerRight.Q AND
	    NOT #tOfTimerLeft.Q AND
	    #xInMotorOk;
	    
	    #xLeft :=
	    #xInFuse AND
	    #xInSafetyOk AND
	    #stInMachineState.xRunning AND
	    NOT #xError AND
	    NOT #stInMachineState.xError AND
	    #tOfTimerLeft.Q AND
	    NOT #tOfTimerRight.Q AND
	    #xInMotorOk;
	    
	    #xOutEnable400V :=
	    #xOutEnable24V := #xInFuse AND
	    #xInSafetyOk AND
	    NOT #xError AND
	    #stInMachineState.xRunning AND
	    NOT #stInMachineState.xError;
	END_REGION
	
	REGION Fehler
	    
	    IF (#xInDriveLeft AND #xInDriveRight) THEN
	        #xError := TRUE;
	        #fbSetAlarmAndLog.nInAlarmNumber := 0;
	        #fbSetAlarmAndLog.xInAlarm := TRUE;
	        #fbSetAlarmAndLog.sInAlarmMessage := 'Motor Li und Re';
	    ELSE
	        #fbSetAlarmAndLog.xInAlarm := FALSE;
	    END_IF;
	    
	    IF NOT #xInFuse AND #stInMachineState.xRunning THEN
	        #xError := TRUE;
	        #fbSetAlarmAndLog.nInAlarmNumber := 1;
	        #fbSetAlarmAndLog.xInAlarm := TRUE;
	        #fbSetAlarmAndLog.sInAlarmMessage := 'Motorsicherung';
	    ELSE
	        #fbSetAlarmAndLog.xInAlarm := FALSE;
	    END_IF;
	    
	    IF #tOnMoviMotEnabled.ET > T#10S AND
	        NOT #xInMotorOk THEN
	        #xError := TRUE;
	        #fbSetAlarmAndLog.nInAlarmNumber := 2;
	        #fbSetAlarmAndLog.xInAlarm := TRUE;
	        #fbSetAlarmAndLog.sInAlarmMessage := 'Movimot Fehler';
	    END_IF;
	    
	END_REGION
	
	REGION Timer
	    #tOfTimerRight(IN := #xInDriveRight,
	                   PT := #stInSettings.tInRightAfter);
	    
	    #tOfTimerLeft(IN := #xInDriveLeft,
	                  PT := #stInSettings.tInLeftAfter);
	    
	    #tOnMoviMotEnabled(IN := #xOutEnable24V AND #xOutEnable400V,
	                       PT := T#1000s);
	    
	END_REGION
	
	REGION Fehler Quittieren
	    
	    IF #xErrorQuitPosEdge AND
	        #xInFuse AND
	        NOT (#xInDriveLeft AND #xInDriveRight) AND
	        #xError THEN
	        #xError := FALSE;
	    END_IF;
	    
	END_REGION
	
	REGION Flanke
	    #xErrorQuitPosEdge := (#stInMachineState.xQuitError OR #xInQuitErrorOpt) AND
	    NOT #xQuitErrorFlag;
	    #xQuitErrorFlag := #stInMachineState.xQuitError OR #xInQuitErrorOpt;
	END_REGION
	
	REGION Ausgänge schreiben
	    #xOutLeft := #xLeft;
	    
	    #xOutRight := #xRight;
	    
	    #xOutAckReq := #xError AND
	    NOT (#xInDriveLeft AND #xInDriveRight) AND
	    #xInFuse;
	    
	    #xOutError := #xError;
	    
	    #xOutStatMtrLeft := #xLeft AND #xInMotorOk;
	    
	    #xOutStatMtrRight := #xRight AND #xInMotorOk;
	    
	    #xOutMotOk := #stInMachineState.xRunning AND #xInSafetyOk AND #xInFuse;
	END_REGION
	
	REGION Monitoring
	    #fbSetAlarmAndLog.stSettings.nNoMaxErrors := 3;
	    #fbSetAlarmAndLog.stSettings.nType := 1;
	    #fbSetAlarmAndLog.stSettings.sFctnName := #sInFctnName;
	    #fbSetAlarmAndLog(stInOutControlUnitCabinet:= #stInOutControlUnitCabinet);
	END_REGION
END_FUNCTION_BLOCK

