PLC面向对象编程的好处

面向对象编程(OOP)是通过使用对象、方法和属性以最佳方式组织和简化程序元素。

通过理查德Jafrate 二零一六年十月七日

最新的IEC-61131-3标准更新包含面向对象编程(OOP)语言。尽管OOP经常与冠冕堂皇的术语联系在一起,但它其实非常简单。面向对象编程是关于组织和简化的。组织是指对程序元素进行分组的方式和采用分组机制的方式。组织良好的程序更直观,也更容易使用。面向对象的特性旨在促进和促进健全的组织项目。简化是指呈现给外部世界的简化界面。在这个表面之下,对象本身的复杂细节被保存在程序中。

什么是对象?

对象将相关的功能和它们所依赖的数据组合成一个单一的实体,该实体对现实世界的设备、流程和其他结构的状态和行为进行建模。简单是通过在对象本身中保留复杂的细节并向外部世界呈现简化的接口来实现的。其他程序可以通过简化的接口与对象交互,而不需要了解对象的内部工作。

在IEC-61131-3标准中,对象被实现为具有一些附加功能的功能块。功能块可以定义方法和属性,以进一步划分代码和扩展接口。方法和属性可以使用任何IEC-61131语言实现。语言选择是由个别方法或属性基础决定的,这使得根据情况很容易使用最适合的语言。

示例项目包含一个功能块,该功能块实现了一个简单的上升/下降计数器,其定义如图1所示。在其他OOP语言中使用的术语“类”是“函数块”的同义词。这两个术语都指的是在使用之前必须实例化的定义。类或功能块的实例被称为“对象”。

定义方法

方法是在函数块上下文中定义的函数,可以访问定义函数块的内部数据和参数。它们也可以像普通函数一样具有输入和输出参数以及返回值。

在图2中,使用Relay Ladder作为实现语言定义了一个方法。当输入参数为真时,计数器递增直到达到最大值。PMaxCount和Count定义在函数块的主体中。因为方法可以访问函数块的数据和参数,所以PMaxCount和Count可以在方法中使用。返回值被写入CountUp,这是方法本身的名称。

变量NotMax在方法中定义,并在方法的调用堆栈上分配。这意味着前一次执行的值不会被保留。函数块体中定义的变量被分配到内存中,并在执行到执行期间保留其值。

图3中定义了第二个递减计数器的方法。这一次,实现语言是结构化文本。当输入参数为TRUE时,计数器递减,直到值为0。Count是函数块的输出参数,返回值被写入方法名CountDn。这种方法提供了一种简单方便的方法,可以将程序组织成更小、更易于管理的部分。它的设计也很容易混合和匹配不同的语言。

从函数块体调用这些方法很简单,如图4所示。由于这些方法是使用关键字“PRIVATE”定义的,因此只能从函数块内部调用它们。使用关键字“PUBLIC”定义的方法也可以在外部调用。

定义属性

属性是行为类似变量的函数,可以像使用变量一样在表达式中使用。属性不是绑定到内存位置,而是绑定到它的get()和set()函数。当从属性中读取数据时,将执行它的get()函数。当数据写入属性时,它的set()函数将被执行,如下例所示:

“PUBLIC”和“PRIVATE”关键字也可以用来控制访问属性的方式。“PRIVATE”表示该属性只能在定义函数块内部使用。“PUBLIC”表示该属性可以对外使用。然而,"PUBLIC"和"PRIVATE"关键字也可以与get()和set()函数定义一起使用。这允许属性在外部可读,在内部可写。

属性最基本的形式是从内部变量中读取和写入数据。它们的附加功能可用于验证数据值或执行其他操作。例如,将属性MaxCount添加到图5所示的程序中。这允许将最大计数设置为指定值,并读取其当前值。数据通过MaxCount属性名传递给set()和get()函数,就像它是一个变量一样。函数的作用是:返回函数块变量PMaxCount的值。set()函数在将结果写入PMaxCount之前,通过确保输入值为正数来验证输入值。

