用VB編寫OPC客戶端訪問WINCC
發表于:2007-07-14來源:作者:點擊數:
標簽:
OPC是一個工業標準,它是由一些世界上著名的自動化系統和硬件、軟件公司和Microsoft(微軟)緊密合作而建立的?!睴代表OLE(對象鏈接和嵌入),P (process過程),C (control控制)。OLE已從 面向對象 重新定義為基于對象并更名為Active X〕。 Win CC 是西門子公司
OPC是一個工業標準,它是由一些世界上著名的自動化系統和硬件、軟件公司和Microsoft(微軟)緊密合作而建立的?!睴代表OLE(對象鏈接和嵌入),P (process過程),C (control控制)。OLE已從
面向對象重新定義為基于對象并更名為Active X〕。
Win
CC是西門子公司在自動化領域采用最先進的技術與微軟公司在共同
開發的居于世界領先地位的工控軟件。WinCC即
WINDOWS CONTROL CENTER(視窗控制中心)。WinCC是一個功能強大的全面開放的監控系統,既可以用來完成小規模的簡單的過程監控應用,也可以用來完成復雜的應用。在任何情況下WinCC都可以生成漂亮而便捷的人機對話接口,使操作員能夠清晰地管理和優化生產過程。它集成的OPC(OLE for process control)
服務器使得過程數據可由其它應用程序(OPC客戶機)訪問。
WinCC在安裝時提供了OPC的客戶端控件: Siemens OPC DAAutomation 2.0( SOPCDAAuto.dll),這個控件就是我們在
VB中要用到的控件,我們也可以使用通用的OPC客戶端控件: OPC Automation 2.0.
在WINCC的幫助中,有Siemens OPC DAAutomation 2.0使用的簡略幫助,但說得不很詳細,我在使用中碰到不少問題,現一并寫出來,與大家共享。
一、OPC的連接
先在“引用”將近 Siemens OPC DAAutomation 2.0加入,然后開始定義全局變量。在本程序中,我使用了兩個OPC組進行OPC訪問,所以定義了全局變量。我們要首先定義OPC服務類型與計算機結點名。定義OPC組與OPC標簽組。并定義OPC的標簽數組與值數,注意,值數組一定要設為Vari
ant。
'OPC處理:只對WINCC
Const ServerName = "OPCServer.WinCC" ‘OPC的類型
Const NodeName = "GUK" ‘結點名,即計算機名
‘Dim NodeName As String
Dim WithEvents MyOPCServer As OPCServer ‘OPC服務
Dim MyOPCGroupColl As OPCGroups ‘
Dim WithEvents MyOPCGroupOut As OPCGroup ‘OPC組,本程序用兩個組進行OPC連接
Dim WithEvents MyOPCGroupIn As OPCGroup
Dim MyOPCItemCollIn As OPCItems ‘OPC標簽組
Dim MyOPCItemCollOut As OPCItems
Dim ServerHandlesIn() As Long ‘句柄
Dim ServerHandlesOut() As Long
Dim ErrorsIn() As Long ‘錯誤句柄
Dim ErrorsOut() As Long
Dim WatchDataReadItem(100) As String '記錄OPC的標簽
Dim WatchDataReadValue(100) As Variant '存放OPC的值
Dim WatchDataWriteItem(100) As String '記錄OPC的標簽
Dim WatchDataWriteValue(100) As Variant '存放OPC的值
在定義所有變量后,我們就要進行OPC連接了,要進行OPC連接之前,先要配置要訪問的OPC標簽名,我們WatchDataReadItem、WatchDataWriteItem中加入相應的標簽名,注意:這兩個數組必須由1開始,不能由0開始。
配置好標簽后就要進行OPC連接了。如下面子程序:
1、 ClientHandles1先配置名柄索引,這將在讀取OPC標簽的值時可要用到
2、 生成OPC對象,
3、 進行OPC標簽連接
至此:OPC連接就成功了,我們可以對OPC進行讀與寫的操作了。
'---------------------------------------------------------------------
' Sub StartClient()
' 目的:連接至OPC_server,創建組和添加條目
'---------------------------------------------------------------------
Private Sub StartClient()
Dim ItemNum As Integer
Dim TarnscationID As Long
Dim CanceID As Long
Dim ClientHandles1(100) As Long
Dim ii As Integer
On Error GoTo HANDLEeRROR
For ii = 0 To 100
ClientHandles1(ii) = ii 先配置名柄索引,這將在讀取OPC標簽的值時可要用到
Next ii
TarnscationID = 1
‘ NodeName = xProfile.GetValue("SYSTEM", "NodeName")
‘生成OPC對象,
Set MyOPCServer = New OPCServer
MyOPCServer.Connect ServerName, NodeName
Set MyOPCGroupColl = MyOPCServer.OPCGroups
MyOPCGroupColl.DefaultGroupIsActive = True
Set MyOPCGroupIn = MyOPCGroupColl.Add("MYGROUPIN")
Set MyOPCGroupOut = MyOPCGroupColl.Add("MYGROUPOUT")
Set MyOPCItemCollIn = MyOPCGroupIn.OPCItems
Set MyOPCItemCollOut = MyOPCGroupOut.OPCItems
‘進行OPC標簽連接
If WriteItemIdex > 0 Then
MyOPCItemCollOut.AddItems WriteItemIdex, WatchDataWriteItem, ClientHandles1, ServerHandlesOut, ErrorsOut '初始化OCP連接
MyOPCGroupOut.IsSubscribed = True
End If
If ReadItemIdex > 0 Then
MyOPCItemCollIn.AddItems ReadItemIdex, WatchDataReadItem, ClientHandles1, ServerHandlesIn, ErrorsIn '初始化OCP連接
MyOPCGroupIn.IsSubscribed = True
End If
Exit Sub
HANDLEeRROR:
needOPCRestart = True
xLog1.log "OPCl連接發生錯誤"
End Sub
二、OPC的標簽讀寫
對OPC標簽的讀可以通過MyOPCGroupIn組與MyOPCGroupOut的DataChange事件來讀取。該事件有多個參數:其中NumItems是指標簽改變值的個數,ClientHandles是改變值的標簽索引,ItemValues為改變值的數據,具體的意思是ClientHandles(1)的值是其對應的標簽數組的索引,其所指的OPC標簽的值在ItemValues(1)中。一般來說,剛連接上時,該事件會把全部所要求訪問的OPC標簽值全部讀取過來(順序不一,要通過ClientHandles索引),此后只有數據發生變化時才會觸發該事件。也只會傳輸發生了變化的數據,沒有變化的數據不會出現在本事件的ItemValues中。
Private Sub MyOPCGroupOut_DataChange(ByVal TransactionID As Long, ByVal NumItems As Long, ClientHandles() As Long, ItemValues() As Variant, Qualities() As Long, TimeStamps() As Date)
'產生要通知下一級的數據變化,根椐不再的控件有不同的處理
For ii = 1 To NumItems
WatchDataWriteValue(ClientHandles(ii) - 1) = ItemValues(ii) '對改變的值讀入本數組
Next ii
End Sub
對OPC的寫可以有同步與異步之分,對于大量的數據傳輸,異步是更佳的選擇,但對少量的數據傳輸,同步表現得更好。
要進行數據傳輸,先要將值數據進行賦值,注意:值數據要由0開始,也就是說,值數組與標簽數據不是一、一對應,值要比標簽前一位,這一點,在WINCC說明中沒有,但在我的實際的使用中一直要這樣,不然數據就產生錯位,看下面程序。
這是一個拔號完畢后返回的數據進行OPC傳遞的程序。包含解包過程,
Private Sub showSu
clearcase/" target="_blank" >ccess(msg As String)
Dim location As String
Dim nowTime As String
Dim logStr As String
Dim Value() As String
Dim ii, temp As Integer
Dim isPack As Boolean
Dim sHead, sDelimited, sTail As String
location = xProfile.GetValue(WatchPoint(nowRunID), "LOCATION")
nowTime = Now
logStr = "拔" & location & "取數成功" & msg
xLog1.log logStr
logStr = " " & msg
xLog2.log logStr '記錄數據
'數據上傳
'如果有包結構,則顯示包結構,
isPack = xProfile.GetValue(WatchPoint(nowRunID), "ISRECHEAD")
If WatchPointRBegin(nowRunID) < 0 Then Exit Sub
If isPack Then
sHead = xProfile.GetValue(WatchPoint(nowRunID), "RECHEAD")
sDelimited = xProfile.GetValue(WatchPoint(nowRunID), "RECDELI
MITER")
sTail = xProfile.GetValue(WatchPoint(nowRunID), "RECEND")
Value = Split(msg, sDelimited)
For ii = 0 To UBound(Value) - 1
temp = WatchPointRBegin(nowRunID) + ii
If temp > WatchPointREnd(nowRunID) Then Exit For
WatchDataReadValue(temp - 1) = Value(ii + 1) 'VALUE要從0開始,比ITEM少1,所以減一。 有包頭,占去一位,向后延一
Next ii
Else
WatchDataReadValue(WatchPointREnd(nowRunID) - 1) = msg
End If
MyOPCGroupIn.SyncWrite ReadItemIdex, ServerHandlesIn, WatchDataReadValue, ErrorsIn '數據上傳
'記錄上次成功執行的時間
xProfile.SetValue WatchPoint(nowRunID), "LASTTIME", nowTime
End Sub
三、OPC連接斷開。
OPC客戶端連接后要占用服務器資源,所以如果不需要使用OPC時,必須進行OPC連接斷開。
斷開的程序相當簡單,釋放資源即可。如下,
Sub StopClient()
On Error Resume Next
'----------- 釋放組和服務器對象
MyOPCGroupColl.RemoveAll
'----------- 與服務器斷開連接并且清除
MyOPCServer.Disconnect
Set MyOPCItemCollIn = Nothing
Set MyOPCItemCollOut = Nothing
Set MyOPCGroupIn = Nothing
Set MyOPCGroupOut = Nothing
Set MyOPCGroupColl = Nothing
Set MyOPCServer = Nothing
End Sub
但在實際的使用中發現,頻繁的連接與斷開,將使服務器的資源被大量的消耗,最終讓服務器出錯。所以盡量減少無謂的OPC連接與斷開。
結語:
OPC的使用是作為一個DCOM在使用,所以OPC客戶端可以
網絡上任一計算機運行,但你必須配置DCOM的訪問權限,如果你不想費神,把服務器與客戶端都用相同的用戶名與密碼登錄就成了。如果想配置DCOM,請參看DCOM的配置。
參考資料:
《WinCC在線幫助》
作者簡介:
顧愷,高級
程序員,湖南大學畢業,曾從事過
LINUX的內核研究,從事過企業信息化平臺的開發,當前從事SCADA的開發,主要將各種不同類型的遠程設備通過同一手段進行數據采集,并集成到企業信息化平臺中去。喜歡將工作中的一些積累形成文字。
原文轉自:http://www.anti-gravitydesign.com