Architecture of 61131 program

834 views Asked by At

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.

2

There are 2 answers

2
Quirzo On BEST ANSWER

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 :)

0
mrsargent On

A VAR in the PRG_POU is the equivalent of a local variable in a standard OOP type language. If you want an object instance/information that can be used in different POUs then the GVL (global variable list) is where you would want to put it. But if a variable is only going to be used in 1 POU then you would want to make this a VAR in that POU. From a "best practice" standpoint you usually always want to limit your global variables to the smallest possible number and use more local VAR to the POU as possible.