Indirect addressing memory/input/outputs

zezami
2017-05-17
2017-06-07
  • zezami - 2017-05-17

    Is it possible to indirectly address memory,input and outputs the way you can do i Siemens Step7?

    In step7 you can do MW[x] or IW[x] for example. In codesys it seems that you can only do it absolute, %MW0 %IW0 and not %MW[x].

    Is there any way to accomplish this in Codesys?

     
  • teichhei - 2017-05-17

    If you mean like fiddeling a dint into a byte array or so I do that with pointers.

    Sent from my SM-G935F using Tapatalk

     
  • zezami - 2017-05-17

    teichhei hat geschrieben:
    If you mean like fiddeling a dint into a byte array or so I do that with pointers.
    Sent from my SM-G935F using Tapatalk

    no not that, i mean when you are directly addressing the input/output/memory area.

    i Siemens you can for example do:
    FOR idx:= 0 to 4 DO
    variable := variable + MW[idx];
    LOOP;

    That doesnt seem possible in codesys since you can only direcly adress input/output/memory with %MW0 or %MW10 for example, but you can't use brackets to indirecly adress

    I would like to be able to do exactly the same:
    FOR idx:= 0 to 4 DO
    variable := variable + %MW[idx];
    LOOP;

    But thats not possible it seems and i can't find any information about indirect addressing if i google it..

     
  • NBCC - 2017-05-17

    Have you tried putting your data into an array?

    VAR
    arr1: array[0..3] of byte;
    END_VAR
    

    Then you can enter your data into the array:
    arr[0] := ...
    arr[1] := ...

    After that you can just do the for-loop like you did before.

    for i := 0 to 3 do
    variable := variable + arr[i];
    end_for
    
     

    Related

    Talk.ru: 1

  • teichhei - 2017-05-17

    I see what you mean. Would be interesting to know.

    But couldn't you still do something like

    paWord := adr(%mw0)

    for idx...
    variable := paWord^[idx]

    In that way you should still get the content of the first, 2nd... word within the loop

    Sent from my SM-G935F using Tapatalk

     
  • josepmariarams - 2017-05-17

    Hi

    You can do:

    IW_in:pointer to word
    IB_in:pointer to byte

    After

    IW_in:=adr(%iw0)
    IB_in:=adr(%iw0)

    After
    A:=ib_in[4] Reads %iw4

    B:=in_w[5] Reads %IB5

     

    Related

    Talk.ru: 5

  • Anonymous - 2017-05-17

    Originally created by: scott_cunningham

    What situations require reading direct memory locations? I've never needed this and I am curious. Or is this old-school PLC techniques/habits?

     
  • hermsen

    hermsen - 2017-05-18

    very old school habit

     
  • josepmariarams - 2017-05-19

    Hi.

    I don t know if it is an school habit, but it helps me in the problem of how to work from OOP point of view with inouts.

    If you have an FB wich modelizes an pneumatic cillinder you need, normally, two Dinputs and two DOutputs. From my point of view this inouts have to be internals to the FB_CILLINDER.

    For me every DInput is an FB wich has three configurable variables: channel, mask and inverted (that I configure using an csv for every di). Dinput has an boolean output with the value of the physical digital input:

    Out:=(xb[channel] and mask) <>0.

    It allows me to solve how pass from an sigleton (di) to Oop. And allows me to change without recompile the connection from an logical input to an logical output. Allows me to reconfigure diferent machines with only one code (versioning, rapid prototyping....).

     
  • zezami - 2017-05-22

    Josep M. Rams hat geschrieben:
    Hi
    You can do:
    IW_in:pointer to word
    IB_in:pointer to byte
    After
    IW_in:=adr(%iw0)
    IB_in:=adr(%iw0)
    After
    A:=ib_in[4] Reads %iw4
    B:=in_w[5] Reads %IB5

    Thank you, i had no idea you could use index on pointer without the pointer being an array. It works perfect though.

    I know this is a really old school way of doing things but i have some S7 code and i want the codebase to be as similar as possible in codesys

     

    Related

    Talk.ru: 5

  • jzhvymetal - 2017-05-22

    Not all CoDeSys controllers support direct addressing. For the one that do you would locate your variables as follows:

    myBool  AT %MX0.0 : BOOL; //Boolean Type
    myInput AT %IX0.0 : BOOL;
    myOut   AT %QX0.0 : BOOL;
    myByte  AT %MB0   : BYTE; //Byte Type
    mySINT  AT %MB0   : SINT;
    myUSINT AT %MB0   : USINT;
    myByteArary AT %MB0 : ARRAY[0..10] OF BYTE; 
    myWORD  AT %MW0   : WORD; //16 bit types
    myINT   AT %MW0   : INT;
    myUINT  AT %MW0   : UINT;
    myWordArary AT %MW0 : ARRAY[0..10] OF WORD; 
    myDWORD AT %MD0   : DWORD; //32bit Types
    myDINT  AT %MD0   : DINT;
    myUDINT AT %MD0   : UDINT;
    myReal  AT %MD0   : REAL;
    myDwordArray AT %MD0 : ARRAY[0..10] OF DWORD;
    mySTRING AT %MB0 : STRING;  //STRING  
    

    Also attached is a useful memory map. It is excel file because calculates the memory map

    SoM Modbus Table V3 .xls.txt [674 KiB]

     
  • Anonymous - 2017-06-07

    Originally created by: scott_cunningham

    I understand the need to link a software BOOL to a physical real output. But for this I use the hardware IO mapping table of EtherCAT or other fieldbus device. Often, I have to shift around modules and when I do, the memory address changes and I do not want to care about this!

    I use FBs with FB_INITs with REFERENCE TO for linking speaking software variables to physical outputs. This example I simply have a BOOL "ActOutput" which I map to an EtherCAT digital output. This forces the link at instantiation without any memory location hard coded. If I insert a module or move the module - CoDeSys handles the memory locations for me.

    Original system has Digital Output 0 at %QX0.0. Second screen shot is after inserting a module, which shifts Digital Output 0 to %QX6.0 (for which I can completely ignore - it just works).

    Here is an example of my Digital Output with REFERENCE TO:

    PROGRAM PLC_PRG
    VAR
       ActOutput : BOOL; //define at memory location, or use hardware IO mapping
       DigOut1   : DigitalOutput(refOutput:=ActOutput); //referencing is required by fb_init
       Temp1     : BOOL;
       Temp2     : BOOL;
    END_VAR
    DigOut1.TurnOn();
    Temp1 := DigOut1.State;
    DigOut1.InvertedLogic := TRUE;
    Temp2 := DigOut1.State;
    END_PROGRAM
    FUNCTION_BLOCK DigitalOutput
    VAR
       InternalState : BOOL := FALSE;
       ActOutState   : REFERENCE TO BOOL; //init not necessary - FB_INIT forces referencing
       Inverted      : BOOL := FALSE;
    END_VAR
    METHOD FB_INIT : BOOL
    VAR_INPUT
       bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
       bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)
       refOutput   : REFERENCE TO BOOL;
    END_VAR
    //link local var to real life BOOL
    THIS^.ActOutState REF= refOutput;
    END_METHOD
    METHOD TurnOn
    VAR_INPUT
    END_VAR
    THIS^.InternalState := TRUE;
    UpdateState();
    END_METHOD
    METHOD TurnOff
    VAR_INPUT
    END_VAR
    THIS^.InternalState := FALSE;
    UpdateState();
    END_METHOD
    METHOD Toggle
    VAR_INPUT
    END_VAR
    THIS^.InternalState := NOT(THIS^.InternalState);
    UpdateState();
    END_METHOD
    METHOD PRIVATE UpdateState
    VAR_INPUT
    END_VAR
    IF THIS^.Inverted THEN
       THIS^.ActOutState := NOT(THIS^.InternalState);
    ELSE
       THIS^.ActOutState := THIS^.InternalState;
    END_IF
    END_METHOD
    PROPERTY InvertedLogic : BOOL
    GET
    InvertedLogic := THIS^.Inverted;
    SET
    THIS^.Inverted := InvertedLogic;
    UpdateState();
    END_PROPERTY
    PROPERTY State : BOOL
    GET
    State := THIS^.ActOutState;
    SET
    THIS^.InternalState := State;
    UpdateState();
    END_PROPERTY
    END_FUNCTION_BLOCK
    

    IMG: no

    IMG: mem

    IMG: dig

     

Log in to post a comment.