基于OPC规范的客户应用程序实现(转载文章)

  
基于OPC规范的客户应用程序实现
石林锁,王涛,刘顺波 (第二炮兵工程学院机电工程系,陕西西安 710025摘要:介绍了过程控制领域中引进的一种新技术-OPC数据访问标准,论述了OPC相关概念、基础及OPC标准接口,并以OPC数据访问定制接口规范(1.0A)为蓝本,给出了利用Visual C++实现OPC客户应用程序的详细步骤。关键词:过程控制;OPC规范;接口;客户应用中图分类号:TP   文献标码:A
The Realization of Client Application Based on OPC Specification
SHI Lin-suo WANG Tao LIU Shun-bo
(Dept. of Mechanical and Electronic, 2nd Artillery Engineering College, Xi'an 710025, China)
Abstract: The paper introduces the OPC data access standard which was introduced into process control field recently, and discusses relative concepts, fundamentals and standard interfaces of OPC (Ole for Process Control). On the basis of OPC Data Access Custom Interface Specification (1.0A), the author gives out the detailed procedures to realize OPC client application using Visual C++.
Key Words: Process control; OPC specification; Interface; Client application
随着计算机技术与控制技术的不断发展,现代工业过程控制系统逐渐发展成为由现场设备管理、过程管理和商业管理三个层次组成的系统。在这种新的过程工业信息体系结构中,从现场设备管理层、过程控制管理层到商业管理层包含了各种信息。为了实现整个过程控制系统的信息集成,需要解决许多问题,其中最重要的是通信兼容问题。因为现场管理层中大量的现场数据信息必须以一致的形式提供给用户或应用程序;过程管理层必须将现场管理层送来的信息及时加以处理并递交商业管理层;在商业管理层中这些信息又以一致的形式送给客户应用程序以简化信息的综合过程。所以,解决这些问题的关键在于为过程控制系统的数据访问提供一种开放有效的通信标准。
   
在传统系统中,解决客户应用程序从数据源(如:现场设备、 SCADA 系统等)读取数据的方法是为不同的客户应用程序编写不同的驱动程序。但是,这种方式存在许多问题,如同一个设备为适应不同的应用程序可能需要多种驱动程序,不同的驱动程序之间存在着不一致性,驱动程序对硬件存在着极大的依赖性等等。为了解决这些问题,一些与微软公司合作的自动化硬件和软件供应商联合制定了一套称为 OPC 规范的 OLE/COM 接口协议,以此来提高过程控制工业中的自动化 / 控制应用程序,现场系统 / 设备以及商业 / 办公室应用程序之间的互操作性。可以说 OPC 是工业监控软件的现场总线,其基本思想是:每个硬件供应商为其设备开发一个通用的数据接口(即 OPC Server ),供其它系统读写信息,客户应用软件也可以通过 OPC 规范的接口来读写硬件设备的信息(作为 OPC Client )。由于硬件供应商通常将硬件驱动程序封装成 OPC Server 单独出售,这样作为 OPC 数据客户端的上层应用,可以不包含任何通讯接口程序,不必关心底层硬件内部的具体细节,只需遵循 OPC 数据接口协议,就能够从不同的硬件供应商提供的 OPC 数据服务器中取得数据。
OPC 规范提供了两套接口方案,即定制接口和自动化接口。定制接口效率高,通过该接口,客户能够发挥 OPC 服务器的最佳性能,采用 C ++语言的客户一般采用定制接口方案;自动化接口使解释性语言和宏语言访问 OPC 服务器成为可能,采用 VB 等语言的客户一般采用自动化接口。本文详细介绍了在 Visual C++ 环境下,使用 OPC 定制接口访问 OPC 服务器的通用实现方法。
1  OPC 的基本结构
OPC 由两套接口组成: OPC 定制接口和 OPC 自动化接口,如图 1 所示。 OPC 服务器必须实现定制接口,可选择实现自动化接口。这两套标准接口的制定极大地方便了服务器和用不同语言开发的客户应用之间的通信,使用户对开发工具的选择有了较大的自由。
SCADA
1  OPC 接口
OPC 接口可以潜在地应用在许多应用程序中。它们可以用于从最低层设备中读取未加工的数据,再转化至 SCADA 或者 DCS 系统;也可以用于从 SCADA 或者 DCS 系统中采集数据输入到应用程序中。 OPC 是为从某一网络节点中的某一服务器中采集数据而设计的,同时又能够形成 OPC 服务器。该服务器允许客户应用软件在由许多不同的 OPC 供应商提供的服务器中传输数据,并可通过单一的对象在不同的节点上运行,其工作特点如图 2 所示。
2  OPC 客户 / 服务器关系
2  OPC 定制接口
C C ++编写 OPC 客户应用程序时可以使用定制接口,也可以使用自动化接口。由于定制接口具有更高的性能,建议尽可能使用定制接口。本文在 VC 下实现的客户应用程序采用的是 OPC 定制接口 1.0 OPC 定制接口的类模式可以根据其接口及其方法划分为 3 组,依次呈包含关系,如图 3 所示。
3  OPC 定制接口的类模式
2.1  OPC Server 对象
OPC Server OPC 启动服务器,通过它获得其他对象和服务的起始类,并用于返回 OPC Group 类对象。 OPC Server 级别有多种属性,其中包含一个 OPC 服务器对象的状态和版本等信息。这种级别中的对象由客户应用创建。 IOPCServer 接口包含管理 OPC Group 级别中的对象的方法。如将组加入服务器或从服务器中删除组的方法( " AddGroup " " RemoveGroup " )。 IOPCBrowseServerAddressSpace 接口包含查找服务器地址空间的方法。 IOPCCommon 接口方法用于通知服务器语言的设置和客户机的名称。同时还存在以下接口:图 4 说明了 OPC Server 对象及其定制接口。
4  OPC Server 对象
2.2  OPC Group 对象
OPC Group 存储由若干 OPC Item 组成的 Group 信息,并用于返回 OPC Item 类对象。 OPC Group 级别管理被称为 OPC Item 的各个过程变量。 IOPCItemMgt 接口提供将项加入组或从组中删除项的方法( " AddItem " " RemoveItem " )。 IOPCGroupStateMgt 接口的方法用于处理组专用的参数或复制组。同时还存在以下接口:图 5 说明了 OPC Group 对象及其定制接口。
5  OPC Group 对象
2.3  OPC Item 对象
    OPC Item 存储具体 Item 的定义、数据值、状态值等信息。 OPC Item 级别的一个对象代表与一个过程变量的连接。该对象的唯一接口是 OPCItemDisp 。关于 OPC Item 的信息可以在属性表中找到,例如数值( " Value " )属性或存取路径( " AccessPath " )属性。图 6 说明了 " OPC Item " 对象及其接口。
6  OPC Item 对象
由于本文使用定制接口实现 OPC 客户应用程序,所以不使用 IOPCItemDisp 接口,而是使用枚举器对象 EnumOPCItemAttributes IEnumOPCItemAttributes 接口枚举服务器中的所有 OPC Item 。如图 7 所示。
7  EnumOPCItemAttributes 对象
3 OPC 客户应用程序的实现
3.1  操作 OPC 的类模型
按照 OPC 的类模型,当对象方法调用 OPC 对象时必须遵循一定的顺序。如果要创建一个 OPC Item 类的实例,则首先需要一个 OPC Group 对象。而要创建一个 OPC Group 对象的前提是存在一个 OPC Server 类的实例,并建立一个与该服务器的连接。图 8 说明了操作 OPC 类模型的流程。
操作 OPC 类模型的流程
3.2  编程顺序
本文在 Visual C++ 环境中实现的 OPC 客户应用程序包括所有通常在典型客户应用下都会有的部分,如:建立与服务器的连接,初始化变量的组,以及为一个项读写数据。下面详细介绍一下在 VC 环境下 OPC 应用的基本结构。
第一步:登陆 COM
如果程序要调用 COM 库的某一函数,必须先登陆 COM 。函数 CoInitialize() 可以完成此功能。从函数 CoGetMalloc() 可以得到一个指向 COM 内存管理接口的指针。
HRESULT r1;
r1= CoInitialize(NULL);
r1= CoGetMalloc(MEMCTX_TASK,&g_pIMalloc);
第二步:将 ProgID 变换为 CLSID
每个 COM 服务器有一个字符串类型的 ProgID ,通过它可以得到一个全球唯一的 CLSID 。用 CLSIDFromProgID() 函数可以实现这个转换。 ProgID 用变量 szName 进行参数传递。
r1= CLSIDFromProgID(szName,&clsid);
第三步:建立与 OPC 服务器的连接
CoCreateInstance() 函数创建一个 OPC Server 类实例,其 CLSID 值设定如下。
r2=CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER,IID_IUnkown,(void**)&pUNK);
这段程序的结果是得到一个指向服务器对象 IUnkown 接口的指针(变量 pUNK )。
第四步:请求其它接口指针
IUnkown 接口,通过 QueryInterface() 方法可以得到其它接口的指针。
HRESULT r3;
r3=punk->QueryInterface(IID_IOPCServer,(void**)&m_pOPC);
这段程序的结果是得到一个指向服务器对象 IOPCSever 接口的指针(变量 m_pOPC )。
第五步:创建 OPC
IOPCServer 接口的 AddGroup() 方法可以创建 OPC 组。
HRESULT r1;
r1=m_pOPC->AddGroup(szName,TRUE,500,&TimeBias,&PercDeadband,dwLCID,&m_GrpServerHandle,
&RevUpRate,IID_IOPCItemMgt,(LPUNKNOWN*)&m_pItemMgt);
这段程序的执行结果是创建一个有指定名称和属性的组。在返回的参数中,有一个指向所需要的进程组对象 IOPCItemMgt 接口的指针(变量 m_pItemMgt )。
第六步:添加项
IOPCItemMgt 接口的 AddItems() 方法可以添加 OPC 项。
HRESULT r1;
r1=m_pItemMgt->AddItems(NumItems,pItems,&m_pItResult,&pErrors);
这段程序的结果是添加具有特殊属性的指定数量的项。除此之外,事件结构变量 m_pItResult (服务器句柄,目标系统上的项数据类型等)也被赋值。
第七步:用 OPC 项执行所需的操作
用于执行所需操作的指针需要通过现有的指向 IOPCItemMgt 接口的指针得到。如:如果用户要进行异步通信,就需要指向 IOPCAsyncIO 接口的指针。
HRESULT r1;
r1=m_pItemMgt->QueryInterface(IID_IOPCAsyncIO,(void**)&pAsyncIO);
通过该接口的 Read() Write() 两个方法,就可以读写项的数值。
HRESULT r2;
r2=pAsyncIO->Read(m_dwConnection,OPC_DS_CACHE,dwNumItems,phServer,&m_TransactionID,
&pErrors);
这段程序的执行结果是, OPC 项的数据被送到客户程序的 IAdviseSink 接口。
HRESULT r3;
r3=pAsyncIO->Write((m_dwConnection,dwNumItems,phServer, pItemValues,&m_TransactionID,&pErrors);
这段程序的执行结果是, OPC 服务器代替 OPC 客户刷新物理设备的数据。
第八步:删除对象,释放内存
在程序停止运行之前,必须删除已创建的 OPC 对象并释放内存。到目前为止,用到的接口都有相应的函数。
r1=m_pItemMgt->RemoveItems(dwNumItems,phServer,&pErrors);
r1=m_pOPC->RemoveGroup(m_GrpServerHandle,TRUE);
m_pItemMgt->Release();
m_pOPC->Release();
3.3  异步通信的说明
OPC 客户和 OPC 服务器进行数据交换可以有两种不同的方式,即同步方式和异步方式。同步方式实现较为简单,当客户数目较少而且同服务器交互的数据量也比较少的时候可以采用这种方式;异步方式实现较为复杂,需要在客户程序中实现服务器回调函数。然而当有大量客户和大量数据交互时,异步方式的效率更高,能够避免客户数据请求的阻塞,并可以最大限度地节省 CPU 和网络资源。本文中用 VC 实现的 OPC 客户程序可以执行异步读写数据,异步意味着程序继续执行后面的操作,只要读或写的任务送达马上申请读写,并由 OPC 服务器返回回调函数的执行结果。为了实现异步通信,客户程序必须提供 IAdviseSink 接口与服务器方的 IDataObject 接口通信。下面详细描述一下用 VC 实现 OPC 客户应用程序中异步通讯的基本步骤。
第一步:得到指向 IDataObject 接口的指针
可以用这个接口在客户和服务器之间建立连接。为此目的,可以在程序中创建由 IAdviseSink 接口派生的 COPCData 类,并建立一个此类的实例 m_pOPCIData ,指向 IDataObject 接口的指针临时保存在这个类的 m_pDataObject 成员变量中。
m_pOPCIData=new COPCData(pWnd);
..........
r1=m_pItemMgt->QueryInterface(IID_IDataObject,(LPVOID*)&m_pOPCIData->m_pDataObject);
第二步:取得指向 IAdviseSink 接口的指针
客户必须能够和服务器建立联系,借此可以收到服务器的通知。 IAdviseSink 接口可以完成这个任务。通过 QueryInterface() 方法可以得到这个接口的指针并把它赋给变量 pAdviseSink
m_pOPCIData-> QueryInterface(IID_IAdviseSink,(LPVOID*)&pAdviseSink);
第三步:建立连接
如果有关接口都存在,就可以建立连接。这可由 IDataObject 接口的 DAdvise() 方法完成,在这个方法中指向 IAdviseSink 接口的指针被传递给服务器。
r1=m_pOPCIData->m_pDataObject->DAdviseSink(&formatEtc,ADVF_PRIMEFIRST,pAdviseSink,
&m_dwConnection);
第四步:收到服务器的通知
如果数据发生变化,服务程序将调用 IAdviseSink 接口的 OnDataChange() 方法。这个方法是在客户应用程序中执行的。 OPC 项的实际数据被赋值给用户定义的成员变量 m_ItemValues, 这就意味着在客户应用程序中可以获得这些想要的数据。
r2=VariantChangeType(&(g_pOPCServer->m_ItemValues[hItClient]),&Value,0,VT_BSTR);
第五步:显示读出的数据
在这里, OnDataChange() 方法发送 Windows 消息 WM_DATA_CHANGE 启动下一步的处理。
SendMessage(*m_pWnd,WM_DATA_CHANGE,0,0);
通过在 OPC 客户应用程序的显示程序中定义消息映射,如果收到上述消息,则调用 OnDataChange() 事件过程。
ON_MESSAGE(WM_DATA_CHANGE,OnDataChange);
这个事件过程很简单,它只是调用用户自定义的 ItemsView() 函数在 OPC 客户应用程序的显示界面上显示实际的数据。
ItemView(g_pOPCServer->m_pItAttr,g_pOPCServer->m_ItemValues,4);
4 结束语
OPC 规范把硬件供应商和应用软件开发者分离开来,使得双方的工作效率都有了很大提高。软件开发商无需了解硬件的实质和操作过程,只要遵循 OPC 规范进行开发,就能够访问 OPC 服务器中的数据。 OPC 十分适应过程控制的需要,开发商可用 C++ 等高级语言编写软件程序,大大简化了过去从设备传输数据的复杂过程。本文介绍的在 Visual C++ 环境下开发使用定制接口访问数据的 OPC 客户程序,能够发挥 OPC 服务器的最佳性能,完全可以满足过程控制领域对数据的实时、高效的要求。
参考文献:
[1] OPC Data Access Specification 1.0A[S].OPC Fundation 1997.
[2] OPC Overview 1.0[S]. OPC Fundation
1998.
[3] OPC Common Definations and Interfaces 1.0[S]. OPC Fundation
1998.
[4] Dale Rogerson,
杨秀章 江英译 .COM 技术内幕 [M]. 北京:清华大学出版社, 1999.
[5]
潘爱民 . COM 原理与应用 [M]. 北京:清华大学出版社, 1999.
[6] Michael J. Young .
邱仲潘等译 .Visual C++6 从入门到精通 [M]. 北京:电子工业出版社 ,1999.
[7] Al Chisholm. A Technical Overview of the OPC DadaAccess Interface[J]. Intellution Inc.1999.
[8]
马国华 . 监控组态软件及其应用 [M]. 北京:清华大学出版社 , 2001.
作者简介: 石林锁( 1959 -),男,硕士,教授,主要从事自动控制、自动检测方面的教学和研究;王涛( 1977 -),男,硕士,研究生,主攻计算机应用;刘顺波( 1963 -),男,博士后,副教授,主要从事制冷空调装置自动化方面的教学和研究。
通讯地址: 西安市第二炮兵工程学院 502          邮编 710025
                                
涛(收)
电话: 029 3344102
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值