Files
HundM_Fortna/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.scl
T
2026-06-29 16:28:48 +02:00

165 lines
5.4 KiB
Plaintext

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