Skip to content

IO Role mapping in Data Lists - structures

Hello,

I am fairly new to PhoenixContacts PLCs and so I am still getting used to them. I worked a lot with B&R PLCs before. There I used structures a lot so I have planned to use similar concept in PLCnext Eng.

But it looks that it's not possible to link variables of the structure to the "IO datums" in Data Lists. Since IO datums only accept basic data types (for example Digital input only accepts BOOL, but can't "see" BOOL that is stored inside a structure for example struct myDigIns.DigIn1.

Am i missing something or is this really not possible? I am using ST programming language.

yrHr3ab.png

fXnPCev.png


I would really appreciate you help.

Best regards.

Comments

  • The structure definitions in the Data Type sheet are only data types, not variables.
    Please try creating a variable, e.g. in a Program, with the Type of one of your STRUCT data types. If that struct variable has the Usage "IN port", and if the program containing that variable is instantiated in a Task, then you should be able to connect an OUT port of type BOOL (like a digital input channel) to a BOOL field in the struct variable in the program instance.
    You can make those Port variable connections in the "GDS Port List" tab of the "PLCnext" branch of the project tree.
  • Hello Martin,

    thank you for your answer. Sorry I didn't write clear enough in the first post. Of course I created global variable Din of structure type DinStruct.

    xWrAODu.png

    But this global variable isn't seen in the IO datums mapping.

    Then I tried your suggestion by using "IN port" and "OUT port" and this does work, but then this structure is limited only to the program in which it's defined. It's not a global variable. I would like to have global IO structure with all DI DO AI AO variables inside and then link/map this variables (which are inside structure) to corresponding physical modules.

    In this way program can be read easier since you can have production line seperated in "sections" by structure, for example: We have 3 conveyors. Conveyor1, Conveyor2, Conveyor3. In this case I would create 1 structure Conveyor with
    1DO BOOL - Start
    1DO BOOL - Stop
    1DI BOOL - Running
    1DI BOOL - InFault

    Then I would simply create array [0..2] of structure Conveyor. Then I would link/map each array element and structure sub-element to corresponding physical element. For example:

    Physical DO1 <- array[0].Start
    Physical DO2 <- array[0].Stop
    Physical DI1 <- array[0].Running
    Physical DI2 <- array[0].InFault

    Physical DO3 <- array[1].Start
    Physical DO4 <- array[1].Stop
    Physical DI3 <- array[1].Running
    Physical DI4 <- array[1].InFault

    and so on for remaining 1 conveyor.

    If this is not possible then I have to create as many variables as there is inputs/outputs? For example above:
    Conveyor1Start
    Conveyor2Start
    Conveyor3Start
    Conveyor1Stop
    Conveyor2Stop
    Conveyor3Stop
    And so on...

    Or am I missing something?

    Maybe I am to used of this concept and there is something simpler I could do but I just don't know it yet...
  • Unfortunately, it is not yet possible to link structure elements or array fields directly with process data in the Global Variable table.

    If you don't want to connect every bit of a DI or DO module, you can also use the the I/O item with the tilde ~ (e.g. Bitstring16 can connect to a WORD variable) . Then, only one variable has to be created for each I/O module, and the bits in that WORD variable can be mapped or used individually in your code. This is not the same as the Role Mapping feature you are asking about, but perhaps it will be useful.
  • Hello,
    The possibility of use structure variables is a great way for code clearance and reducing amount of global variables.
    During my work over projects I find out that the best way for me is to use WORD, DWORD or LWORD variables attached to bitstring input\output parameter of a module, as Martin noted before. And use additional parsing function, it need to be used because order of inputs\outputs of bitstring variable does not directly assigned to bits in WORD variable. Actually it have inverted byte order.

    Here is the part of parsing function block code for input module with 64 inputs:
    Where _00_00...15_17 is function outputs, as if you attach your variables to data list page of the module, and DI_64_IN.X* is a partial access to a bits of a variable you actually attach to bitstring input of the module.

    _00_00 := DI_64_IN.%X56;
    _01_01 := DI_64_IN.%X57;
    _02_02 := DI_64_IN.%X58;
    _03_03 := DI_64_IN.%X59;
    _04_04 := DI_64_IN.%X60;
    _05_05 := DI_64_IN.%X61;
    _06_06 := DI_64_IN.%X62;
    _07_07 := DI_64_IN.%X63;

    _08_10 := DI_64_IN.%X48;
    _09_11 := DI_64_IN.%X49;
    _10_12 := DI_64_IN.%X50;
    _11_13 := DI_64_IN.%X51;
    _12_14 := DI_64_IN.%X52;
    _13_15 := DI_64_IN.%X53;
    _14_16 := DI_64_IN.%X54;
    _15_17 := DI_64_IN.%X55;
    ...

    In this case you can connect members of your structured variables to the outputs of the function block

    AXL_F_DI64_DECODE1(
    DI_64_IN := PN_DD1_DI64, //Global variable attached to bitstring input of the module
    _00_00 => TRN_IO.K1_1.xIN_ST_KM1, //Parsed boolean outputs
    _01_01 => TRN_IO.N1.xIN_ST_KM,
    _02_02 => TRN_IO.N1.xIN_ST_SAFETY_SWITCH,
    _03_03 => TRN_IO.N1.xIN_ST_SB_WM,
    _04_04 => TRN_IO.N1.xIN_SN_BELT_BOT_L,
    _05_05 => TRN_IO.N1.xIN_SN_BELT_TOP_L,
    _06_06 => TRN_IO.N1.xIN_SN_JAM,
    _07_07 => TRN_IO.N1.xIN_SN_ROT,

    _08_10 => TRN_IO.K1_1.xIN_ST_KM2,
    _09_11 => TRN_IO.N2.xIN_ST_KM,
    _10_12 => TRN_IO.N2.xIN_ST_SAFETY_SWITCH,
    _11_13 => TRN_IO.N2.xIN_ST_SB_WM,
    _12_14 => TRN_IO.N2.xIN_SN_BELT_BOT_L,
    _13_15 => TRN_IO.N2.xIN_SN_BELT_TOP_L,
    _14_16 => TRN_IO.N2.xIN_SN_JAM,
    _15_17 => TRN_IO.N2.xIN_SN_ROT,
    .....

    I don't use SWAP because, have additional functionality for inverting and time shifting of input signals inside function block.
Sign In or Register to comment.