属性还可以执行操作,而不仅仅是读写数据。在示例的下一部分中,使用Relay Ladder语言将Reset属性添加到图6中的项目中。reset属性没有可读写的底层变量。当写入值为TRUE时,执行重置操作。当读取该属性时,将计算表达式并返回结果。

值得注意的是,项目的结构和组织是如何反映在项目树中的。项目中的每个程序、功能块、方法和属性都由一个节点表示。双击一个节点将在主窗口的文档页中将其作为一个选项卡打开。选项卡可以取消停靠,并显示为单独的窗口,如图5和图6所示。get()和set()函数是未停靠的,因此两者都可以与属性定义一起显示。

扩展功能块

当一个功能块满足了几乎所有的需求,除了一些需要做不同处理的事情,会发生什么?通常情况下,函数块会根据需要进行复制和修改。这种情况的问题在于,两个块中的大量代码是相同的,这意味着可能需要进行两次错误修复或其他修改。

这可以通过扩展原始功能块而不是复制来避免。原始块的变量、参数、方法和属性定义应用于新块。这个块被称为从原始块“继承”或“派生”。因此,对原始块所做的更改将反映在新块中。

在图7所示的示例中,添加了一个新的函数块FB_MyUpDn。通过使用关键字“EXTENDS”,新块继承了原来向上/向下计数器FB_UpDn的所有数据、参数、方法和属性。FB_UpDn主体中的代码没有被继承,这使得两个函数块在这一点上是相同的。

新的函数块通过定义自己的属性对MaxCount属性施加了一个上限,该属性实现了图8所示的限制。新属性将覆盖原函数块中定义的MaxCount属性。从原始块的实例调用MaxCount(500)执行原始MaxCount代码,并将值设置为500。从新块的实例调用MaxCount(500)执行新代码,并将该值设置为上限250。

程序呢?

程序是一个函数块,其中定义和实例是相同的。因此,一个程序只有一个实例,但它也有几个与函数块相同的特性。程序可以像函数块一样定义内部数据、参数、方法和属性。尽管这并没有严格遵守OOP的规定,但它是一种有用的技术,可以应用于任何程序,而不考虑底层的设计理念,如图9所示。

在本例中,已将A_Property和示例方法A_Method添加到主程序中,以演示此功能。主程序还包含FB_UpDn函数块的实例。函数块及其两个主要属性用于程序主体中。Reset属性写在第一梯级,它的值在第二梯级读取。UpDn功能块的代码在第三档执行。最后两个梯级将值写入MaxCount属性。

利用对象进行设计

对象对给定实体的状态和行为进行建模。好的基于对象的设计的关键是选择要建模的实体。好的选择会产生干净直观的设计。然而,做出正确的选择既是科学也是艺术,也是这个过程中最困难的部分。将对象视为现实世界的设备和进程是一个很好的开始。从有形的实体开始,然后转向抽象的概念,比一次性尝试所有东西要容易得多。

结论

OOP还有更多内容,但这一切都回到了以最佳方式组织程序元素的基本目标上。对象、方法和属性是实现这一目标的主要手段,因此理解和掌握这些概念非常重要。从一些小步骤开始组织常规项目;基于对象的设计可以稍后出现。熟悉使用这些技术将使您更容易想象所有其他可能性。没有理由不试一试。

理查德Jafrate他是Mitek自动化公司的创始人。由制作编辑克里斯·瓦夫拉编辑,控制工程, CFE传媒,cvavra@cfemedia.com

更多的建议

关键概念

  • 面向对象编程(OOP)是关于组织和简化。
  • 功能块可以定义方法和属性来进一步划分代码和扩展接口。
  • 基于对象的设计是关于选择要建模的实体。

考虑一下这个

还有什么其他面向对象的方法可以使用?

在线额外

www.mitek-automation.com

资源

示例项目是使用Bedrock Automation的集成开发环境(IDE)创建的,该环境可以从他们的网站上免费下载。

www.bedrockautomation.com/download

示例项目的源代码可以从Mitek Automation的网站上下载。

https://mitek-automation.com/resources

有关PLC编程的其他故事,请参见下面的链接。