西门子PLC “事务型” 信息的通信
2022-01-04杨继志
杨继志
(北京航天试验技术研究所, 北京 100074)
0 引言
西门子PLC 之间的通信有两种最为常用的方式,一种是双边通信,通信双方都需要编写通信程序,还有一种是通过PUT/GET 机制实现的单边通信,这种通信方式只需要通信一方编程,因此应用也是非常普遍的。 本文简要介绍两种机制在实际工程中的应用方式,但是本文并不准备讨论西门子PLC 之间的各种通信方式的实现细节以及区别,而是在讨论两种最常用的西门子PLC 之间的通信方式基础上,讨论为“事务型”数据的通信提供一个更高层的协议的原因、 如何构造一个这种协议,以及协议通过SCL 程序的实现方法。 为什么需要一种更高层的协议,主要在于PLC 之间的通信机制的设计思想主要是为设备的控制,传统上一台PLC 与其他的PLC 之间的通信主要目的是控制或获得对方的IO 点状态或信息,但是随着PLC 处理能力的提高,一些工艺、整线上的信息有些也在PLC 中进行处理,这样就出现了一些“事务型”数据通信交换的需求,而这种针对控制设计的通信对于“事务型”数据的通信支持存在一些问题,因此需要一个高层协议解决这些问题。
1 目前的通信方式及特点
1.1 西门子PLC 之间常用的通信方式
西门子PLC 之间的通信常用的有两种方式, 一种是在通信双方的CPU 中调用通信函数(TSEND_C,TR CV_C);还有一种通信方式采用PUT/GET 机制,通信双方只需要一方进行编程, 这在设备控制通信中非常方便,相当多的SCADA 系统与西门子PLC 之间的通信也是采用这种方式,优点是PLC 侧不需要额外的编程,只需要将接口(DB 全局数据块)属性设置为允许PUT/GET 并且关闭块的优化存贮即可,这种通信不但适用于西门子最新的1200、1500 系列PLC 而且还适用于其较早一些型号的PLC,包括SMART200 等,因此应用较广。 无论哪种通信方式一般的通信编程结构如下:把通信双方叫做A、B,以采用PUT/GET 通信方式为例,其中PUT/GET 指令编程在A 中实现,控制功能是A、B 双方控制一整套工艺设备,其中A 控制的工艺设备需要与B 控制的工艺设备进行通信, 在A 中生成两个全局数据局块如DB1_PUT,DB2_GET,用于向B 发送数据和接收B 的数据, 同样,B 中生成两个结构相同的全局数据块,如DB1,DB2,其中DB1 与A 中的DB1_PUT 链接,DB2与A 中的DB2_GET 链接,通信过程见图1。
图1 常用的通信模式
通过这种通信方式,设备A 中的各控制点的状态就实时传递到了PLC_B 中了,同样地,设备B 中的各控制点的状态也时时传递到PLC_A中。 PLC_A 控制设备B 中的控制点或获得设备B 中的控制点状态就如同控制本PLC 下的控制点一样简单和容易。
图1 表达的这种通信方式工艺数据是存贮在接口中的, 而且一方的通信接口持续不断接收另外一方的数据,造成本PLC 内的程序也不可以对接口中的工艺数据进行修改了,可以将这种现象叫做数据的“锁死”。锁死式通信是设备控制所必须的一种机制,所以对于单纯的设备控制任务这种通信模式不存在任何问题,而且是必须的,但是对于读写整线唯一信息这类非实时数据就存在问题,包括不同通信方并发改写问题,而且由于编程水平的不同,如果是不同单位分别负责整线某段设备控制,当一方程序存在瑕疵,则这种锁死式通信会造成问题长期得不到解决,控制总体希望即使某些工艺段程序存在瑕疵, 问题也仅仅存在整线的一部分,不会对整线的数据和通信造成较大的影响,这些需求在“锁死”式通信的情况下无法解决。
1.2 “锁死”式通信
1.3 数据与接口耦合
图1 表达的这种通信方式对于IO 控制是最为方便的,可以看到这种模式数据和接口是耦合在一起的,接口即是通信双方的界面,也是工艺数据存贮的位置。在逻辑和工程实践中均需要接口和数据解耦, 一方面在接口变化时不至于对数据存贮造成影响, 另外一方面保证数据的统一性。 这种数据与接口耦合情况可见图2。
图2 “事务型”信息接口和数据耦合
在通信双方的全局数据块接口中均有“事务型”信息,接口中的数据通过PLC_A 内部的处理后会将更新状态放置在与PLC_B 通信的DB 块位置处。同样PLC_B 也可能根据本PLC中的设备运行状态和工艺状态对这个信息进行处理,之后再传递给PLC_A。 并不是所有的“事务型”信息的传递都采用如上的方式, 有些具体的项目的信息传递可能只有该过程的一部分, 但是完整的逻辑链条与上图基本是一致的。
2 存在的问题
2.1 数据存储于接口
如图2 所示,直接采用单边、双边通信机制传递事务型数据, 接口中的数据既是要存储数据也要与多方进行“锁死”通信,这样存在的问题就是,多方均可对该数据进行直接的操作, 唯一数据管理方对该数据的管理能力削弱,根本原因是接口与数据存贮耦合,而一般在设计上希望的是进行一定的判断之后才进行存贮数据的修改等操作,总控PLC 有相应的接受与拒绝修改工艺数据的能力,在这种接口与存贮耦合的状态下就难以实现。 接口与存贮解耦、分离是解决“事务型”数据通信的一个核心思想,可以参考面向对象的思想解决这个问题, 接口中只存在一些实现(函数),数据只有通过接口中的实现才能获得。
2.2 接口仅能传递数据
一般来说对接口能力的要求除能够传递数据外,有时还需要能够申请一些过程的运行,也就是由PLC_B 通过接口可以启动PLC_A 中的某些过程,这也是接口与存贮解耦后的一个自然要求。 接口需要得到存贮在其他位置的数据显然是需要通过某些过程实现的。 也就是接口除能够传递数据还能够传递某些函数的“指针”。通过PLC_A 中自己的函数对数据进行修改,同样获得这些数据也需要通过接口进行而不是直接获得或修改,这样便于将此类数据进行封装。 而图1、2 表达的通信过程接口仅能够传递数据。
2.3 接口形式变化影响大
接口不可能一次性全部设计完成, 在项目进行过程中接口中的数据变得越来越复杂。 希望的接口一方面在项目实施过程中有一定柔性, 在项目的进化过程中接口的含义可以发生变化, 而这种变化却不会带来太多的编程结构方面的变化是最好的。 显然这种模式要么在双方通信前全部定义完成接口的含义, 并在后续的过程中接口完全保持不变,如果在项目进展过程中接口发生变化,则双方的程序变化量较大, 特别是增加了协作双方的沟通成本。 最好的方式是,在接口的大体形式确定后,在后续的项目演化过程中即使通信的需求发生了变化但是双方的接口可以保持不变或基本不变, 而且通信一方若不对通信方面的编程进行修改也不会影响到这个项目的通信,这是一种自然的需求。 而这种锁死的、接口和数据完全耦合在一起的通信方式是无法实现这个需求的。
3 解决办法
3.1 通信接口与数据存贮分离
接口和数据分离是“事务型”数据通信的自然需求,能够保证数据的唯一性和统一性, 但是需要接口和数据之间有一些函数关系, 比如通过确定的函数将数据放入存贮位置,或提取最新的数据并放入接口,因此需要在接口中描述这些动作以及动作需要的参数, 另一方面需要在全局数据块开辟一个专门的DB 用于存贮数据,见图3。
图3 接口和数据分离
实现方式是设计一个全局数据块,这个数据块中包含一些信息,利用这些信息可以运行PLC 中的一些函数,显然这样的数据块至少需要包含需要启动的函数的函数名称(当然并不一定是字符串型的数据类型,可以是整数型的数据类型,其实这种数据类型在后续的处理时更为方便) 和函数的参数。通过这个函数实现接口和数据存贮分离,即使是通信对象不遵守该协议的情况下也不会影响其他遵守协议的通信方。
3.2 通过接口启动过程
通过一个全局数据块实现驱动函数运行, 而且是函数名变量发生变化时运行一次, 避免了多个通信方得通信锁死问题,而且实现了利用接口数据启动PLC 内过程。利用这种机制建立一层协议,避免任何一方直接“锁死”通信信息,虽然同一个信息也可能出现在不同的位置,但是这些位置只有一个是临时的存贮位置, 而且任何一个通信方都不可能对其进行“锁死”式的通信,避免由于某个通信方程序瑕疵造成影响。 协议的自动机描述见图4。
图4 协议状态机描述
协议的状态机描述:接口中函数名称是否发生变化,如果未发生变化则继续监控接口,如果发生变化,则在函数驱动表中检索响应的函数并执行一次, 之后回到继续监控接口表中函数名是否发生变化。
接口中本质上是存贮函数的 “指针”,PLC 中只需要在一个永远保持运行的监控函数中一个CASE 语句维护实现函数映射表即可。 本文介绍这种编程思想时采用整形数作为“指针”,采用CASE 语句进行函数表映射管理。接口中的函数参数表是所有可能运行函数的参数并集,在具体编程和操作过程中,这个表也可能需要变化,当然如果采用DB_ANY 类型的数据可以保证这个接口的不变性,但是增加了处理函数的复杂性,增加了通信的复杂性,在实际的项目开发中也许是不适当的,因此做这种折中的考虑是实际项目开发可以接受的。接口中的函数一般是只需要运行一次即可,但是接口中的数据一般情况下都是全时间保持的,所以需要检测函数名发生变化时运行函数一次。 如下一个DB 数据块,这个数据块可以起名称为“INTERFACE”,见图5。
图5 函数驱动接口数据块
通过函数Fun1、Fun2……就可以执行品牌号改写、获取品牌号等函数操作,也就是将品牌号码的读写添加到一个函数接口,而不是直接锁死,这样能够保证改写的一致性和并发改写,“事务型” 数据是存贮在一个位置,其他位置仅仅可能会出现暂存数据。 函数映射表管理见图6。
图6 函数映射表
在OB1 中运行一个函数时时监控DB1 数据块中的Fun_name 是否发生变化,如果发生变化,则以Par1、Par2等函数参数运行相关的函数一次。
3.3 解决的问题
(1)灵活的接口数据定义。 从以上通信“协议”的描述可以看到,由于数据是通过函数的参数传递的,因此接口中的数据含义取决于当时运行的函数, 运行不同的接口函数,在同一个位置可以得到不同含义的数据,因此接口更灵活,且数据的获得均是通过函数获得,函数可以进行相关的判断处理,避免锁死通信的问题。
(2)实现数据驱动。通过接口中的数据实际上实现了驱动PLC 中的过程, 启动和停止, 实现了通过接口驱动PLC 过程的目的。 接口不仅仅是数据的交换,而且可以运行对应PLC 上不同的函数过程。在项目演化过程中,虽然不可能保证接口的永远不变, 主要是无法确定未来的函数的参数类型和数量, 如果对函数类型和数量进行一定的限制显然是可以部分解决这个问题的, 但是显然接口形式的变化比数据型接口变化的要小的多。 因为他本质上是实现了接口函数参数的“复用”。
4 结束语
目前西门子PLC 之间的通信都是为了设备控制而开发的, 因此通过各种通信方法控制其他PLC 上的设备就像是直接在本PLC 下的设备控制一样方便, 但是这种通信方式对于“事务型”数据的通信就存在一些问题,主要表现在接口与数据耦合、“锁死”式通信等。本文提出在该通信协议的基础上开发一种高层协议, 解决接口与数据耦合问题、PLC 中数据对象的封装等问题,并且使得通信除了具备数据交换的功能外还可以启动对应PLC 中的某些过程,拓展了接口的功能和能力。本文中的“事务”型信息指的是不同于设备的控制信号和状态信号, 比如生产线中的线上正在生产的产品的牌号和批次信息, 这些类型的信息一般在不同的PLC 和设备中均需要处理和存贮,但是整条线的该信息最好是存在一个共同的位置,通信有的时候并不是仅仅传递一些信息, 还希望通信方按照已经商定的协议作出某种复杂的动作, 本文提供了一种解决如上问题的改进通信机制。