用VB編寫OPC客戶端訪問WINCC (轉)

worldblog發表於2007-12-14
用VB編寫OPC客戶端訪問WINCC (轉)[@more@] 

用VB編寫OPC客戶端訪問WINCC

  :namespace prefix = v ns = "urn:schemas--com:vml" />Office:office" />ectratio="t">
  OPC是一個工業標準,它是由一些世界上著名的自動化和、公司和Microsoft()緊密合作而建立的。〔O代表OLE(連結和嵌入),P (process過程),C (control控制)。OLE已從物件導向重新定義為基於物件並更名為Active X〕。

WinCC是西門子公司在自動化領域採用最先進的技術與微軟公司在共同開發的居於世界領先地位的工控軟體。WinCC即 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的標籤陣列與值數,注意,值陣列一定要設為Variant。

'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 WriteItemx > 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 showSuccess(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), "RECDELIMITER")

  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.Dinnect

  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線上幫助》

   

作者簡介:

顧愷,高階程式設計師,湖南大學畢業,曾從事過的核心研究,從事過企業資訊化平臺的開發,當前從事SCADA的開發,主要將各種不同型別的裝置透過同一手段進行資料採集,並整合到企業資訊化平臺中去。喜歡將工作中的一些積累形成文字。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993098/,如需轉載,請註明出處,否則將追究法律責任。

相關文章