APP下载

基于Prodave组件的PLC通讯接口的设计与实现

2020-09-10夏富平

内燃机与配件 2020年13期
关键词:设计模式

夏富平

摘要:上位PC机利用从PLC控制器实时采集的各项实时数据,自动监控现场各种机械设备和传感器设备的运行状态,并根据设备的实时状态进行有效合理的统计分析,从而实现工业控制系统的自动化和信息化管理,这已成为工业控制领域的一个重量的发展方向。本文以西门子的Prodave 组件为基础,设计并实现了一种上位机与PLC控制器通讯的通用接口,项目实践证明,该通讯接口稳定性好、扩展性强且实际操作灵活方便,便于用户将此通讯接口集成至各类工业控制系统中。

关键词: simatic;prodave;PLC;C#;设计模式

1  概述

自动化工业控制领域中PLC作为一种高效、灵活、稳定的控制器,有着广泛的应用。以PLC控制器为核心,上位PC机为实时监控体的控制系统已经成为工业自动化PLC控制系统的一个重要发展方向。实现PLC与PC的通信可以实现向上一级提供诸如工艺流程图、动态数据画面、报表显示等多种窗口技术,使PLC控制系统具有良好的人机交互界面,通过上位机对PLC数据的读写监控实现现场数据的采集、传送以及生产过程调度的自动化和信息化,其应用前景十分广阔。

自动化生产线控制系统中通常会采用工业组态软件开发上位机系统,PLC作为下层控制设备,目前市场上通信组态系统结构复杂,价格昂贵,应用繁琐,且不具备一定的通用性。随着工业以太网的深入发展,相较于品种繁多的组态软件来说,高级编程语言更加适合开发具有实时响应、功能丰富、扩展方便、高灵活性和易于移植等技术需求的上位机系统。为此,需要设计一种与PLC通信的通用接口,用户采用高级编程语言开发的上位机系统能够运用此通讯接口与PLC进行数据通信。

本文以造纸行业中纸卷输送控制系统的设计方法为基础,对西门子S7系列中的PLC与上位机通讯的原理作深入细致的研究,依据Visual Studio 2005作为开发平台用C#语言实现了PLC与上位PC机的通用通讯接口,该接口具有稳定性好、易于扩展维护且操作方便的特点,对于需要用上位机与PLC通讯的工程设计人员来说,具有一定的借鉴作用。

2  西门子Prodave组件介绍

Prodave是“Process Data Traffic”(过程数据交换)的缩写形式,可以用于西门子S7-200、S7-300/400、M7和C7等S7系列PLC的通讯,通过MPI通信处理器、PC/MPI适配器和以太网络可以方便地在PLC与PC之间建立数据链接。Prodave的动态链接库(Dynamic Link Library,DLL)提供了大量的基于Windows系统的DLL函数,为用户提供了解决上位机与PLC之间的数据交换与数据处理的详细方案。

表1为项目中涉及到的Prodave组件的简单介绍。

现阶段项目中使用的Prodave组件版本主要有Prodave5.x系列和Prodave6.2系列。其中,Prodave6.2可用于Window 64位操作系统,且可以采用MPI-Profibus或者以太網通信,而其他版本的组件只能安装于Windows 32位操作系统的上位机中,一般采用MPI-Profibus通信方式。

Prodave组件的函数分为基本函数、数据处理函数和电话服务函数,基本函数主要包含建立连接、关闭连接、激活连接、读取PLC地址数据以及写入PLC地址数据的函数。

3  通用接口的详细设计方案

3.1 现有设计问题

由于上位机与PLC通信需要用到的Prodave组件版本过多,导致上位机与PLC通信时接口不尽相同,代码复用能力差。当上位机硬件设备升级或者更换Prodave通讯组件时,需要修改上位机控制系统中与PLC通信的模块代码。在纸卷输送控制系统的设计过程中,由于每个项目的工艺设计和功能要求不同,工程设计人员在做项目方案设计和设备选型时,选用西门子的CPU型号也不尽相同,因此网络设计人员需要根据不同的工艺需求采用不同版本的Prodave组件来编写与PLC通信的代码。图1为上位机与PLC控制器现有通讯结构。

3.2 通信接口设计要求

由于与PLC通信的Prodave组件版本多,对应的接口函数也不尽相同,因此对上位机来说,新的通用接口需要满足以下设计要求:

①通用性能强。能够满足现阶段项目中使用的不同Prodave组件的要求,当通信组件发生改变时,原有通信模块不用发生变化;

②有较强的灵活性和扩展性能。如果未来出现新的Prodave组件的升级,现有系统中涉及的PLC通信模块代码不用发生变化,仅需要按接口要求增加新的Prodave组件对象即可;

③封装性好,利于模块移植。通用接口对应的PLC通信模块可以非常方便的迁移至其他项目中,尽可能少的修改原有模块代码。

3.3 通信接口设计方案

