Search code examples
twincatcodesysstructured-text

Concatenate variable


I need to concatenate a string and an integer and a string into a variable - in this case an input.

The inputs are named as following:

DI_Section1_Valve AT %I*: BOOL;
DI_Section2_Valve AT %I*: BOOL;
DI_Section3_Valve AT %I*: BOOL;

Now, I want to loop through these (this is just a short example):

For i:= 1 TO 3 DO
    Var[i] := NOT CONCAT(CONCAT('DI_Section', INT_TO_STRING(i)), '_Valve')
END_FOR

But by concatenating strings, I'll end up with a string, eg. 'DI_Section1_Valve', and not the boolean variable, eg. DI_Section1_Valve.

How do I end up with the variable instead of just the string? Any help is appreciated, thanks in advance. /Thoft99


Solution

  • That technique is called variable variables. Unfortunately this is not available in ST. There are few ways around it. As I understand Twincat 3 is based on Codesys 3.5. That means UNION is available. There is also a trick that references to BOOL does not work as expected and one reference take one byte. So you cannot place them in order, so you need to know BYTE address of input module.

    TYPE DI_Bits : STRUCT
            DI_Section1_Valve  : BIT; (* Bit 1 *)
            DI_Section2_Valve  : BIT; (* Bit 2 *)
            DI_Section3_Valve  : BIT; (* Bit 3 *)
            DI_Section4_Valve  : BIT; (* Bit 4 *)
            DI_Section5_Valve  : BIT; (* Bit 5 *)
            DI_Section6_Valve  : BIT; (* Bit 6 *)
            DI_Section7_Valve  : BIT; (* Bit 7 *)
            DI_Section8_Valve  : BIT; (* Bit 8 *)
        END_STRUCT
    END_TYPE
    
    TYPE DI_Sections : UNION
            ByName : DI_Bits; 
            ByID : ARRAY[1..8] OF BOOL; (* Comment *)
            ByMask: BYTE;
        END_UNION
    END_TYPE
    
    PROGRAM PLC_PRG
        VAR
            DIS AT %IB0.0: DI_Sections; (* Our union *)
            xOut : BOOL;
        END_VAR
    
    
        xOut := DIS.ByID[1];
        xOut := DIS.ByName.DI_Section1_Valve;
        
        DIS.ByID[5] := TRUE; 
        // Now DIS.ByName.DI_Section5_Valve also EQ TRUE
    
    END_PROGRAM