Smaller array equal to Subarray of Larger array

I have a larger array example of x as type usint[0…99] which contains certain addresses I want to isolate.

It would be extremely convenient to do any one of the following as the array masking is varies

Option 1
y as type usint[4…5]
y := x // where y[4…5] = x[4…5]

Option 2
y as type usint[0…1]
y := x[4…5] // where y[0…1] = x[4…5]

Option 3
y as type uint
y := x[4…5] // where y = usint[2] to uint

is it correct that masking and Subarrays are not supported in Automation Studio? I’m trying to avoid multiple lines to take larger data sets. We have a series of parameters which range from one bit to 64 bytes and their address in an array vary depending on the machine used so being able to change a few enumerators would be quite an advantage.

Two suggestions for you depending on whether you want to copy the data, or just use a pointer to it. Both of them work with all of your Option variants.

Copy the data to a new variable. (Data in y is only updated when this line is executed, changing value in y does not affect x).

brsmemcpy(ADR(y), ADR(x[4]), SIZEOF(y));

Use pointers.

Define y as what you want as a “reference” and use the following line. (Data is updated in y as soon as it is updated in x. Changing values in y will also change it in x)

y ACCESS ADR(x[4]);

Example code below:

Variable definitions

Code:

PROGRAM _INIT
	// Preset example data
	FOR i := 0 TO 99 DO
		x[i] := i;
	END_FOR;
END_PROGRAM

PROGRAM _CYCLIC
	
	// Option by copying to new variable
	brsmemcpy(ADR(y), ADR(x[4]), SIZEOF(y));
	
	// Different options with pointers
	Option1 ACCESS ADR(x[4]);
	Option2 ACCESS ADR(x[4]);
	Option3 ACCESS ADR(x[4]);
	
END_PROGRAM

Values in Watch

Your solution works great, and was exactly what I was looking for in the original post.

That being said, I have now raised another concern.

After some “I swear I did that already”, my issue seems to have come from referencing within a structure.

//Works
y ACCESS ADR(x[4]);

// Does not work
z.y ACCESS ADR(x[4]);

just as an added bonus, referencing z does not work either.

Error 1392: Dynamic Variable required for Access

Hi Adam,

Unfortunately, it is not possible to do this. You can’t include a dynamic variable as part of a structure (at least within IEC languages like Structured Text). The entire structure would have to be dynamic. Your options are:

  1. Use a non-structure variable to reference a non-structure variable
  2. Use a non-structure variable to reference a member of a structure variable
  3. Use a structure variable to reference a structure variable

Something you could do is make the variable z.y a UDINT and store the address you want to reference:

z.y = ADR(x[4])

However this isn’t a dynamic variable which means you’d then have to either pass this address into a function, or access it with another dynamic variable (residing outside of a structure).

I did not achieve success when all of my variables were set to dynamic within the structure. So the third Option you suggested was tested and at the very least, I have not had any success. I decided to use a non-structured pointer to reference a structured variable as my solution.

Sorry if that was unclear. You can use a variable of a structure type to reference another variable of the same structure type. You cannot reference anything with a structure member.

Glad you have a working solution though!

1 Like