How to pass variable type as an argument to an function in IEC61131-3 structured text (TwinCAT3)?

1.1k views Asked by At

This is what I would like to have (this is a constructor for FB object):

METHOD FB_init : BOOL
    VAR_INPUT
        bInitRetains : BOOL;
        bInCopyCode : BOOL;

        //My variables:
        typeOfVariable : TYPE; // This obviously doesn't work 
    END_VAR

size := 1;
myArray := __NEW(typeOfVariable, size); // Create dynamic array with 'typeOfVariable' variables.

END_METHOD
  • In this method I would pass to the parameter typeOfVariable for example REAL and the method would create array of REAL variables with size 1.
  • I need to know what type I declare typeOfVariable so it can store the data about type of another variable.

  • Working example is the __NEW() method for dynamically creating array.

  • This method takes in a argument such as REAL or INT.

This is the code for it:

myArray := __NEW(REAL, 10); //Create array with type REAL variables with the size of 10
4

There are 4 answers

2
Filippo Boido On BEST ANSWER

OK, here a small example how you could tackle this problem:

Create an Enum first:

TYPE E_Type :
(
    eNO_TYPE := 0,
    eINT,
    eREAL
);
END_TYPE

Use it in a switch case:

METHOD createArray : POINTER TO BYTE
VAR_INPUT
    eType : E_Type;
    size : UINT;
END_VAR

CASE eType OF
    eINT:
        //Remember to __DELETE
        createArray := __NEW(INT, size);
    eREAL:
        createArray := __NEW(REAL, size);
END_CASE

Check for Null-Pointer and remember to __Delete when you don't need the array anymore.

0
Jakub Szlaur On

To my surprise (and by accident) I discovered that there is a file named ETcloEcPredictDataType containing this code:

{attribute 'TcTypeSystem'}
{attribute 'signature_flag' := '33554432'}
{attribute 'checksuperglobal'}
{attribute 'show'}
{attribute 'no-analysis'}

    {attribute 'GUID' := '6FFE9C73-9040-49AE-8731-5485B8A3A604'}
{attribute 'Namespace' := 'IO'}
TYPE ETcIoEcPredictDataType : (_SINT:=1, _USINT:=2, _INT:=3, _UINT:=4, _DINT:=5, _UDINT:=6, _LINT:=7, _ULINT:=8, _REAL:=9, _LREAL:=10) UDINT;
END_TYPE

Note that I didn't even have to include this file. I just written down _REAL clicked on it and choose Go to definition. Then it opened the ETcloEcPredictDataType file.


So following to @Filippo Boido answer you can create function with this CASE statement:

//_SINT:=1, _USINT:=2, _INT:=3, _UINT:=4, _DINT:=5, _UDINT:=6, _LINT:=7, _ULINT:=8, _REAL:=9, _LREAL:=10
CASE _type OF
    1: myArray := __NEW(SINT, size);
    2: myArray := __NEW(USINT, size);
    3: myArray := __NEW(INT, size);
    4: myArray := __NEW(UINT, size);
    5: myArray := __NEW(DINT, size);
    6: myArray := __NEW(UDINT, size);
    7: myArray := __NEW(LINT, size);
    8: myArray := __NEW(ULINT, size);
    9: myArray := __NEW(REAL, size);
    10: myArray := __NEW(LREAL, size);
END_CASE

And call the FB constructor as follows:

array : dynamicArray(_REAL);
0
Peter Zerlauth On

PLC_ReadSymInfoByName() is a possibility to do this for Function Blocks, attribute 'instance-path' > PLC_ReadSymInfoByName > "FB_Test"

it would also be Possible to do this with a Struct. ST_Real: fValue: Real; eTypeOf : E_Type:= E_Type.Real;

0
Tomáš Rompotl On

Just use ANY data type (or ANY_) for input variable. It will give you pointer to variable, its size and datatype (If you pass structure or fb, it will say just "USER_DEFINED". If you would like to compare datatype, use "IBaseLibrary.TypeClass" type.)

Also pay attention if you would like to pass the ANY variable into another function. ANY returns struct AnyType:

TYPE AnyType :
STRUCT
    // the type of the actual parameter
    typeclass : __SYSTEM.TYPE_CLASS ;
    // the pointer to the actual parameter
    pvalue : POINTER TO BYTE;
    // the size of the data, to which the pointer points
    diSize : DINT;
END_STRUCT
END_TYPE

...so that another function would have to accept variable of AnyType instead of ANY. ANY somehow works for compiler to know it should replace variable with filled AnyType struct.

see infosys https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/2529388939.html&id=