用VB編寫OPC客戶端訪問WINCC (轉)
用VB編寫OPC客戶端訪問WINCC
:namespace prefix = v ns = "urn:schemas--com:vml" />
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OPC客戶端開發過程整理客戶端
- grpc套路客戶端編寫RPC客戶端
- 編寫Enterprise bean的客戶端(下) (轉)Bean客戶端
- 遠端客戶端 訪問 ASM 例項客戶端ASM
- 用VB編寫COM+應用時碰到問題? (轉)
- Swift編寫自己的API客戶端SwiftAPI客戶端
- 用VB編寫抽獎程式 (轉)
- 客戶端訪問POP3--SMTP客戶端
- 用VB編寫標準CGI程式 (轉)
- Docker部署mysql並提供客戶端訪問DockerMySql客戶端
- 客戶端 post ,get 訪問伺服器客戶端伺服器
- OPC客戶端開發工具WTopcclient補充說明客戶端client
- 無線1x客戶端編寫概要客戶端
- 限制訪問Oracle客戶端IP方法總結Oracle客戶端
- 測試平臺系列(90) 編寫oss客戶端客戶端
- 用VB編寫網路尋呼機(1) (轉)
- 用VB編寫網路尋呼機(2) (轉)
- 編寫 Netty / RPC 客戶端【框架程式碼分析】NettyRPC客戶端框架
- 手把手教你編寫入門級redis客戶端Redis客戶端
- FastDFS-nginx外掛作為FastDFS客戶端訪問ASTNginx客戶端
- EVE-NG初次啟動及WEB客戶端訪問Web客戶端
- ExchangeServer2010客戶端的安全訪問Server客戶端
- 用VB編寫一個彈出選單類 (轉)
- 如何編寫一個前端框架之七-客戶端路由(譯)前端框架客戶端路由
- python 編寫遊戲測試機器人客戶端 (一)Python遊戲機器人客戶端
- python 編寫遊戲測試機器人客戶端 (二)Python遊戲機器人客戶端
- python 編寫遊戲測試機器人客戶端 (三)Python遊戲機器人客戶端
- Zookeeper C客戶端庫編譯客戶端編譯
- Nginx基於客戶端請求頭的訪問分類Nginx客戶端
- 客戶端(windows)訪問FTP伺服器遇到的問題(總結)客戶端WindowsFTP伺服器
- JAVA FTP客戶端問題JavaFTP客戶端
- cvs客戶端大全(轉)客戶端
- frp內網穿透,客戶端能訪問,服務端訪問報錯404,有兄弟遇到過嗎FRP內網穿透客戶端服務端
- 關於如何編寫好金融科技客戶端SDK的思考客戶端
- VB也能訪問記憶體 (轉)記憶體
- !請教:java NIO編寫服務端,C++編寫客戶端,二者採用自定義資料包資料通訊Java服務端C++客戶端
- 用VB編寫非同步多執行緒下載程式 (轉)非同步執行緒
- C#版Nebula客戶端編譯C#客戶端編譯