通过深入分析可以得知:不论是哪一种Prodave组件,上位机控制系统均希望此组件能完成对PLC控制器的建立连接、读取数据、写入数据和关闭连接的功能,而各种版本的Prodave组件均能满足此种功能,不同的是接口函数名称以及输入参数各不相同。因此,可以按照软件设计模式中的工厂设计方法,将涉及到与PLC操作的各个对象中操作函数按一定的规则抽象出来,形成一个通用的接口对象。图2是改进后上位机系统与PLC的通讯结构。

3.4 通用接口的设计实现

在实现通用接口对象前,首先需要分析现有各版本Prodave 组件对应的接口函数,然后再根据各接口函数再抽象成对应的接口对象。

①Prodave5.x组件。

主要包含有加载与激活连接、读取与写入PLC数据以及卸载连接的接口函数。

protected extern static int load_tool(byte nr, string device, byte[,] adr_table)

protected extern static int new_ss(byte no)

protected extern static int unload_tool()

protected extern static int d_field_read(int dbno, int dwno, int amount, byte[] buffer)

protected extern static int d_field_write(int dbno, int dwno, int amount, byte[] buffer)

②Prodave6.x组件。

主要包含有加载与激活连接、读取与写入PLC数据以及卸载连接的接口函数。

protected extern static int LoadConnection_ex6(int ConNr, string pAccessPoint, int ConTableLen, ref CON_TABLE_TYPE pConTable)

protected extern static int SetActiveConnection_ex6(UInt16 ConNr)

protected extern static int UnloadConnection_ex6(UInt16 ConNr)

protected extern static int field_read_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen, byte[] pBuffer, ref UInt32 pDatLen)

protected extern static int field_write_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen, byte[] pBuffer)

從上述各版本Prodave组件对应的接口函数可知,Prodave5.x系列对应的主要接口函数的函数名称与对应参数数量与类型与Prodave6.x系列对应的主要接口函数函数名称与对应参数数量与类型基本不相同。因此需要在各个引用Prodave组件对应的接口对象之上还需要抽象一个适配对象,目的在于将原始接口函数与加工后的接口函数分离开,将各组件使用的接口函数的函数名称与函数参数数量尽量保持一致。

图3为对应组件的类设计示意图,从图中可以看出,每一种Prodave组件的接口函数均有一个适配对象与之对应,如Prodave5.0的接口对象PLCProdave5D0与适配对象PLCOperation5D0对应,同理Prodave5.6的接口对象PLCProdave5D6与适配对象PLCOperation5D6对应, PLCProdave6D0与适配对象PLCOperation6D0对应。从图3中还可以看出,每一类适配对象对应的连接函数(ConnectPLC)、重新连接函数(ReConnectPLC)、读取PLC数据函数(ReadData)、写入PLC数据函数(WriteData)以及关闭连接函数(CloseConnectPLC)对应的函数名称、函数对应参数数量和类型均相同,每个适配类使用的属性名称和数量以及定义的事件名称和返回的参数也相同。因此,可以在对应的适配器对象之上编写统一的通用接口对象IPLCOperation。适配对象PLCOperation5D0、PLCOperation5D6和PLCOperation6D0除了继承各自对应的接口对象外,还需要实现IPLCOperation和IDisposible接口,其中实现IDisposible接中主要用于在关闭对象时要求系统显示释放对应内存等重要资源。

从图3Prodave组件类设计图中,将各适配器对象相同的部分抽象出来可以非常容易得到通用的PLC接口对象如图4所示。

通用接口中用到的其他相关对象如图5所示

以下代码为通用接口类的具体实现方式:

public interface IPLCOperation

{

event PLCMessageEventHandler OnPLCMessageChanged;

bool Connected  {get;}

PLCType CurrPLCType { get; }

bool ConnectPLC();

bool CloseConnectPLC();

bool ReConnectPLC();

bool ReadData(int dbno, string strAddr, ref string retBoolValue);

bool ReadData(int dbno, int dwno, int amount, ref byte[] buffer);

bool WriteData(int dbno, string strAddr);

bool WriteData(int dbno, string strAddr, bool blnValue);

bool WriteData(int dbno, int dwno, int amount, ulong data);

bool WriteData(int dbno, int dwno, int amount, byte[] buffer);

}

最后建立了一个PLC操作工厂类,完全将各种具体的PLC接口实现对象封装起来,主要是根据外部参数的不同创建不同的具体的PLC操作对象实例,以下代码为工厂类的具体实现代码:

public class PLCFactory

{

public static IPLCOperation CreatePLC(PLCType plcType, PLCConnItem plcConnParams)

{

IPLCOperation currPLCOperation;

switch (plcType)

{

case PLCType.PLC_5D0:

currPLCOperation = new PLCOperation5D0(plcConnParams);

break;

case PLCType.PLC_5D6:

currPLCOperation= new PLCOperation5D6(plcConnParams);

break;

case PLCType.PLC_6D0:

currPLCOperation = new PLCOperation6D0(plcConnParams);

break;

default:

currPLCOperation = new PLCOperation6D0(plcConnParams);

break;

}

return currPLCOperation;

}

}

