Cycle time in FB

Greetings.
In order for my function block (written in ST) to work properly, I need to get the cycle time during which it is called. How can I do this?

Hi Pavel,

Welcome to the Community!

You can use the RTInfo function block from the BRSystem library to get the taskā€™s cycle time.

2 Likes

Thanks Marcus!
RTInfo inside the function block will be called every cycle, although 1 time would be enough for me.
Or should I not worry about it?

Hi Pavel @c578598 ,
that should be a ā€˜cheapā€™ operation, but you can check this with the profiler.

btw: an elegant way to call such ā€˜one time operationsā€™ would be to check the rising edge of an ā€˜Enableā€™ or ā€˜Executeā€™ input of your function block.

Thank you, Christoph.
Iā€™ll think about it.

Hi,

I want to add: Usually inside a FUB you implement a state machine, so doing such an operation is a thing of one step only. Also, you can always remember the value somewhere in some ā€œInternalā€ structure and only call the FUB in case the value is still zero.
Note: Often times I see people who use cycle times doing calculations with them to achieve timings. Iā€™d like to say: ā€œdonā€™tā€. If you need to act on specific timings, use FUBs like TON, TOFF, ā€¦ :slight_smile:

Yes, I agree, I will highlight the INIT state in the internal finite automaton to get the cycle time and validate the input parameters.
TON / TOF and other timers will not work for me, because I need to change the output value from 0 to MAX in a given time (input parameter) by ramp. For this purpose I use the product of the output value by the alpha factor (0.0 - 1.0). Alpha is incremented (with limit check) for each cycle by a fixed value calculated from the cycle time and the given change time.

I guess you could still use a TON :smiley:

	TON_Ramp.PT := InputTime;
	TON_Ramp();
	IF TON_Ramp.IN THEN
		OutputValue := TIME_TO_REAL(TON_Ramp.ET)/TIME_TO_REAL(TON_Ramp.PT);
	ELSE
		OutputValue := 0.0;
	END_IF

Edit: See Christophs answer below: Only precise down to 10ms (TON base)

1 Like

Hi,

there are, as your usecase shows, cases where itā€™s definitely legit to do those calculations. I just often enough stumbled upon the highlighted wrong (imo) usage of it and wanted to point to it :slight_smile: I have also seen people count cycles to implement timings, which is even worse since itā€™s loosing functionality once you move the task class :face_vomiting:

Please feel free to ask again for further questions, good luck with your new FUB and have a nice day

Marcel, thanks for the interesting solution!

Hmm, maybe I should really stop using cycle time, Iā€™ll think about it, thanks!

1 Like

donā€™t underestimate the counting of cycles.
TON works on a 10ms base so it is less precise.

B&R Online Help (br-automation.com)

3 Likes

If you need the exact information of time exceeded between 2 calls, you also could use the AsIoTimestamp() function, which delivers a actual system time counter in microseconds.

This then has to be done cyclic, and you always have to store the timestamp value of the last call also. As itā€™s a DINT value, you can subtract ā€œoldā€ from ā€œactualā€ without any further calculation to get the difference between the 2 calls:

act := AsIoTimestamp();
diff := act - old;
old := act;

Of course using RTinfo() like mentioned above is the right way to determine the cycle time of the calling task class, thereā€™s no doubt about.
I only mentioned AsIoTimestamp() additionally if you need to know the exact time between 2 calls (independent of if a task class maybe also consumed some tolerance time, or if someone ā€œaccidentlyā€ calls the same FB instance twice in one cycle ā€¦ who knows :wink: ).

Best regards!

4 Likes