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

Persistent Variables in Function Block

tvm
2017-09-26
2017-10-05
  • tvm - 2017-09-26

    I'm trying to figure out the best way to link some variables of type PERSISTENT RETAIN in a function block. I have tried the following:

    1. declaring a VAR_IN_OUT structured variable which is connected to a PERSISTENT RETAIN global variable of the same type, put all persistent variables in that structure
    FUNCTION BLOCK TestFB
    VAR_IN_OUT
       PersistentVar: SETPOINTSTRUCTURE;
    END_VAR
    VAR_GLOBAL PERSISTENT RETAIN
       TestFBSetpoints: SETPOINTSTRUCTURE;
    END_VAR
    use:
    TestFB(PersistentVar:= TestFBSetpoints);
    
    1. declaring a REFERENCE TO a structured variable inside the function block, and assigning it to a PERSISTENT RETAIN variable of the same type within the function block declaration
    FUNCTION BLOCK TestFB
    VAR
       PersistentVar: REFERENCE TO SETPOINTSTRUCTURE;
    END_VAR
    VAR_GLOBAL PERSISTENT RETAIN
       TestFBSetpoints: SETPOINTSTRUCTURE;
    END_VAR
    function block declaration:
    VAR
       TestFB(PersistentVar:= TestFBSetpoints);
    END_VAR
    

    both of these approaches work, but neither work with a Schneider Vijeo Designer HMI, which loses communication with the PLC every time it tries to access a VAR_IN_OUT or a referenced variable within a function block (normal referenced variables work fine).

    1. I tried for a while just declaring the entire function block as PERSISTENT RETAIN, which worked, except every time I made any changes to the function block code, the PLC would go into exception and nothing would bring it back except a Reset Origin. I assume it had to do with the compiler trying to relocate all the persistent memory. It seems like bad practice anyway.

    I have the same problem with a structure with reference variables to persistent data. (ie. no logic, just data) For example:

    TYPE TESTSTRUCT:
    STRUCT
       Name: STRING(16);
       Status: TESTSTRUCTSTATUS;
       Config: REFERENCE TO TESTSTRUCTCONFIG;
    END_STRUCT
    END_TYPE
    VAR_GLOBAL PERSISTENT RETAIN
       DeviceSetpoints: TESTSTRUCTCONFIG;
    END_VAR
    VAR   
       Device: TESTSTRUCT:= (Config:= DeviceSetpoints);
    END_VAR
    

    However, this works just fine:

    VAR_GLOBAL PERSISTENT RETAIN
       TestVarRef: INT;
    END_VAR
    VAR
       TestVar: REFERENCE TO INT;
    END_VAR
    TestVar REF= TestVarRef;   //no problem using TestVar on the HMI
    

    I'm not looking for help on the HMI side, as I understand that that's beyond the scope of this form, but is there any other methods to link retain variables to a function block? Or is there a problem with my code that would mean it would work in the PLC but not to an external device? Variables are exported in the symbol configuration, in this case, the entire function block. Other variables in the function block work fine on the HMI, it's only the linked variables that cause a problem.

    thanks

    Tim

     
  • schaepper - 2017-09-28

    Hello

    What is the reason you need to do it by reference? Is the value stored in the HMI?

    Greetings

     
  • tvm - 2017-09-28

    The HMI just reads and writes the variables, they're stored in the PLC

    There's a couple reasons to use a reference:
    1. It saves memory space--rather than copying a whole block of variables into the function block, why not use a reference?
    2. There's a couple of variables that need both read and write access. For example, an hour counter would need to first be initialized with the value stored in persistent memory, but then the function block needs to write to it as well. A direct reference seems to be the easiest way to do that.

     
  • tvm - 2017-09-28

    Further testing shows that this problem occurs with any reference to a structure. A reference to an INT, for example, works fine, but a reference to a structure does not. I wonder if it has something to do with the way symbols are exported.

    In the below symbol configuration, TestVar is a REFERENCE TO INT, TestStruct is a REFERENCE TO SETPOINTSTRUCTURE, and TestFB1 contains a REFERENCE TO SETPOINTSTRUCTURE.

    This guy seems to have the same issue l viewtopic.php?t=7731 l

    <?xml version="1.0" encoding="utf-8"?>
    <Symbolconfiguration xmlns="http://www.3s-software.com/schemas/Symbolconfiguration.xsd">
      <Header>
        <Version>3.5.3.50</Version>
        <SymbolConfigObject version="3.5.3.50" />
        <ProjectInfo name="Test Reference Variable" devicename="MyController" appname="Application" />
      </Header>
      <TypeList>
        <TypeSimple name="T_INT" size="2" swapsize="2" typeclass="Int" iecname="INT" />
        <TypeUserDef name="T_SETPOINTSTRUCTURE" size="4" nativesize="4" typeclass="Userdef" iecname="SETPOINTSTRUCTURE">
          <UserDefElement type="T_INT" iecname="Var1" byteoffset="0" />
          <UserDefElement type="T_INT" iecname="Var2" byteoffset="2" />
        </TypeUserDef>
        <TypeSimple name="T_BIT_X_0" size="1" swapsize="0" typeclass="Bit" iecname="BOOL" />
        <TypeSimple name="T_BIT_X_1" size="1" swapsize="0" typeclass="Bit" iecname="BOOL" />
        <TypeUserDef name="T_TESTSTATUS" size="4" nativesize="4" typeclass="Userdef" iecname="TESTSTATUS">
          <UserDefElement type="T_BIT_X_0" iecname="Running" byteoffset="0" />
          <UserDefElement type="T_BIT_X_1" iecname="Available" byteoffset="1" />
          <UserDefElement type="T_INT" iecname="Amps" byteoffset="2" />
        </TypeUserDef>
        <TypeUserDef name="T_TESTFB" size="12" nativesize="12" typeclass="Userdef" iecname="TESTFB">
          <UserDefElement type="T_TESTSTATUS" iecname="Status" byteoffset="4" />
          <UserDefElement type="T_SETPOINTSTRUCTURE" iecname="Setpt" byteoffset="8" />
        </TypeUserDef>
      </TypeList>
      <NodeList>
        <Node name="Application">
          <Node name="GVL">
            <Node name="TestFB1" type="T_TESTFB" access="ReadWrite" />
            <Node name="TestStruct" type="T_SETPOINTSTRUCTURE" access="ReadWrite" />
            <Node name="TestVar" type="T_INT" access="ReadWrite" />
          </Node>
        </Node>
      </NodeList>
    </Symbolconfiguration>
    
     
  • tvm - 2017-10-05

    FYI, this is the response I received from Schneider tech support:

    "REFERENCE TO structs cannot be shared with HMIs with the actual SoMachine version - this is a known bug (PCR/IPR OEM53949 & OEM00064749) and it will be fixed with SoMachine V5."

    So this has nothing to do with Codesys

     

Log in to post a comment.