1 引言
VC(Visual C++)是功能強大的一種Windows應用程序可視化軟件開發(fā)工具,。VC支持面向對象的設計方法,,并可以使用功能強大的微軟基礎類庫MFC(Micro - soft foundation class)。并且由于Microsoft公司在操作市場上的壟斷地位,,用VC開發(fā)出來的軟件穩(wěn)定性好,、可移植性強,而且軟件與硬件相互獨立[1],,可以用來開發(fā)控制系統(tǒng)的上層管理系統(tǒng),。RSView32是作為一種專門用于工業(yè)控制的組態(tài)軟件,不僅包含了大量圖形開發(fā)工具和現(xiàn)成圖形庫,,使用戶能夠方便的進行系統(tǒng)開發(fā),,而且還可以對報警、活動記錄,、事件,、歷史趨勢等進行組態(tài),是一個功能強大的工業(yè)自動化產品[2],,因此可以很方便地對下層設備進行組態(tài),。在實際系統(tǒng)開發(fā)時,利用OPC技術把兩種工具有效的結合起來,,使上層的VC程序通過RSView32間接地與下層PLC進行數(shù)據(jù)通信,,以獲取令人滿意的結果。
2 OPC介紹
OPC(OLE for Process Control)是根據(jù)Microsoft的OLE(現(xiàn)在Active),、COM(部件對象模型)和DCOM(分布式部件對象模型)技術所要求的功能制定的一個開放和互用式的用戶界面標準,,它保證了自動化/控制應用程序和區(qū)域系統(tǒng)/設備之間的互用。它以OLE/COM機制作為應用程序級的通訊標準,,采用 CLIENT/SERVER模式,,典型的OPC體系結構如圖1所示:
圖1 典型的OPC體系結構
OPC規(guī)范中提供了兩套接口方案,即定制接口和自動化接口,。定制接口效率高,,通過該接口能夠發(fā)揮OPC服務器的最佳性能,,采用C++語言的客戶一般采用定制接口方案;自動化接口使解釋性語言和宏語言訪問OPC服務器成為可能,采用VB等語言的客戶一般采用自動化接口,。
OPC 數(shù)據(jù)存取服務器由三類對象組成:服務器(Server),、組(Group)、數(shù)據(jù)項(Item),。服務器對象用于指出特定的OPC服務器應用程序名,,并作為組對象的容器;組對象存儲由若干Item組成的Group信息并邏輯組織數(shù)據(jù)項;數(shù)據(jù)項對象()存儲具體的Item的定義、數(shù)據(jù)值,、狀態(tài)值等信息,,一個 Item就代表一個具體的過程變量。OPC客戶應用程序要獲取OPC服務器的數(shù)據(jù),,必須事先指定服務器應用程序所在的計算機名(服務器應用程序和客戶應用程序不在同一臺PC上),、OPC數(shù)據(jù)訪問服務器名和該服務器提供的OPC項的定義。
建立OPC連接后,,客戶應用程序一般可以通過三種方式從OPC 服務器讀取數(shù)據(jù):使用同步接口IOPC- SyncIO,,簡單有效,適合于只讀取少量數(shù)據(jù)的客戶程序;使用接口IOPCCallback的“訂閱”的功能OnChange,,每當數(shù)據(jù)有變化時,,服務器自動通知客戶;使用異步接口IOPCASyncIO2,可以直接與物理設備通訊,,速度慢但數(shù)據(jù)精確度高,。
3 RSView32作為OPC服務器
西門子專門用于工業(yè)控制的通用組態(tài)軟件之一RSView32支持OPC技術,它可以用作一個OPC客戶和外部OPC服務器軟件通信,,也可以作為一個OPC服務器和其它第三方支持OPC技術的軟件進行連接,。本文中RSView32作為服務器,VC應用程序作為客戶端,,采用C/S模式實現(xiàn)兩者之間的數(shù)據(jù)交換,。
3.1 使RSView32作為OPC服務器[4]
用下列方法之一使RSView32作為OPC服務器:
(1) 選擇“啟動”編輯器里“啟動”頁上的“OPC/DDE服務器”復選框;
(2) 發(fā)出RTDataServerOn命令(從命令行或另一個 RSView32組件里,使用RTDataServerOff命令可以取消此功能),,這將允許其它應用程序讀取數(shù)值但不能改變它;
(3) 發(fā)出RTDataWriteEnable命令(從命令行或另一個RSView32組件里,,使用RTDataWriteDisable命令可以取消此功能),這允許從外部OPC應用程序寫入,,以改變RSView32的標記值,。
3.2 建立 OPC 客戶項目[4]
VC應用程序要從RSView32取得數(shù)據(jù),必須使用下列信息:
服務器:RSI.RSView32OPCTagServer;
類型:本機/遠程;
服務器計算機名或地址:如果客戶和服務器在同一計算機上,,這項可以是空白,。
訪問路徑:項目名;
更新速率:一個以秒為單位的速率;
條目:標記名??梢酝ㄟ^查看RSView32的標簽數(shù)據(jù)庫獲得,。
4 VC應用程序作為OPC客戶端的程序實現(xiàn)
在VC環(huán)境中使用定制接口開發(fā)OPC客戶應用程序,,下面是程序實現(xiàn)的關鍵步驟。
4.1 包含OPC頭文件
開發(fā)OPC客戶應用程序,,除了需要OPC接口外,,還需要在程序中包含OPC標準庫文件,可以從OPC基金會網站(網址:www.opcfoundation.org)下載這些文件:
#include "opcda_i.c" OPC數(shù)據(jù)存取接口
#include "opcda.h" OPC數(shù)據(jù)存取2.0頭文件
#include "opccomn_i.c" OPC公共接口定義
#include "opccomn.h" OPC公共頭文件
4.2 初始化COM支持庫
由于OPC是基于COM技術制定,,所以在使用接口類之前必須首先使用CoInitialize(NULL)函數(shù)初始化COM庫,,如果成功,,函數(shù)返回值等于S_ OK,。
4.3 連接opc服務器
OPC 客戶能夠連接到OPC服務器上,并建立OPC組和OPC數(shù)據(jù)項,,這是OPC數(shù)據(jù)訪問的基礎,,如果沒有這個機制,數(shù)據(jù)訪問的其它機能不可能實現(xiàn)[4],。連接 OPC服務器,,OPC客戶需要事先指定計算機名(如果OPC服務器和OPC客戶不在同一臺計算機上)和OPC數(shù)據(jù)訪問服務器名 (RSI.RSView32OPCTagServer)。實現(xiàn)代碼如下:
ConnectToServer(/*in */LPOLESTR ProgID,/*in*/ BOOL IsRemote,/*out */ IUnknown **ppUnknown)
{
CLSID OPCCLSID;
HRESULT hRet=CLSIDFromProgID(ProgID,&OPCCLSID);
//將字符串ProgID轉換為唯一OPCCLSID
if(IsRemote)
//opc服務器和opc客戶不在同一臺計算機上
{
COSERVERINFO ServerInfo;
memset(&ServerInfo,0,sizeof(ServerInfo));
ServerInfo.pwszName=T2OLE("ServerComouter");
MULTI_QI qi[1];
memset(qi, 0, sizeof(qi));
qi[0].pIID=&IID_IUnknown;
HRESULT hRet=CoCreateInstanceEx(OPCCLSID,NULL,CLSCTX_REMOTE_SERVER,
&ServerInfo,1,qi);
*ppUnknown=qi[0].pItf;
}
else
//opc服務器和opc客戶在同一臺計算機上
{
hRet=CoCreateInstance(OPCCLSID,NULL,CLSCTX_LOCAL_SERVER,IID_IUnknown,
(void **)ppUnknown);
}
}
4.4 創(chuàng)建OPC組
IOPCServer接口的AddGroup()方法可以創(chuàng)建一個有指定名稱和屬性的OPC組,。在調用該方法之前,,可以使用上一步得到的Iunknown接口指針,通過QueryInterface()方法請求IOPCServer接口指針,。代碼如下:
ppUnknown->QueryInterface(IID_IOPCServer,(void **)&pServer);
//得到IOPCServer接口指針
pServer->AddGroup(L"",TRUE,500,1235,&lTimeBias,&fTemp,0,&hOPCServerGroup, &dwActualRate,IID_IOPCItemMgt,& pOPCItemMgt);
4.5 添加數(shù)據(jù)項
IOPCItemMgt接口的AddItem()方法可以添加具有特殊屬性的指定數(shù)量的數(shù)據(jù)項,。
pOPCItemMgt->AddItems(ItemNumber,ItemArray,
(OPCITEMRESULT**)&pItemResult,(HRESULT **)&pErrors);
ItemArray 為OPCITEMDEF類型結構數(shù)組,,它包含數(shù)據(jù)項的詳細信息,,客戶需要知道要進行交換的數(shù)據(jù)在RSView32標簽數(shù)據(jù)庫中的名稱、數(shù)據(jù)類型及作為 OPC服務器的RSView32項目名稱,。添加數(shù)據(jù)項之前,,要用這些數(shù)據(jù)項信息對ItemArray結構數(shù)組進行初始化。
4.6 數(shù)據(jù)交換
成功地增加完所需要的數(shù)據(jù)項后,,OPC客戶(VC應用程序)和OPC服務器(RSView32)就可以進行數(shù)據(jù)交換了,。在數(shù)據(jù)量不大的情況下,可以使用 IOPCSyncIO同步接口的Write()和Read()兩個方法進行數(shù)據(jù)的讀寫操作,,從而實現(xiàn)OPC客戶(VC應用程序)和OPC服務器 (RSView32)之間的數(shù)據(jù)交換,。代碼如下:
ppUnknown->QueryInterface(IID_IOPCSyncIO,(void **)&pOPCSync);
//得到IOPCSyncIO接口指針
pOPCSync->Read(OPC_DS_CACHE,ReadNumber,hServerRead,&pItemValue,&pErrors);
//讀ReadNumber個數(shù)據(jù)
pOPCSync->Write(WriteNumber,hServerWrite,WriteValue,&pErrors);
//寫WriteNumber個數(shù)據(jù)
4.7 釋放接口指針
在VC應用程序停止運行之前必須使用Release()方法刪除已創(chuàng)建的OPC對象并釋放內存。
5 結束語
OPC技術規(guī)范把硬件供應商和應用軟件開發(fā)者分離開來,,使得雙方的工作效率都有了很大提高,。軟件開發(fā)商無需了解硬件的實質和操作過程,就能訪問OPC數(shù)據(jù)服務器中的數(shù)據(jù),,尤其是開發(fā)商在已使用了組態(tài)軟件進行實時監(jiān)控的過程控制系統(tǒng)基礎上,,用C++等高級語言開發(fā)系統(tǒng)時,,大大簡化了過去從設備傳輸數(shù)據(jù)的復雜過程。在某鋁廠的自動配料系統(tǒng)開發(fā)中,,應用OPC技術方便地實現(xiàn)了VC應用程序和RSView32的數(shù)據(jù)交換,,間接地實現(xiàn)了VC應用程序與PLC的通信,獲得了很好的結果,。