61131程序架构

Architecture of 61131 program

在我的 61131 程序中,我有 Objects/Information 需要在不同的程序部分之间共享。关于此的最佳实践是什么,需要共享的对象应该是 PRG POU 中的 VAR 还是 GVL 中的全局对象?

来自 "high-level" 编程我对全局数据持怀疑态度,但这可能是必要的?

感谢您对 61131 中的最佳实践架构提出任何意见。

PRG_POU中的VAR相当于标准OOP类型语言中的局部变量。如果您想要一个可以在不同 POU 中使用的对象 instance/information,那么 GVL(全局变量列表)就是您想要放置它的地方。但是,如果一个变量仅在 1 POU 中使用,那么您可能希望在 POU 中将其设为 VAR。从 "best practice" 的角度来看,您通常总是希望将全局变量限制为尽可能小的数量,并尽可能使用更多本地 VARPOU

我会给全局变量创建一个 STRUCT,它包含一个组件的所有全局数据,例如一个名为 ST_CoolingSystem 的结构,它包含处理冷却系统的程序所需的全局数据等等

其他方法是 PROGRAMPOU 的方法/属性。它当然需要 Codesys 3 或类似软件。通过这种方式,您可以为程序或功能块本身的变量/结构创建一个 getter,例如 PRG_CoolingSystem.GetData() 其中 returns 结构或对它的引用。

更新:

使用 OOP 功能的一种方法是添加一个 属性 returns 对数据结构的引用。 注意:这适用于 TwinCAT 3,应该也适用于具有新功能的其他 IEC 61131-3 系统。

假设我们有一个结构 ST_Cooling

TYPE ST_Cooling :
STRUCT
    //Commands
    RunCooling          : REAL;
    TemperatureSetpoint : REAL;

    //Status
    MotorRunning        : BOOL;
    CurrentTemperature  : REAL;
END_STRUCT
END_TYPE

而且我们还有一个功能块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

我们可以添加一个PROPERTYFB_Cooling,它可以用来检索结构并读取和编辑它。因为它returns是一个引用(像指针),我们可以删除属性.

的Set方法

属性 的类型:

PROPERTY Data : REFERENCE TO ST_Cooling

添加的属性的Get()代码:

//FB_Cooling.Data (Get)

//Return reference to the data struct
Data REF= Data_;

现在可以从任何可以访问功能块实例的地方读取和编辑数据。

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();

也许这张图片也解释了它在项目中的样子。看到Data属性是Get,是自动添加的

这只是一个例子,真正的系统会有更多的代码和数据。可以(应该?)还有更多结构,每个结构用于命令、状态和参数。但这只是我的意见:)