94 lines
3.6 KiB
Markdown
94 lines
3.6 KiB
Markdown
|
|
### FB Scan Time ( FB1 )
|
|
***
|
|
This function needs to be called before the code that needs to be measured and at the end of the code. The time between each call is taken, and in the second call, the input SecondCall needs to be set to True.
|
|
|
|
```pascal
|
|
Example: OB32 - Intterrupt of 5.0 ms
|
|
-----------------------------------------
|
|
"FB Scan Time_DBx"(CalculateRuntime := false,
|
|
CycleTime := 5.0);
|
|
...
|
|
PROGRAM .....
|
|
...
|
|
"FB Scan Time_DBx"(CalculateRuntime:=true,CycleTime:=5.0);
|
|
|
|
```
|
|
|
|
Then on the DB the FB will calculate this:
|
|
***
|
|
* Max: Maximum time between calls since last reset
|
|
- Average: Average elapsed time between calls since last reset
|
|
- Min: Minimum time between calls since last reset
|
|
- CallLost%: When the cycletime input has a valid time, CallLost calculates the percentage of cycles lost every second. This is useful for timing and monitoring Interrupt OB3x. The cycletime parameter must be set to the interrupt time in milliseconds. Then, the FB counts the number of times per second it is called and calculates the percentage of lost calls.
|
|
|
|
The Reset bit on the DB resets all memory's. Also there is a auto reset the first 10 seconds the CPU goes from STOP to START.
|
|
|
|
```pascal
|
|
//FB Scan Time
|
|
//*************
|
|
//Calculate the execution time for the PLC of the code between the two call to this function. Normally this Function is used on a OB30 like this:
|
|
//
|
|
// Example: OB32 - Intterrupt of 5.0 ms
|
|
// -----------------------------------------
|
|
// "FB Scan Time_DBx"(CalculateRuntime := false,
|
|
// CycleTime := 5.0);
|
|
// ...
|
|
// PROGRAM .....
|
|
// ...
|
|
// "FB Scan Time_DBx"(CalculateRuntime:=true,CycleTime:=5.0);
|
|
|
|
//Max / Min / Average : of the runtime
|
|
//CallLost% : When the cycletime input > 0, CallLost% calculates the percentage OF cycles lost every second. This is useful for timing and monitoring Interrupt OB3x and to commision the right time for the interrupt.
|
|
//
|
|
//Reset: when TRUE resets all values. There is an autoreset also the first 10s of the PLC startup.
|
|
|
|
CALL RUNTIME
|
|
Ret_Val :=#ElapsedRuntime_s
|
|
MEM :=#Internal.TimeRecorded
|
|
|
|
IF NOT #CalculateRuntime THEN
|
|
RETURN;
|
|
ELSE
|
|
#CalculateRuntime := FALSE;
|
|
END_IF;
|
|
#ElapsedRuntime_ms := LREAL_TO_REAL(#ElapsedRuntime_s * 1000.0);
|
|
#TimeFromRUN := TIME_TO_DINT(TIME_TCK());
|
|
|
|
IF (#TimeFromRUN / 1000) < 10 THEN
|
|
#First10sCycle := true;
|
|
END_IF;
|
|
IF #Internal.CyclesForAverageCalc < 2 THEN
|
|
#Internal.CyclesForAverageCalc := 2;
|
|
END_IF;
|
|
|
|
IF #ElapsedRuntime_ms > #Max THEN
|
|
#Max := #ElapsedRuntime_ms;
|
|
END_IF;
|
|
|
|
IF #ElapsedRuntime_ms < #Min OR #Reset OR #First10sCycle THEN
|
|
#Min := #ElapsedRuntime_ms;
|
|
END_IF;
|
|
|
|
#Average := (#Average * (#Internal.CyclesForAverageCalc - 1) + (#ElapsedRuntime_ms)) / #Internal.CyclesForAverageCalc ;
|
|
#Internal.CounterOfCallsEachSecond := #Internal.CounterOfCallsEachSecond + 1;
|
|
|
|
IF (#TimeFromRUN / 1000) <> #Internal.LastCycleSeconds THEN
|
|
#Internal.CallCountLastSecond := #Internal.CounterOfCallsEachSecond;
|
|
#Internal.CounterOfCallsEachSecond := 0;
|
|
END_IF;
|
|
|
|
#Internal.LastCycleSeconds := (#TimeFromRUN / 1000);
|
|
IF #CycleTime > 0.5 THEN
|
|
#"CallLost%" := (((1000.0 / #CycleTime) - #Internal.CallCountLastSecond) / (1000.0 / #CycleTime)) * 100.0;
|
|
END_IF;
|
|
IF NOT #First10sCycle AND #Internal.CalculatedCycleStartTime = 0 OR #Reset THEN
|
|
#Internal.CalculatedCycleStartTime := #TimeFromRUN;
|
|
#Internal.CyclesForAverageCalc := 0.0;
|
|
END_IF;
|
|
|
|
IF (#TimeFromRUN - #Internal.CalculatedCycleStartTime) < #AverageTimeForCalc THEN
|
|
#Internal.CyclesForAverageCalc := #Internal.CyclesForAverageCalc + 1;
|
|
END_IF;
|
|
IF #RESET .. reset all counters
|
|
``` |