上述代码将PLC组件类型和PLC连接参数对象传入PLC工厂对象中,由工厂对象根据PLC组件类型来实例化不同的PLC操作类。当然上述实现实例化不同PLC操作类还可以使用反射的方法,在此不再赘述。

4  通用接口的具体操作实现

上位机控制系统只需要关注PLC通信通用接口的实现方式,因此在项目实际使用过程中,系统设计人员可以按以下方式使用。

4.1 PLC模块初始化

在实际项目设计过程中,如某台上位机控制系统需要与一个以上的PLC通信,此处可以在PLC通信模块中,可以建立一个以PLC通用接口对象为元素的PLC接口集合,将控制系统需要使用的PLC通信接口封装在此集合体中,方便程序遍历PLC通用接口和存储连接PLC需要的各种参数值,图6为多个PLC通信接口对应多个PLC的应用场景:

private void InitialPLCModule()

{

CGlobal.PLCHelpers.Clear();

foreach (DataRow currRow in m_dtPLCConnParams.Rows)

{

//PLC连接参数初始化

PLCConnItem plcItem = new PLCConnItem();

plcItem.GongweiType = m_GongweiType;

plcItem.MobanNO = m_MobanNO;

plcItem.ByteBuffer = new byte[m_MaxBytesCount];

plcItem.DBUnit = m_DBUnit;

plcItem.Address=m_Address;

//建立一個PLC通用接口类,并将其放至集合中

IPLCOperation plcHelper = PLCFactory.CreatePLC(m_plcType, plcItem);

plcHelper.OnPLCMessageChanged += new

PLCMessageEventHandler(PLCHelper_OnPLCMessageChanged);

plcHelper.ConnectPLC();

plcItem.PLCHelper = plcHelper;

CGlobal.PLCHelpers.AddPLCConnItem(plcItem);

}

}

4.2 PLC数据读取操作

当PLC接口集合不为空时,可以循环遍历PLC接口集合中的通用接口类,并读取对应的PLC对应地址块中数据放置在指定的字节数组中。

private void ReadPLCData()

{

if (CGlobal.PLCHelpers == null || CGlobal.PLCHelpers.Count == 0) return;

byte[] bytBuffer;

foreach (PLCConnItem plcItem in CGlobal.PLCHelpers)

{

if (plcItem == null || plcItem.PLCHelper == null)

{ continue; }

if (plcItem.PLCHelper.Connected)

{

bytBuffer = new byte[plcItem.ByteBuffer.Length];

bool blnSucc=plcItem.PLCHelper.ReadData(plcItem.DBUnit, 0, plcItem.ByteBuffer.Length, ref bytBuffer);

if (blnSucc) plcItem.ByteBuffer = bytBuffer;

}

else{

CGlobal.DelayTime(1000);

plcItem.PLCHelper.ReConnectPLC();

}

}

}

4.3 PLC数据写入操作

PLC数据写入的方法比较简单,首先按工位类型和模板类型参数遍历PLC接口集合中找到指定接口,然后调用对应的接口函数WriteData即可。

CGlobal.PLCHelpers[m_GongweiType,m_MobanNO].PLCHelper.WriteData

(dbunit,dwno,amount,value);

4.4 释放PLC模块资源

当需要释放PLC接品资源时,需要遍历PLC接口集合,先关闭当前连接,然后再销毁对象即可。

if (CGlobal.PLCHelpers != null) CGlobal.PLCHelpers.Clear();

5  结论

以西门子的Prodave 组件为具体研究对象,结合软件工程中的软件设计模式思想,设计并实现了一种上位机与PLC通讯的通用接口,该通讯接口已成功应用于福建联盛纸业PM5&6,PM7,PM8、山东太阳纸业PM19&20,24、安徽山鹰PM5&6等多套纸卷输送控制系统中。实践证明,该通讯接口可以使通讯模块的代码结构清晰,稳定性好、擴展性和集成性强且实际操作灵活方便,可适应复杂的项目工艺需求变化,具有一定的参考价值和应用价值。

参考文献:

[1]程宏.福建联盛纸业PM8输送控制系统源码,2012.

[2]程宏.山东太阳纸业PM24输送控制系统源码,2014.

[3]王翔.设计模式-基于C#的工程化实现及扩展[M].电子工业出版社,2012.

[4]葛新锋,晋景涛.基于VB的上位机与PLC通信系统实现,2009.

[5]赵晓明,徐立,邵威,夏春林.基于VC++的上位机与西门子系列PLC通信的研究[J].机电工程,2007.

猜你喜欢

设计模式
“1+1”作业设计模式的实践探索
新媒体下的广告设计教学改革与创新方法研究
智慧图书馆环境下的融贯式服务设计模式研究
信息化教学模式构建研究
基于生产者/消费者设计模式的连续音频信号采集系统
浅析基于问题的教学设计模式