FUNCTION_BLOCK "FB_PerfTest"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      nInSepNo : Int;   // Nummer welche hinter Sep-Konstante steckt
      xInSepFlag : Bool;   // Flanke vom Release pro MiniTrolley
      xInReset : Bool;
      tInTimeMeasurement : Time := T#86400s;   // Default 24h
      nInGoalFlags : Int;   // Anzahl der Releases welche Messung stoppen
   END_VAR

   VAR 
      tOnTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'; S7_SetPoint := 'False'} : TON_TIME;
      xTestActive : Bool;   // true = Messung läuft
      xTimerRun : Bool;   // Signal für Timer
      nCount : Int;   // MiniTrolleys pro Sep während Messung
      Date_And_TimeStart : Date_And_Time;   // Beginn mit erstem MiniTrolley
      Date_And_TimeLap : Date_And_Time;   // Zeit bei jedem weiteren MiniTrolley
      tTimeResult : Time;   // jeweiliges Ergebnis
      rTrigRun {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
      fTrigRun {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG;
      fTrigSepFlag {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG;
   END_VAR
   VAR RETAIN
      arTrolley : Array[1..500] of Struct
         nCountNo : Int;   // Aktuelle Schaltung
         tTimeEvent : Date_And_Time;   // Zeitstempel bei Release
         tTimeResult : Time;   // Differenz seit Start
      END_STRUCT;
      nTrolleyNo : Int;   // aktuelle Zeile in Array in welche geschrieben wird
   END_VAR

   VAR_TEMP 
      nTmpTimeReturn : Int;
      nIdx : Int;
   END_VAR


BEGIN
	IF #nTrolleyNo = 0 THEN
	    #nTrolleyNo := 1;
	END_IF;
	
	REGION Flanken erfassen
	    #rTrigRun(CLK := #xTestActive);
	    #fTrigRun(CLK := #xTestActive);
	    #fTrigSepFlag(CLK := #xInSepFlag);
	END_REGION
	
	REGION Nullen bei neuer Messung
	    IF #xInReset THEN
	        #Date_And_TimeLap := DT#1990-01-01-00:00:00;
	        #Date_And_TimeStart := DT#1990-01-01-00:00:00;
	        #tTimeResult := T#0s;
	        #nTrolleyNo := 1;
	        FOR #nIdx := 1 TO 500 DO
	            #arTrolley[#nIdx].nCountNo := 0;
	            #arTrolley[#nIdx].tTimeEvent := DT#1990-01-01-00:00:00;
	            #arTrolley[#nIdx].tTimeResult := T#0s;
	        END_FOR;
	    ELSIF #rTrigRun.Q THEN
	        #Date_And_TimeLap := DT#1990-01-01-00:00:00;
	        #Date_And_TimeStart := DT#1990-01-01-00:00:00;
	        #tTimeResult := T#0s;
	        #nTrolleyNo := 1;
	        #xTimerRun := TRUE;
	    END_IF;
	END_REGION
	
	REGION Sep-Flanken während Messung erfassen
	    //Während Messtimer läuft und 1. Flanke kommt, ermittle Zeit und schreibe sie weg und erhöhe Pos für nächste Zeile.
	    //Danach so weiter machen aber dann immer die Zeitdifferenz wegschreiben
	    IF #tOnTimer.ET > T#0s AND #tOnTimer.ET < #tInTimeMeasurement AND #fTrigSepFlag.Q THEN
	        IF #nTrolleyNo = 1 THEN //Nur beim ersten Trolley die Startzeit ermitteln
	            #nTmpTimeReturn := RD_SYS_T(#Date_And_TimeStart);
	        END_IF;
	        #nTmpTimeReturn := RD_SYS_T(#Date_And_TimeLap); //Flankenzeitpunkt für Differenz aus diesem und Startzeitpunkt
	        #tTimeResult := T_DIFF(IN1 := #Date_And_TimeLap, IN2 := #Date_And_TimeStart);
	        //Daten wegschreiben
	        #arTrolley[#nTrolleyNo].nCountNo := #nTrolleyNo;
	        #arTrolley[#nTrolleyNo].tTimeEvent := #Date_And_TimeLap;
	        #arTrolley[#nTrolleyNo].tTimeResult := #tTimeResult;
	        //erhöhen für nächste Zeile oder beende Messung
	        IF #nTrolleyNo <= #nInGoalFlags THEN
	            #nTrolleyNo += 1;
	        ELSIF #tOnTimer.ET >= #tInTimeMeasurement OR #fTrigRun.Q OR #nTrolleyNo > #nInGoalFlags THEN
	            #xTimerRun := FALSE;
	            #xTestActive := FALSE;
	        END_IF;
	        
	    END_IF;
	    IF #tOnTimer.ET >= #tInTimeMeasurement OR #fTrigRun.Q OR #nTrolleyNo > #nInGoalFlags THEN
	        #xTimerRun := FALSE;
	        #xTestActive := FALSE;
	    END_IF;
	END_REGION
	
	REGION Timer
	    #tOnTimer(IN := #xTimerRun,
	              PT := #tInTimeMeasurement);
	END_REGION
	
END_FUNCTION_BLOCK

