FUNCTION_BLOCK "FB_StateManager" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT stInSettings : Struct nStartState : Int := 100; // State auf den als erstes gesprungen wird wenn xFunctoinEnable = TRUE nStartStateTestMode : Int; xRestartAtStartState : Bool; // TRUE: Wird der Baustein wieder aktiviert wird der State der unter "Settings.nStartState" angegeben ist angesprungen. False: Alter State wird wieder angesprungen xActUnivTOn : Bool; END_STRUCT; xInFunctionEnabled : Bool; // nState springt auf 0 wenn FALSE, und zurück zum Ursprung bei TRUE xInReset : Bool; xInRunUnivTOn : Bool; xInTimerReset : Bool; xInTestMode : Bool; END_VAR VAR_OUTPUT nOutStateLast : Int; xOutStepchange : Bool; // einen Zyklus True bei Schrittwechel. Kommt nicht beim Wechel in State = 0 aus State = 0 tOutTimeInStep : Time; // Zeit wie lange schon im Schritt, wird bei Stepchange zurückgesetzt tOutUnivTonR : Time; // Gibt eine hochzählende Zeit aus die z.B. in Schrittketten verwendet werden kann END_VAR VAR_IN_OUT nInOutState : Int; END_VAR VAR RETAIN nStateBeforeError : Int := 100; nStateLast : Int := 100; arHistory : Array[0..50] of Int; END_VAR VAR arHistoryAdv : Array[0..#cSizeHistoryAdv] of Struct nStepNum : Int; tTimeStamp {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; END_STRUCT; END_VAR VAR RETAIN nPosHistory : USInt; tOnrTimeInStep {InstructionName := 'TONR_TIME'; LibVersion := '1.0'} : TONR_TIME; tOnrUnivTimer {InstructionName := 'TONR_TIME'; LibVersion := '1.0'} : TONR_TIME; tOnUnivTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME; xStepchange : Bool; END_VAR VAR R_TRIG_TestMode {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG; F_TRIG_TestMode {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG; R_TRIG_FunctionEn {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG; END_VAR VAR_TEMP t_Status : Int; END_VAR VAR CONSTANT cSizeHistory : USInt := 50; cSizeHistoryAdv : UInt := 200; END_VAR BEGIN // #R_TRIG_TestMode(CLK := #xInTestMode); // #F_TRIG_TestMode(CLK:=#xInTestMode); //#R_TRIG_FunctionEn(CLK := #xInFunctionEnabled); REGION Reset IF #xInReset (* OR "FirstScan" *) (* OR #R_TRIG_TestMode.Q OR #F_TRIG_TestMode.Q *) THEN //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #nInOutState := 0; #nStateLast := #stInSettings.nStartState; #nStateBeforeError := #stInSettings.nStartState; END_IF; END_REGION REGION Stephistory schreiben IF #nInOutState <> #nStateLast AND #nInOutState <> 0000 THEN #arHistory[#nPosHistory] := #nInOutState; IF #nPosHistory >= #cSizeHistory THEN #arHistory[0] := 9999; #nPosHistory := 0; ELSE #arHistory[#nPosHistory + 1] := 9999; #nPosHistory += 1; END_IF; END_IF; END_REGION REGION Stephistory mit Zeitstempel // IF // #nInOutState <> #nStateLast // THEN // #t_Status := MOVE_BLK_VARIANT(SRC := #"arHistoryAdv", // COUNT := #cSizeHistoryAdv, // SRC_INDEX := 0, // DEST_INDEX := 1, // DEST => #"arHistoryAdv"); // #t_Status := RD_LOC_T(#"arHistoryAdv"[0].tTimeStamp); //Zeitstempel // #"arHistoryAdv"[0].nStepNum := #nInOutState; // #nStateLast := #nInOutState; // END_IF; END_REGION REGION Ein- und Ausschalten //Bei Ein - Auschalten in Schritt 0 und zurück wechseln IF NOT #xInFunctionEnabled AND #nInOutState <> 0000 THEN #nStateBeforeError := #nInOutState; #nInOutState := 0000; ELSIF #xInFunctionEnabled AND #nInOutState = 0000 THEN IF #stInSettings.xRestartAtStartState THEN #nInOutState := #stInSettings.nStartState; ELSE #nInOutState := #nStateBeforeError; END_IF; END_IF; END_REGION REGION Stepchange IF #nInOutState <> #nStateLast THEN IF #nInOutState <> 0000 THEN #nStateLast := #nInOutState; IF #nStateLast <> 0000 THEN #xStepchange := TRUE; END_IF; END_IF; ELSE #xStepchange := FALSE; END_IF; END_REGION REGION Timer #tOnrTimeInStep(IN := #nInOutState <> 0000, PT := T#+24d_20h_31m_23s, //Max Zeit für "Time" R := #xStepchange OR #xInReset); IF #stInSettings.xActUnivTOn THEN #tOnrUnivTimer(IN := #xInRunUnivTOn, PT := T#+24d_20h_31m_23s); //Max Zeit für "Time" IF #xInReset OR #xInTimerReset THEN RESET_TIMER(#tOnrUnivTimer); END_IF; END_IF; END_REGION REGION Ausgänge schreiben #xOutStepchange := #xStepchange; #tOutTimeInStep := #tOnrTimeInStep.ET; #nOutStateLast := #nStateLast; IF #stInSettings.xActUnivTOn THEN #tOutUnivTonR := #tOnrUnivTimer.ET; ELSE #tOutUnivTonR := T#0S; END_IF; END_REGION END_FUNCTION_BLOCK