TwinCAT and Codesys - Function block FB_init array initialization

I have been using IEC 61131-3 function block FB_init methods quite a lot for different library blocks. They allow almost constructor-like initialization possibilities for function blocks. For example it’s quite useful to pass buffer size to a block using FB_init and then initialize a dynamic array using __NEW operator.

DataLogger  : FB_Logger(BufferSize := 2000);
StateLogger : FB_Logger(BufferSize := 500);
METHOD FB_init : BOOL
VAR_INPUT
	bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
	bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)
	BufferSize	: UDINT;
END_VAR
//Code:
//Note this is not a fully working correct example
Buffer := __NEW(BYTE, BufferSize);

However I just had a situation that I needed to have array of function block instances that all have a FB_init parameter.

The Beckhoff Information System had an example of an array with different parameters, so I knew it was possible (phew).

PROGRAM MAIN
VAR
    fbSample  : FB_Sample(nInitParam := 1) := (nInput := 2, nMyProperty := 3);
    aSample   : ARRAY[1..2] OF FB_Sample[(nInitParam := 4), (nInitParam := 7)]
                            := [(nInput := 5, nMyProperty := 6), (nInput := 8, nMyProperty := 9)];
END_VAR

However in my case the array size was based on a CONSTANT, the initial values were all the same and updating them manually would be too time-consuming. Finally I found that it’s possible, like the following (all instances get 123 to FB_init):

Example : ARRAY[0..ARRAY_MAXIMUM] OF FB_Block(123);

Here are the different possibilities for initialization.

//FB_Block
METHOD FB_init : BOOL
VAR_INPUT
	bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
	bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)
	MyParam	: INT;
END_VAR
//Code:
Prm := MyParam;
{attribute 'qualified_only'}
VAR_GLOBAL
	//Single block instance
	SingleFB_1 : FB_Block(MyParam := 1);
	SingleFB_2 : FB_Block(1);
	
	//Array of function block instances with different FB_init parameters
	ArrayFB_1	: ARRAY[0..2] OF FB_Block[(MyParam := 1), (MyParam := 2), (MyParam := 3)];
	ArrayFB_2	: ARRAY[0..2] OF FB_Block[(1), (2), (3)];
	
	//Array of function block instances with same FB_init parameter
	ArrayFB_3	: ARRAY[0..2] OF FB_Block(MyParam := 1);
	ArrayFB_4	: ARRAY[0..2] OF FB_Block(1);
END_VAR

Results: image

Written on November 20, 2022