plciec61131-3

Architecture of 61131 program


In my 61131 program I have Objects/Information that needs to be shared between different program parts. What is best practice regarding this, should the Objects that needs to be shared be VAR in the PRG POU or global in a GVL?

From "high-level" programming I'm skeptical about global data, but this is maybe necessary?

Thanks for any input about best practice architectures in 61131.


Solution

  • I would make a STRUCT to global variables that has all the global data for a one component, for example a struct called ST_CoolingSystem which has the required global data for program handling the cooling system etc.

    Other approach would be a method / property for the PROGRAMPOU. It of course required Codesys 3 or similar. This way you could create a getter for variable / struct to the program or function block itself such as PRG_CoolingSystem.GetData() which returns the struct or reference to it.

    Update:

    One way to use OOP features is to add a property that returns a reference to data struct. NOTE: This works in TwinCAT 3, should also work in other IEC 61131-3 systems that have the new features.

    Let's say we have a struct ST_Cooling

    TYPE ST_Cooling :
    STRUCT
        //Commands
        RunCooling          : REAL;
        TemperatureSetpoint : REAL;
    
        //Status
        MotorRunning        : BOOL;
        CurrentTemperature  : REAL;
    END_STRUCT
    END_TYPE
    

    And we also have a function block FB_Cooling

    FUNCTION_BLOCK FB_Cooling
    VAR_INPUT
    END_VAR
    VAR_OUTPUT
    END_VAR
    VAR
        MotorRunCmd AT %Q*  : BOOL;
        Data_               : ST_Cooling; //"Private" of data struct
    END_VAR
    
    
    IF Data_.RunCooling THEN
        //Do something
        MotorRunCmd := TRUE;
    
        //Update status
        Data_.MotorRunning := TRUE;
    ELSE
        //Do something
        MotorRunCmd := FALSE;
    
        //Update status
        data_.MotorRunning := FALSE;
    END_IF
    

    We can add a PROPERTYto FB_Cooling that can be used to retrieve the struct and read and edit it. Because it returns a reference (like pointer), we can delete the Set method of the property.

    Type of the property:

    PROPERTY Data : REFERENCE TO ST_Cooling
    

    Code of the added PROPERTY's Get():

    //FB_Cooling.Data (Get)
    
    //Return reference to the data struct
    Data REF= Data_;
    

    Now it's possible to read and edit the data from anywhere where the instance of the function block can be accessed.

    PROGRAM PRG_Test
    VAR
        CoolingSystem : FB_Cooling;
    END_VAR
    
    //This is how we read
    IF CoolingSystem.Data.CurrentTemperature > 40.0 THEN
        //This is how to write (because it is a reference)
        CoolingSystem.Data.RunCooling := TRUE;
    END_IF
    
    //Run the block
    CoolingSystem();
    

    Perhaps this image also explains what does it look like in the project. See the Data property and it's Get, which is added automatically.

    enter image description here

    This is just an example, and a real system would have much more code and data. There could (should?) be also more structs, each for commands, statuses and parameters. But it's just my opinion :)