Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Address components of variable to IO-addresses

flog
2014-03-31
2014-04-01
  • flog - 2014-03-31

    Hi, Newbie on the forum

    Is there a nifty way to address components of an instance of a data type to pins on an IO?

    Ive got an virtual profinet node with 32 Byte in and 32 Byte out. I want every bit addressed to a component in my data type. The data type basically consists of 512 boolean components.

    Im trying to simulate a solution to my problem with a smaller data type and a 32DI module. Im using an AC500 PM573 and an DI524.

    TYPE MyDataType :
    STRUCT
       Bool_0 : BOOL;
       Bool_1 : BOOL;
       Bool_2 : BOOL;
       ...
       Bool_15 : BOOL;
    END_STRUCT
    END_TYPE
    
    PROGRAM PLC_PRG
    VAR
       MyVar : MyDataType;
       MyVar2 : MyDataType;
    END_VAR
    

    The first input on my 32DI has address %IX0.0, %IB0, %IW0 or %ID0.
    For example I would like to access the components in MyVar on %IX1.0 through %IX1.7 and MyVar2 on %IX2.0 through %IX3.7.

    Im not allowed to bitaddress the variable. And if I address adress the variable with %IB0 every bit in the io uses one byte. So affecting input0 would set MyVar.Bool_0 to TRUE. Fine, but input1 gives MyVar.Bool_0 INVALID: 16#02 and input8 sets MyVar.Bool_1 to TRUE.

    How do I solve this?

     
  • shooter - 2014-03-31

    you can use combine for this.

     
  • flog - 2014-04-01

    Would you elaborate "combine"?

     
  • shooter - 2014-04-01

    it is called pack and unpack and can be found in util.lib

     
  • flog - 2014-04-01

    So there is no way to directly address a component of a struct to an IO?

    Since I've got a 256 bool struct, I came up with this function block to copy the IO to the struct. But I don't think it seems like the optimal solution.

    FUNCTION_BLOCK 32Byte_IO_to_Struct
    VAR_INPUT
       Address: DWORD; (*Address of first byte on IO*)
    END_VAR
    VAR_OUTPUT
       IO_Struct : ;
    END_VAR
    VAR
       IO_BYTE_ARRAY   : ARRAY[0..31] OF BYTE;
       pt            : POINTER TO BYTE;
       i            : INT;
       ByteNr         : INT;
    END_VAR
    pt := Address;
    FOR i := 0 TO 31 BY 1 DO
       IO_BYTE_ARRAY[i]:=pt^;
       pt:=pt+1;
    END_FOR;
    ByteNr:=0;                                       (*Byte0*)
       IO_Struct.Component0:=         IO_BYTE_ARRAY[ByteNr].0;   (*Bit0*)                        
       IO_Struct.Component1:=         IO_BYTE_ARRAY[ByteNr].1;   (*Bit1*)                        
       IO_Struct.Component2:=         IO_BYTE_ARRAY[ByteNr].2;   (*Bit2*)                        
       IO_Struct.Component3:=         IO_BYTE_ARRAY[ByteNr].3;   (*Bit3*)                        
       IO_Struct.Component4:=         IO_BYTE_ARRAY[ByteNr].4;   (*Bit4*)                        
       IO_Struct.Component5:=         IO_BYTE_ARRAY[ByteNr].5;   (*Bit5*)                        
       IO_Struct.Component6:=         IO_BYTE_ARRAY[ByteNr].6;   (*Bit6*)                        
       IO_Struct.Component7:=         IO_BYTE_ARRAY[ByteNr].7;   (*Bit7*)                        
    ByteNr:=1;                                       (*Byte1*)
       IO_Struct.Component8:=         IO_BYTE_ARRAY[ByteNr].0;   (*Bit8*)                        
       IO_Struct.Component9:=         IO_BYTE_ARRAY[ByteNr].1;   (*Bit9*)                        
       IO_Struct.Component10:=         IO_BYTE_ARRAY[ByteNr].2;   (*Bit10*)                        
       IO_Struct.Component11:=         IO_BYTE_ARRAY[ByteNr].3;   (*Bit11*)                        
       IO_Struct.Component12:=         IO_BYTE_ARRAY[ByteNr].4;   (*Bit12*)                        
       IO_Struct.Component13:=         IO_BYTE_ARRAY[ByteNr].5;   (*Bit13*)                        
       IO_Struct.Component14:=         IO_BYTE_ARRAY[ByteNr].6;   (*Bit14*)                        
       IO_Struct.Component15:=         IO_BYTE_ARRAY[ByteNr].7;   (*Bit15*)                        
    .
    .
    .
    ByteNr:=31;                                    (*Byte31*)
       IO_Struct.Component248:=         IO_BYTE_ARRAY[ByteNr].0;   (*Bit8*)                        
       IO_Struct.Component249:=         IO_BYTE_ARRAY[ByteNr].1;   (*Bit9*)                        
       IO_Struct.Component250:=         IO_BYTE_ARRAY[ByteNr].2;   (*Bit10*)                        
       IO_Struct.Component251:=         IO_BYTE_ARRAY[ByteNr].3;   (*Bit11*)                        
       IO_Struct.Component252:=         IO_BYTE_ARRAY[ByteNr].4;   (*Bit12*)                        
       IO_Struct.Component253:=         IO_BYTE_ARRAY[ByteNr].5;   (*Bit13*)                        
       IO_Struct.Component254:=         IO_BYTE_ARRAY[ByteNr].6;   (*Bit14*)                        
       IO_Struct.Component255:=         IO_BYTE_ARRAY[ByteNr].7;   (*Bit15*)   
    
     
  • shooter - 2014-04-01

    for inputs
    doubleword.1 := in0_0;
    for outputs:
    for extracting use out0_0:= doubleword.0
    simplest solution, and yes you have to declare every in/out separate as they can have several addresses, however it is possible to use a word direct like above.

    so outword at %QW0 :WORD;

    then you have outword.1 etc.

     

Log in to post a comment.