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" 的角度来看,您通常总是希望将全局变量限制为尽可能小的数量,并尽可能使用更多本地 VAR
到 POU
。
我会给全局变量创建一个 STRUCT
,它包含一个组件的所有全局数据,例如一个名为 ST_CoolingSystem
的结构,它包含处理冷却系统的程序所需的全局数据等等
其他方法是 PROGRAM
POU 的方法/属性。它当然需要 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
我们可以添加一个PROPERTY
到FB_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,是自动添加的
这只是一个例子,真正的系统会有更多的代码和数据。可以(应该?)还有更多结构,每个结构用于命令、状态和参数。但这只是我的意见:)
在我的 61131 程序中,我有 Objects/Information 需要在不同的程序部分之间共享。关于此的最佳实践是什么,需要共享的对象应该是 PRG POU 中的 VAR 还是 GVL 中的全局对象?
来自 "high-level" 编程我对全局数据持怀疑态度,但这可能是必要的?
感谢您对 61131 中的最佳实践架构提出任何意见。
PRG_POU
中的VAR
相当于标准OOP类型语言中的局部变量。如果您想要一个可以在不同 POU 中使用的对象 instance/information,那么 GVL(全局变量列表)就是您想要放置它的地方。但是,如果一个变量仅在 1 POU
中使用,那么您可能希望在 POU
中将其设为 VAR
。从 "best practice" 的角度来看,您通常总是希望将全局变量限制为尽可能小的数量,并尽可能使用更多本地 VAR
到 POU
。
我会给全局变量创建一个 STRUCT
,它包含一个组件的所有全局数据,例如一个名为 ST_CoolingSystem
的结构,它包含处理冷却系统的程序所需的全局数据等等
其他方法是 PROGRAM
POU 的方法/属性。它当然需要 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
我们可以添加一个PROPERTY
到FB_Cooling
,它可以用来检索结构并读取和编辑它。因为它returns是一个引用(像指针),我们可以删除属性.
属性 的类型:
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,是自动添加的
这只是一个例子,真正的系统会有更多的代码和数据。可以(应该?)还有更多结构,每个结构用于命令、状态和参数。但这只是我的意见:)