plctwincat

Accessing Twincat Function Block Field using Property


I have a function block with following hardware links :

bEL1852OutputBools AT %Q* : ARRAY[1..8] OF BOOL;

I would like to create a property that gives me both get and set access to the bEL1852OutputBools so I can do this :

fbEL1852.Outputs[1] := TRUE;

I guess I need to reference/pointer it somehow but I am not really sure how.

PROPERTY PUBLIC Outputs : ARRAY[1..8] OF BOOL

GET

Outputs := bEL1852OutputBools;

SET

bEL1852OutputBools:= Outputs;

EDIT.

ok so I figured out how to do this with Outputs :

PROPERTY PUBLIC Outputs : REFERENCE TO ARRAY[1..8] OF BOOL;

GET

Outputs REF= bEL1852OutputBools;

SET

bEL1852OutputBools = Outputs;

but if I try to do the same for inputs I get Compiler error : "Reference assign is not possible on a variable mapped to an input address"

Inputs REF= bEL1852InputBools; 

Is there no way to make this work with properites for input variables ?


Solution

  • If you have a function block with properties then there is not much need to worry about any references unless you are intending to pass those references to somewhere that cannot easily access the FB.

    Function access to properties coming from objects can be a little bit of a pain in the case of accessing arrays. In this case I would say that the preferred solution really depends on your use case, but some options are:

    ( N.B. There are cleaner way to handle most these through static allocations, but this should get the point across in a concise manner )

    Use a standard helper variable:

    Exactly as the error value says, use a helper variable that you are expecting to read/write the value to. This can be a useful method if you are performing the access to these variables within a function block or loop, some place where the same variable can be used for multiple accessors.

     _TempBool := fbEL.Inputs[1];
    

    Split the data at the accessors:

    If you can't access the data via functions, then remove the need to. Splitting the properties entirely means that there is no need to process these, however this may not be a useful solution if you intend to access variables in any kind of programmatic way as you can't call them by position specifically

    PROPERTY Input1 : BOOL
        Input1 := Inputs[1];
    
    PROPERTY Input2 : BOOL
        Input2 := Inputs[2];
    

    Pack the data within the accessors:

    Rather than accessing the data as elements of an array, access the data as elements of a BYTE. On the plus side you can do any kind of bit operations on the BYTE, however the speed can be a bit slower if you are doing bit access and it will be more frustrating if you are trying to access things within a loop

    PROPERTY InputByte : BYTE
        InputByte.0 := Inputs[1];
        InputByte.1 := Inputs[2];
    

    Use pointers rather than references:

    Pointers are the fall back in the event of references not being usable, but with good reason. They require extra planning and careful handling to avoid crashes or bad data. Otherwise though they should be able to be do what you want.

    PROPERTY pInputArray : ARRAY [1..8] OF POINTER TO BOOL
        pInputArray[1] := ADR( Inputs[1] );
        pInputArray[2] := ADR( Inputs[2] );
    

    Hope this helps, and ask if you have any more questions