Home > Enterprise >  TwinCAT Pointer to Pointer of undefined type?
TwinCAT Pointer to Pointer of undefined type?

Time:04-17

I'm trying to build a function that sums a single dimension array of any type in TwinCAT.

I'm relatively inexperienced with pointers so the answer may be obvious, but I could not find any solutions. I read through all these and they helped a bit.

screanshot of codesys

If writing the same code for every type is too tedious, you can always use a script to automate this:

code_template = \
"""CASE arr_first.TypeClass OF
{0}
ELSE
\tfn_SumArray := TRUE;
\tFOR i := 0 TO sum_out.diSize - 1 DO
\t\tsum_out.pValue[i] := 0;
\tEND_FOR
END_CASE;
"""

case_template = \
"""\t__SYSTEM.TYPE_CLASS.TYPE{0}:
\t\tptr_arr.{0} := arr_first.pValue;
\t\tptr_sum.{0} := sum_out.pValue;
\t\tptr_sum.{0}^ := 0;
\t\tFOR i := 0 TO arr_size - 1 DO
\t\t\tptr_sum.{0}^ := ptr_sum.{0}^   ptr_arr.{0}[i];
\t\tEND_FOR
"""

types = ['_REAL', '_LREAL', '_USINT', '_UINT', '_UDINT', '_ULINT', '_SINT', '_INT', '_DINT', '_LINT']

cases = [case_template.format(t) for t in types]
code = code_template.format(''.join(cases))

print(code)

Just run the above script with python and you'll get the case code for the types listed in the script.

CodePudding user response:

What I ended up going with was a case statement, with for loops inside.

Not as elegant as I had hoped, but still functional.

FUNCTION fn_SumArray : REAL
VAR_INPUT 
    inArr : ANY; //Array to size
    inElem : ANY; //Any element in the array
END_VAR

VAR
    i : DINT := 0;
    pBYTE : POINTER TO BYTE; //8 bit
    pSINT : POINTER TO SINT; //8 bit
    pUSINT : POINTER TO USINT; //8 bit
    pWORD : POINTER TO WORD; //16 bit
    pINT : POINTER TO INT; //16 bit
    pUINT : POINTER TO UINT; //16 bit
    pDINT : POINTER TO DINT; //32 bit
    pUDINT : POINTER TO UDINT; //32 bit
    pDWORD : POINTER TO DWORD; //32 bit
    pREAL : POINTER TO REAL; //32 bit
    pLREAL : POINTER TO LREAL; //64 bit
    pLWORD : POINTER TO LWORD; //64 bit
    
END_VAR
//---------------------------------
CASE inElem.TypeClass OF
    __SYSTEM.TYPE_CLASS.TYPE_SINT:
        FOR i := 0 TO inArr.diSize-1 BY 1 DO
            pSINT := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pSINT^;
        END_FOR;
    __SYSTEM.TYPE_CLASS.TYPE_USINT:
        FOR i := 0 TO inArr.diSize-1 BY 1 DO
            pUSINT := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pUSINT^;
        END_FOR;
    __SYSTEM.TYPE_CLASS.TYPE_WORD:
        FOR i := 0 TO inArr.diSize-1 BY 2 DO
            pWORD := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pWORD^;
        END_FOR;    
    __SYSTEM.TYPE_CLASS.TYPE_INT:
        FOR i := 0 TO inArr.diSize-1 BY 2 DO
            pINT := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pINT^;
        END_FOR;    
    __SYSTEM.TYPE_CLASS.TYPE_UINT:
        FOR i := 0 TO inArr.diSize-1 BY 2 DO
            pUINT := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pUINT^;
        END_FOR;    
    __SYSTEM.TYPE_CLASS.TYPE_DINT:
        FOR i := 0 TO inArr.diSize-1 BY 4 DO
            pDINT := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pDINT^;
        END_FOR;    
    __SYSTEM.TYPE_CLASS.TYPE_UDINT:
        FOR i := 0 TO inArr.diSize-1 BY 4 DO
            pUDINT := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pUDINT^;
        END_FOR;    
    __SYSTEM.TYPE_CLASS.TYPE_DWORD:
        FOR i := 0 TO inArr.diSize-1 BY 4 DO
            pDWORD := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pDWORD^;
        END_FOR;
    __SYSTEM.TYPE_CLASS.TYPE_REAL:
        FOR i := 0 TO inArr.diSize-1 BY 8 DO
            pREAL := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pREAL^;
        END_FOR;    
    __SYSTEM.TYPE_CLASS.TYPE_LREAL: 
        FOR i := 0 TO inArr.diSize-1 BY 8 DO
            pLREAL := ADR(inarr.pValue[i]);
            fn_SumArray := fn_SumArray   pLREAL^;
        END_FOR;    
ELSE
    fn_SumArray :=0;
END_CASE;
  • Related