Array of function blocks as a function input - TwinCAT3 / IEC61131-3

robiere48

Member
Join Date
Mar 2018
Location
Belgium
Posts
6
Hello all :rolleyes:

I've been browsing Google and forums for a while but haven't found a solution to my problem so far.

To give a bit of context, I have a series of machines and I need a program to make decisions depending on the states of all those machines. To do so, I listed all my machines in a array ListMachines and I implemented a function that crawls the list while extracting the individual state of all the machines.

In practice, I'm trying to use an array of function blocks as a function input but it seems that my function is not seeing the input. Without any success, I've also tried using pointers. Since there is no compilation errors, I don't really know what to do.

  • In Machines [PRG]:
  • My array is defined in the program as follows:
    VAR_OUTPUT
    ListMachines : ARRAY[1..3] OF Machine;
    END_VAR

    Where a Machine is a custom function block I created.
  • I then populate ListMachines with 3 machines (with default values) in the program code. This works well as I can see in my IDE while being Online.
In LineModes.Starting_Action [PRG]:
  • A function is supposed to use Machines.ListMachines as an input and process it to say if all machines from ListMachines are in the same state.

The problem seems that the function is never using my argument Machines.ListMachines as an input and never get running. I can for instance see that some local variables are never initiated.

What would be the best solution to send an array of function blocks as a function input ? Do I need to use global variables as a workaround?

If this happens to be possible and the right way, I will try to be more specific to see what went wrong in my situation.
 
Last edited:
It is impossible to use functions or blocks in an array, Only variables are possible in an array, they may be segmented etc.
you can put a lot of status bytes into the array, however never put a program (or a function block inside an array.
 
Could you clarify what is the content of your function block?

Propably STRUCTs works better in your case?
 
It is impossible to use functions or blocks in an array, Only variables are possible in an array, they may be segmented etc.
you can put a lot of status bytes into the array, however never put a program (or a function block inside an array.
Hi Shooter, thanks for your answer!
I also thought that this could be the problem but I found about this article where arrays of function blocks are used as follows:
afbSample2 : ARRAY [0..1, 0..1] OF FB_Sample[(nId_Init := 100, fIn_Init := 123.456)];

So I would guess that, since this type of declaration is permitted, there should be a way to transmit the array, right?
 
Could you clarify what is the content of your function block?

Propably STRUCTs works better in your case?

Hi Mara, thank you for considering my problem.

I also think using an ARRAY of STRUCTs containing all the states could solve this problem or even a global variable. However, since I am trying to use as much as possible an object oriented approach, I feel that I won't have a better/cleaner data control using such an input. For instance, it would be less appropriated for Online debugging in my opinion.


I joined a picture [imgur link here] showing all the relevant blocks for this case. You have the LineModes (A) that is calling the block (B) (I tried as an entry action or a 'N' action. As an input, it receives a list of Machines defined in (C). And in (D), you have the function in Live mode.
 
Could you send the project file? Maybe it is some silly mistake, you won't even consider to be wrong?

To be honest strongly disagree that it will help with online debugging. It is much easier when you have all your variables in one place.
 
Could you send the project file? Maybe it is some silly mistake, you won't even consider to be wrong?

To be honest strongly disagree that it will help with online debugging. It is much easier when you have all your variables in one place.

Hi Itrim, sorry for this late reply.

Unfortunately, I can't really send the whole project as it is using the common files of my company (I am an intern so I don't really know how carefull I should be). I asked my collegues but they are not used to manipulate function blocks like this so they don't know either. They are the ones who told me about their opinion on Online Debugging.

I also thought this could be a silly mistake (that's why I shared parts of my code) but I more importantly wanted to know if what I was trying to do was possible.


That being said, I realized that even by using the list as a global variable and calling it inside my function, it was not working. However, a call of Machines.ListMachine[1].GetReqState() in an action of my LineModes program is working properly. At least, this proves that the ARRAY of Function blocks has been defined successfully and can be accessed elsewhere.
 
Update: I found the problem !
I was thinking my problem was coming from my function because I was seeing '???' instead of variable values while being in Online mode. It was actually working and my problem was related to the way I was appending elements in my array.

If you define your machines and your list of generic machines (parent class) as follows:
SubMachine1(InArg1 := XXX, InArg2 := XXX);
SubMachine2(InArg1 := XXX, InArg2 := XXX);
List[1] := machine1;
List[2] := machine2;
--> Your reset your machines all the time

If you then want to use a list of parent Function Blocs I therefore found my way using a list of pointer to Machine (the parent class).
 
Edit: Corrected a mistake in my example -> changed the name of the machines
Update: I found the problem !
I was thinking my problem was coming from my function because I was seeing '???' instead of variable values while being in Online mode. It was actually working and my problem was related to the way I was appending elements in my array.

If you define your machines and your list of generic machines (parent class) as follows:
SubMachine1(InArg1 := XXX, InArg2 := XXX);
SubMachine2(InArg1 := XXX, InArg2 := XXX);
List[1] := SubMachine1;
List[2] := SubMachine2;
--> Your reset your machines all the time

If you then want to use a list of parent Function Blocs I therefore found my way using a list of pointer to Machine (the parent class).
 

Similar Topics

Hi I would like to make a array of function blocks. I'm trying to declare the array in a data block, in other platforms such as Codesys i would...
Replies
0
Views
1,926
Howdy, I am currently struggling with an array of values that I want to re-arrange in a programmatic way. My program is a mix of ladder and STX...
Replies
6
Views
392
Hi all I am currently working with an B&R controller using structured text. I have some code, that has previously worked with CODESYS, but when I...
Replies
2
Views
1,648
i try to move with one msg function array that i created in rslogix 5000 data type that have 1 int and one real but i have an error messege why?
Replies
1
Views
2,077
Hi, I want to create a block that takes a dynamic number of inputs like the AND, OR or MUX blocks in Unity Pro for Schneider Quantum PLC. You...
Replies
4
Views
6,019
Back
Top Bottom