One problem I face quite often is that I need to have some code executed only once in the first cycle of the PLC, and then never again. Up until now I’ve always used a boolean of some sort; “bFirstCycleExecuted”, instantiated to false and then set to true after the first cycle resulting in something like:
PROGRAM MAIN VAR bFirstCycleExecuted : BOOL := FALSE; END_VAR IF NOT bFirstCycleExecuted THEN // The code that you want to be executed at the first cycle bFirstCycleExecuted := TRUE; END_IF
There actually is a built-in way in TwinCAT to know whether the current cycle is the first one or not, using the global data type PlcTaskSystemInfo. Among other parameters in this data type is the boolean FirstCycle. In your program you have access to an array of the data type PlcTaskSystemInfo, accessing it by _TaskInfo[index_of_current_task]. The index of current task can be retrieved by using the function block GETCURTASKINDEX. Replacing the above piece of code with our new knowledge results in:
PROGRAM MAIN VAR fbGetCurTaskIndex : GETCURTASKINDEX; END_VAR fbGetCurTaskIndex(); IF _TaskInfo[fbGetCurTaskIndex.index].FirstCycle THEN // The code that you want to be executed at the first cycle END_IF
Hi Jakob, great blog, a friend put me onto this!
I wrote a little class that wraps some of PlcTaskSystemInfo for easier access. see the T_Task class in my open source library : https://bitbucket.org/Intecre/intecrelibs.
There’s also some work on a test base class in there – I see you’re also interested in TDD.
All pull requests / comments welcome!
Hi Mark, thanks for your comments! Really neat to see that you’ve developed a library, had completely missed this one. Quickly looked into it, and saw that you’ve off with a good start with TDD FB’s. Noticed that you’re using the pragmas “instance-path” and “reflection”, which seem interesting!
Hi Jakob and Mark,
What would be the difference between using this approach for the first cycle against using the built in, at least in CODESYS, FB_INIT method?
Apart from, when you are inheriting from another class implementing an FB_INIT and therefore you can not overwrite/overload it?
Thanks and great blog!