FUNCTION_BLOCK "CpuZylZt" { S7_Optimized_Access := 'FALSE' } AUTHOR : FSI VERSION : 1.1 VAR_INPUT I_Rst : Bool; // Reset I_ZylZtSreg : Any; // Schieberegister für Zykluszeiten "I_STIME.tx" : DWord; // Zeit END_VAR VAR_OUTPUT O_ZylZtMin : Time := t#10h; // minimale gemessene Zykluszeit O_ZylZtMax : Time := t#0ms; // maximal gemessene Zykluszeit O_ZylZtAv : Time := t#0ms; // durschnittlich gemessene Zykluszeit O_ZylZt : Time := t#0ms; // zuletzt gemessene Zykluszeit O_SysZt : Time := t#0ms; // Laufzeit seit dem letzten Start O_SysTg : Int := 0; // Anzahl der Tage seit dem letzten Start O_Zyl : DWord := 0; // Anzahl der Zyklen seit dem letzten Start END_VAR VAR zylZt : Time; // zuletzt gemessene Zykluszeit tx : Time; // aktuelle Systemzeit init : Bool; // Baustein inizialisiert anyFlt : Word; // Infos des Schieberegisters ZylZtSum : Time; // Fehler beim Bestimmen der Länge i : Int; // ermittelte Länge des AnyPointers i_init : Bool; tmpUdt : "CpuZylZt.T_ZylZt"; // Summe der Zykluszeiten oldVal : "CpuZylZt.T_ZylZt"; cyclNrs : DInt; // Laufvariable für Schieberegister END_VAR VAR_TEMP TOP_SI : Struct EV_CLASS : Byte; EV_NUM : Byte; PRIORITY : Byte; NUM : Byte; TYP2_3 : Byte; TYP1 : Byte; ZI1 : Word; ZI2_3 : DWord; END_STRUCT; START_UP_SI : Struct EV_CLASS : Byte; EV_NUM : Byte; PRIORITY : Byte; NUM : Byte; TYP2_3 : Byte; TYP1 : Byte; ZI1 : Word; ZI2_3 : DWord; END_STRUCT; err : Int; END_VAR BEGIN (*################################################################################################# Copyright (c) Fondium Singen GmbH ### Änderungshistorie ### Datum: Version: Bearbeiter: Beschreibung: 23.09.2019 0.0 St. Maier Neuerstellung 24.09.2019 0.1 St. Maier Durchschittsberechnung der Zykluszeit angepasst 24.09.2019 1.0 St. Maier Überarbeitung des Baustein, damit nicht Baustein für Verlängerung des Schieberegisters angepasst werden muss sondern nur der dazugehörige DB 11.10.2019 1.1 St. Maier Überarbeitung Kopf damit TIA kompatibel 15.10.2019 2.0 St. Maier Überarbeitung des Baustein, damit nicht Baustein für Verlängerung des Schieberegisters oder Anpassung des UDT angepasst werden muss. 17.10.2019 2.1 St. Maier I_STIME Eingefügt, damit keine Abhängigkeit zu einem IDB besteht 18.10.2019 2.2 St. Maier Variablen Kommentare eingefügt - wurden bei der Portierung nach TIA nicht übernommen 18.10.2019 2.3 St. Maier O_ZylZtMin Defaultwert auf t#10h gesetzt,ansonsten wird min. Zykluszeit von 0 ms angezeigt 24.10.2019 3.0 St. Maier Überarbeitung Schieberegister 10.02.2021 3.1 St. Maier Probleme mit Zeitwert im negativen Bereich behoben #################################################################################################*) (*################################### Baustein Beschreibung ####################################### Abhängigkeiten (von anderen Fuktionen und Quellen): - RD_SINFO - CpuZeit - Any.Lng - Any.Struct Inputs: - I_Rst : Reset - I_ZylZtShiftReg : Schieberegister für Zykluszeiten Outputs: - O_ZylZtMin: minimale gemessene Zykluszeit - O_ZylZtMax: maximal gemessene Zykluszeit - O_ZylZtAv : durschnittlich gemessene Zykluszeit - O_ZylZt : zuletzt gemessene Zykluszeit - O_SysZt : Laufzeit seit dem letzten Start - O_SysTg : Anzahl der Tage seit dem letzten Start - O_Zyl : Anzahl der Zyklen seit dem letzten Start In-\Outputs: - Return-Value: - Funktionsbeschreibung: Dies Funktion überacht die Zykluszeiten der SPS und stellt eine Reihe von Informationen über Zykluszeiten und Laufzeiten zur Verfügung. #################################################################################################*) (* aktuelle Startinformationen auslesen *) (* OB1_SCAN_1 BYTE - B#16#01: Abschluss des Neustarts (Warmstarts) - B#16#02: Abschluss des Wiederanlaufs - B#16#03: Abschluss des freien Zyklus - B#16#04: Abschluss des Kaltstarts - B#16#05: Erster OB 1-Zyklus der neuen Master-CPU nach Master-Reserve-Umschaltung und STOP des bisherigen Masters *) #err := RD_SINFO(TOP_SI => #TOP_SI // OUT: STRUCT , START_UP_SI => #START_UP_SI // OUT: STRUCT ); // INT // Zurücksetzen der letzten Zykluszeit bei System start IF #TOP_SI.EV_NUM <> 3 THEN #zylZt := t#0ms; END_IF; // Infos wie Array-Länge von Schieberegiaster bestimmen #anyFlt := "Any.Struct"(I_UDT := #tmpUdt , I_StartBitAndRange := #I_ZylZtSreg , O_DataCount => #cyclNrs ); #tx := DINT_TO_TIME(DWORD_TO_DINT("CpuZt"("I_STIME.tx" := #"I_STIME.tx"))) - #zylZt; IF #I_Rst THEN #O_ZylZtMin := t#10h; #O_ZylZtMax := t#0ms; #O_ZylZtAv := t#0ms; #ZylZtSum := t#0ms; #O_Zyl := 0; #i := 0; #i_init := false; RETURN; ELSIF #zylZt <> t#0ms THEN IF #tx < #O_ZylZtMin AND #tx > t#0ms THEN #O_ZylZtMin := #tx; ELSIF #tx > #O_ZylZtMax THEN #O_ZylZtMax := #tx; END_IF; #O_ZylZt := #tx; #tmpUdt.Zt := #tx; END_IF; IF #init THEN #O_SysZt := #O_SysZt + #tx; IF #O_SysZt >= t#1d THEN #O_SysZt := #O_SysZt - t#1d; #O_SysTg := #O_SysTg + 1; END_IF; END_IF; // Zähler zum durchlaufen des Registers IF #i >= DINT_TO_INT(#cyclNrs) - 1 THEN #i := 0; #i_init := true; ELSE #i := #i + 1; END_IF; // Daten aus Array abholen für Zykluszeitberechnung "UdtAryGet"(I_SrcAry := #I_ZylZtSreg, I_SrcIndex := #i, I_DesUdt := #oldVal, O_Ret => #err); // "alte" Zykluszeit subtrahieren IF #i_init = true THEN #ZylZtSum := #ZylZtSum - #oldVal.Zt; END_IF; // Daten kopieren "UdtArySet"(I_SrcUdt:=#tmpUdt, I_DestIndex:= #i, I_DestAry:=#I_ZylZtSreg, O_Ret=>#err); // Zykluszeiten addieren #ZylZtSum := #ZylZtSum + #tmpUdt.Zt; #init := TRUE; #zylZt := #zylZt + #tx; #O_Zyl := DINT_TO_DWORD(DWORD_TO_DINT(#O_Zyl) + 1); // Durchschnitts-Zykluszeit berechnen IF #i_init THEN #O_ZylZtAv := #ZylZtSum / (#cyclNrs - 1); ELSE #O_ZylZtAv := #ZylZtSum / (#i); END_IF; END_FUNCTION_BLOCK