Hello,
as far as I know there is no “good practice” for this, since there are several ways of doing it, like using instances of the task or using arrays and FOR loops which was already mentioned. I am not entirely sure I understand what you would like to achieve. But I am using a different approach, it is somewhat complex, but here is an example how I handle and structure my axes which are always identical:
I create one task called Axis, I put it inside a new user library. Internally the task is using a local variable (structure) called “Internal”.
Internal contains three structure members: Command, Parameter and Status. The code can look like this:
IF (Internal.Command.MoveAbsolute) THEN
Internal.Status.AxisMoving := TRUE;
END_IF;
However, since my axis must be unique, I also create a global structure variable called gConveyor. Then I create 3 PV mappings:
gConveyor.Command → Internal.Command
gConveyor.Parameter → Internal.Parameter
Internal.Status → gConveyor.Status
Outside of the task I am calling the axis by using gConveyor.Command.MoveAbsolute.
gConveyor.Command.MoveAbsolute := TRUE;
IF (gConveyor.Status.AxisMoving) THEN
...
The task itself is more or less just a shell, with referenced files from the library task, and if you want you can have some axis specific files which are not referenced.
What are the benefits of this? I am always working with the generic local structure “Internal” in my tasks. I am not forced to use massive arrays, which are difficult to debug. And since I am doing this PV mapping for every task, I can be sure that the data is only written once to all tasks, at the beginning of the task cycle. This ensures consistency across tasks and cycles - if a higher priority task would interrupt the task and change the global variable, the local values will not change mid-task. It also makes sure that only the task itself can write the statuses.
This library is then a submodule in git, which means I can use the submodule across all my projects, and if I update the code in the submodule, this of course means the axis code will be updated in all projects using it. This comes at the cost of some overhead, because all structure members are copied cyclically through “Variable mapping”.