【技术前沿】基于VC++6.0的OPC 客户端开发方法
驱动部 苏加庆
1 引言
通信技术、计算机技术和自动化技术的的快速发展促进了企业信息化的建设,使得信息共享在综合自动化系统中变得越来越重要。在企业自动化系统中不同的系统层次之间、同一个层次的不同设备或子系统之间都需要信息的共享。在传统的控制系统中,现场设备之间的通信要通过特定的驱动程序实现,如果存在不同厂家的设备驱动程序也将不适用而需要重新开发,这样不但增加了系统集成的成本而且在系统实现时带来一定的限制,并且也不利于系统的二次改造。然而使用OPC则使得信息共享变得相当容易,OPC定义了统一的、开放的接口及其相关实现的标准,不同厂家只要遵守这个统一的标准就可以进行通信。OPC相关的内容很多,本文重点阐述如何开发OPC客户端进行浅显。
2 OPC技术简介
OPC的全称是OLE for Process Control,主要用于工业控制,是基于微软公司的DNA构架和COM/DCOM技术而设计的。OPC规范定义了一个标准接口,这个标准使得COM技术适用于过程控制和制造自动化等应用领域。OLE最初意思为对象链接与嵌入,是微软的复合文档技术。随着后续版本OLE2中导入了COM技术之后,现在的OLE在原版的基础上增加更多新的功能,包括结构化存储、统一数据传输和自动化等,它已经成为独立于编程语言、操作系统甚至硬件平台的一种规范,OPC建立在OLE2规范之上,为工业控制领域提供了一种标准的数据访问机制。
OPC包括3种规范:OPC数据访问规范(OPC DA)、OPC报警和事件规范(OPC AE)和OPC历史数据访问规范(OPC HDA)等。其中OPC数据访问规范是最为常用,本文仅针对OPC DA 进行讨论。由于OPC基于COM技术的面向对象思想,它包含3类对象:OPC Server、OPC Group和OPC Item。OPC服务器对象维护有关服务器的信息并作为OPC组对象的包容器,能够动态地创建和释放组对象;OPC组对象除了维护有关自身的信息之外,还提供包容OPC项的机制,从逻辑上管理OPC项。它提供客户组织数据的一种方法,客户可以对其进行读写,还可以设置客户端的数据更新速率等,所有这些功能都定义在访问OPC对象的标准接口中。
3 OPC数据访问方式
OPC客户端在对OPC服务器进行数据访问时,可以选择两种不同的访问方式,即同步访问和异步访问。同步访问的方式实现相对简单,在客户端应用程序提出数据访问请求时,OPC服务器根据请求中的参数将相应的数据返回给OPC客户端应用程序,这期间,OPC客户端应用程序一直处于等待状态,这种方式明显比较耗时,适用于客户端数目较少并且与服务器交互的数据较少的情况。相比之下,异步访问方式的实现较为复杂,OPC服务器接到OPC应用程序的要求后,立即给与返回,但并不是同时返回数据,这也是称为异步通信的缘由,OPC客户端应用程序也不用一直等到数据返回,而可以继续处理其他的问题,当OPC服务器完成数据访问时,触发OPC应用程序的异步访问完成事件并将数据访问结果传送给OPC客户端应用程序。这种方式使在有大量OPC客户端应用程序和交互数据量较大时通信的效率更高,能够避免客户数据请求的阻塞,进而最大限度地节省计算机和网络资源。
4 OPC客户端程序设计
在OPC客户端应用程序设计时需要遵守OPC数据访问规范实现所规定的必需接口,并且客户端模块需要有独立的设备连接界面和监控运行界面,并能够支持多服务器的连接,这样的客户端才更加通用。下面详细介绍VC环境下的OPC客户端应用程序开发步骤:
中国论文联盟http://www.lwlm.com
(1)包含OPC头文件。首先创建新的工程,编辑StdAfx.h文件,加载opcda.h、opccomn.h、opcerrors.h、opcprops.h、opcquality.h以及opcda_i.c、opccomn_i.c文件。
(2)初始化COM库。由于OPC是基于COM技术制定的,所以在使用接口类之前必须首先使用CoInitialize(NULL)函数对COM库进行初始化,如果成功,函数返回值等于S_ OK。
HRESULT hr;
Hr=CoInitialize(NULL);
if(hr!=S_OK)
return(FALSE);
(3)通过OPC服务器的ProgID查询注册表中相关CLSID。每个COM服务器都有一个字符串型的ProgID,通过ProgID可以得到全球惟一的CLSID,使用CLSIDFromProgID( )函数实现ProgID到CLSID的转换。
Hr=CLSIDFromProgID(ProgID,&CLSID);
(4)连接OPC服务器,查询对象的IID_IOPCServer接口。在连接OPC服务器前,OPC客户端需要事先指定计算机名和OPC数据访问服务器名,建立连接后,创建OPC组并添加OPC数据项。
hr=CoCreateInstance(clsid,NULL,CLSCTX_ LOCAL_ SERVER,IID_IOPCServer,(void**)&m_OPCServer);
(5)创建OPC组,查询IOPCItemMgt接口。IOPCServer接口的AddGroup() 方法可以创建一个有指定名称和属性的OPC组。
hr=m_IOPCServer->AddGroup(L,” ”,TRUE,800,111,&TimeBias,&PercentDeadBand,LOCAL_ID,& m_ GrpSrvHandle,&RevisedUpdateRate,IID_IOPCItemMgt, (LPUNKNOWN*)m_IOPCItemMgt);
(6)添加OPC数据项。使用IOPCItemMgt接口的AddItem()方法可以添加具有特殊属性的指定数量的数据项。
pOPCItemMgt->AddItems(ItemNumber,ItemArray,(OPCITEMRESULT**)&pItemResult,(HRESULT **) & pErrors);
(7)OPC的数据项读写。对OPC数据项的读写可以有同步与异步之分,对于大量的数据传输,异步是更佳的选择,但对少量的数据传输,同步表现得更好。本程序采用异步访问方式,需要指向IOPCAsyncIO2指针。
hr=m_IOPCItemMgt->QueryInterface(IID_IOPCAsyncIO2,(void**)&m_IOPCAsyncIO2);
void CAsynOPCDlg::OnRead ( ) 实现异步读数据。
hr=m_IOPCAsyncIO2->Read(1,phServer,1,&dwCancelID,&pErrors);
delete[] phServer;
void CAsynOPCDlg::OnWrite( ) 实现异步写数据。
hr=m_IOPCAsyncIO2->Write(1,phServer,values,2,&dwCancelID,&pErrors);
delete[] phServer;
(8)OPC连接断开,释放接口指针。当程序退出或停止服务器时,依次删除Item(RemoveItems)、Group(RemoveGroups),释放资源。
void CAsynOPCDlg::OnStop( ) 停止服务器。
hr=m_IOPCItemMgt->RemoveItems(1,phServer,&pErrors);删除Items。
hr=m_IOPCServer->RemoveGroup(m_GrpSrvHandle,TRUE);删除Group。
m_IOPCServer->Release( );释放服务器。
m_IOPCServer=NULL;
CoUninitialize( );关闭COM库。
通过以上方法就可以对已经存在的OPC DA服务器进行数据存取,根据具体情况设计所需要的可视化界面即可,这里则不必多说明。
5 结语
当今,OPC技术在工控领域的应用越来越加广泛,很多厂家都提供相应的OPC服务器,掌握OPC客户端应用程序的开发具有非常实用的意义。