FUNCTION_BLOCK "FB_StateMain" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT xInBtnMachineOn : Bool; // Anlage Ein xInBtnMachineNotOff : Bool; // Anlage Aus xInBtnLightTest : Bool; // Lampentest xInBtnTrigMot : Bool; // Trig Mot xInBtnQuitError : Bool; // Start nach Störung xInAllReadyToStart : Bool; // Alles bereit xInAllInExecute : Bool; // Alle Antriebe in Run xInAllStarted : Bool; // Starten erfolgreich beendet xInSafetyActive : Bool; // Safety aktiv xInAllInSafeState : Bool; // Alles im sicheren Status stSettings : Struct // Einstellungen tCancelStarting : Time := t#10s; xEnableStartUpWarning : Bool; xPressMachineOnAllTime : Bool; tStartUpTime : Time := T#3s; END_STRUCT; END_VAR VAR_IN_OUT stInOutControlUnitCabinet : "UDT_MainState"; // Schnittstelle MainState stInOutHMI : "UDT_HMI_StateMachine"; // NUR FÜR HMI END_VAR VAR nState : Int := -10; // Schritt sStateText : String; // Schritttext tOnStartUpTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME; // Anlaufverzögerung nConveyorStartUpCounter : Int; // Counter Förderer xQuitErrorFlag : Bool; // Start nach Störung Flag stControl : Struct // Start,Stop,Quit xStart : Bool; xStop : Bool; xQuitt : Bool; END_STRUCT; END_VAR VAR_TEMP nCounter : Int; nNoStartingAct : Int; END_VAR BEGIN REGION MainStateMachine CASE #nState OF "E_DeviceState.eUndefined": REGION Undefined #sStateText := 'StartUp'; #nState := "E_DeviceState.eStopped"; END_REGION ; "E_DeviceState.eStopped": REGION Stopped #sStateText := 'Stopped'; IF #xInAllReadyToStart AND NOT #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eIdle"; END_IF; #stInOutControlUnitCabinet.xStopMachine := FALSE; END_REGION ; "E_DeviceState.eIdle": REGION IDLE #sStateText := 'Idle'; IF NOT #xInAllReadyToStart OR #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eStopped"; ELSIF (#xInBtnMachineOn OR #stInOutHMI.xStart OR #stControl.xStart)AND (((#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) THEN #nState := "E_DeviceState.eStarting"; #stControl.xStart := FALSE; END_IF; END_REGION ; "E_DeviceState.eStarting": REGION Starting #sStateText := 'Start UP Warning Time'; IF NOT #xInAllReadyToStart OR #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eStopped"; ELSIF #xInAllStarted AND (NOT #stSettings.xEnableStartUpWarning OR (#stSettings.xEnableStartUpWarning AND #tOnStartUpTimer.Q)) THEN #nState := 120; ELSIF (NOT #xInBtnMachineOn AND #stSettings.xPressMachineOnAllTime) OR NOT #xInBtnMachineNotOff OR #tOnStartUpTimer.ET > #stSettings.tCancelStarting THEN #nState := "E_DeviceState.eStopping"; END_IF; END_REGION ; 120: REGION Waiting for All in Excecute #sStateText := 'Waiting for All in Execute'; IF #xInAllInExecute THEN #nState := "E_DeviceState.eExecute"; #nConveyorStartUpCounter := 0; ELSIF NOT ((#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) OR #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eStopping"; END_IF; END_REGION "E_DeviceState.eExecute": REGION Execute #sStateText := 'Execute'; IF NOT #xInSafetyActive THEN #nState := "E_DeviceState.eHolding"; #nConveyorStartUpCounter := 0; ELSIF NOT (#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) OR #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eStopping"; ELSIF FALSE THEN #nState := "E_DeviceState.eSuspending"; END_IF; IF #nConveyorStartUpCounter < 6000 THEN #nConveyorStartUpCounter := #nConveyorStartUpCounter + 1; ELSIF #xInBtnTrigMot THEN #nConveyorStartUpCounter := 0; END_IF; END_REGION ; "E_DeviceState.eHolding": #sStateText := 'HOLDING: When the machine is in the EXECUTE state the Hold command can be used to start HOLDING logic which brings the machine to a controlled stop or to a state which represents HELD for the particular machine mode. '; #nState := "E_DeviceState.eHeld"; "E_DeviceState.eHeld": REGION Held #sStateText := 'HELD: The HELD state would typically be used by the operator to hold the temporarily hold the machines operation whilst material blockages are cleared, or to stop throughput whilst a downstream problem is resolved.'; IF (NOT (#xInBtnMachineNotOff AND NOT #stInOutHMI.xStop)) OR #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eStopping"; ELSIF #xInSafetyActive THEN #nState := "E_DeviceState.eUnholding"; END_IF; END_REGION ; "E_DeviceState.eUnholding": REGION Unholding #sStateText := 'Un-Holding: The UNHOLDING state is typically a response to an operator command to resume EXECUTE state. UNHOLDING prepares the machine to re-enter the EXECUTE state.'; IF NOT #stSettings.xEnableStartUpWarning OR (#stSettings.xEnableStartUpWarning AND #tOnStartUpTimer.Q) THEN #nState := "E_DeviceState.eExecute"; END_IF; END_REGION "E_DeviceState.eSuspending": #sStateText := 'SUSPENDING: This state is a result of a command change from the EXECUTE state. This state is typically required prior to the SUSPENDED wait state, and prepares the machine (ie stops glue cycles, stops carton feeds, etc) prior to the SUSPEND state.'; #nState := "E_DeviceState.eSuspended"; "E_DeviceState.eSuspended": REGION Suspended #sStateText := 'SUSPENDED: The machine may be running at the relevant setpoint speed, there is no product being produced. This state can be reached as a result of a machine status, and differs from HELD in that HELD is typically a result of an operator request.'; IF NOT (#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) OR #stInOutControlUnitCabinet.xStopMachine THEN #nState := "E_DeviceState.eStopping"; ELSIF TRUE THEN #nState := "E_DeviceState.eUnsuspending"; END_IF; END_REGION ; "E_DeviceState.eUnsuspending": #sStateText := 'UN-SUSPENDING: This state is a result of a request from SUSPENDED state to go back to the EXECUTE state. This actions of this state may include: ramping up speeds, turning on vaccums, the re-engagement of clutches.'; (*IF NOT #xInSafetyOk THEN #nState := "E_DeviceState.eHolding"; ELSE *) #nState := "E_DeviceState.eExecute"; (* END_IF; *) "E_DeviceState.eStopping": REGION Stopping #sStateText := 'Stopping'; #nState := 5010; END_REGION 5010: #sStateText := 'Waiting for Safe State'; IF #xInAllInSafeState THEN #nState := "E_DeviceState.eStopped"; END_IF; END_CASE; END_REGION // REGION Global stop conditions IF (#nState > "E_DeviceState.eIdle") AND (#nState < "E_DeviceState.eStopping") AND NOT #xInAllReadyToStart THEN #nState := "E_DeviceState.eStopped"; END_IF; END_REGION REGION Timer #tOnStartUpTimer(IN := (#nState = "E_DeviceState.eStarting" OR #nState = "E_DeviceState.eUnholding"), PT := #stSettings.tStartUpTime); END_REGION REGION Outputs #stInOutControlUnitCabinet.xStartUpWarning := (#nState = "E_DeviceState.eStarting" OR (#nState = "E_DeviceState.eUnholding" AND #stSettings.xEnableStartUpWarning)) AND #stSettings.xEnableStartUpWarning AND "Clock_1Hz"; #stInOutControlUnitCabinet.xStarting := (#nState = "E_DeviceState.eStarting") OR (#nState = "E_DeviceState.eUnholding");// AND #stSettings.xEnableStartUpWarning; #stInOutControlUnitCabinet.xRunning := #nState > "E_DeviceState.eStarting" AND #nState <= "E_DeviceState.eUnholding"; #stInOutControlUnitCabinet.xMachineOnLed := (#nState > "E_DeviceState.eStarting" AND #nState < "E_DeviceState.eUnholding") OR #nState = "E_DeviceState.eStarting" AND "Clock_2.5Hz" OR #nState = "E_DeviceState.eUnholding" AND "Clock_2.5Hz"; #stInOutControlUnitCabinet.xQuitError := (NOT #xQuitErrorFlag AND #xInBtnQuitError) OR #stControl.xQuitt OR #stInOutHMI.xQuit; #stInOutControlUnitCabinet.xSafetyRequest := #nState >= "E_DeviceState.eStarting" AND #nState <= "E_DeviceState.eAborting"; #stInOutControlUnitCabinet.xSafetyActive := #xInSafetyActive; IF (NOT #xQuitErrorFlag AND #xInBtnQuitError) THEN #stInOutControlUnitCabinet.xError := 0; END_IF; #xQuitErrorFlag := #xInBtnQuitError; #stInOutControlUnitCabinet.xRestart := #nConveyorStartUpCounter < 6000 AND #nState = "E_DeviceState.eExecute"; END_REGION REGION Flags #xQuitErrorFlag := #xInBtnQuitError OR #stInOutHMI.xQuit; END_REGION REGION HMI #stInOutHMI.nStateStatus := #nState; // Für Anzeige END_REGION END_FUNCTION_BLOCK