当前位置:文档之家› OPC客户端编程汇编

OPC客户端编程汇编

OPC编程汇编OPC客户端的自动化实现OPC是建立在COM,DCOM的基础商的,因此绝大多数语言都可以很好的进行开发。

在Net中开发客户端有以下几种方式:(1)使用OPCNetAPI,需要用到OPCNetAPI.dll,.dll(2)使用自动化接口,需要用到OPCDAAuto.dll(3)使用自定义接口,需要用到多个Wrapper:OpcRcw.Ae.dll,OpcRcw.Batch.dll,n.dll,OpcRcw.Da.dll,OpcRcw.Dx.dll,OpcRcw.Hda.dll,OpcRcw.Sec.dll以上开发方式所需的动态链接库可以从OPC基金会(/)的网站上下载,一些下载项目可能需要注册,或成为基金会的成员。

不同的方式有各自的有缺点,请参见…本文使用自动化接口,语言进行开发,开发项目是无线射频(RFID)卡方面的应用,典型的如公交车,或公司考勤使用的刷卡机。

需要注意的是自动化接口存在一个“不是问题”的问题,数组下标是以1开始的,而不是传统计算机开发上的以0开始。

不知道设计者头脑是怎么想(有人知道吗?);这可能会给一些语言的开发造成问题(有人碰到吗,没有你就是幸运的)需求:OPCDAAuto.dll或该Dll的Interop(一):客户端开发流程OPC客户端的开发主要遵循下图所示的开发流程,下面就从以下几个开发步骤进行说明(二):枚举OPC服务器列表枚举服务器主要是通过OPCServer接口的GetOPCServers方法来实现的,该方法会返回OPC服务器数组(以1为下界,上面已有说明),以下是代码段Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Loa dTryGlobalOPCServer = New OPCAutomation.OPCServerClass()Dim ServerList As Object= GlobalOPCServer.GetOPCServersFor index As Short= LBound(ServerList) To UBound(ServerList) '加入控件列表中,注意这里使用LBound和UBoundcbbServerList.Items.Add(ServerList(index))NextIf cbbServerList.Items.Count > 0 ThencbbServerList.SelectedIndex = 0End IfResetControlStatus() '设置控件状态GlobalOPCServer = NothingCatch Ex As ExceptionMessageBox.Show("List OPC servers failed: "+ Ex.Message, "OPCSample", MessageBoxButtons.OK) End TryEnd Sub(三):连接OPC服务器自动化接口中连接到服务器是使用connect方法Public Overridable Sub Connect(ByVal ProgID As String, Optional ByVal Node As Object = Nothing)ProgID指服务器的ProgID,Node代表网络节点,如果是本机则放空即可。

连接到服务器后,以下属性需要特别注意:OPCServer.StartTime:服务器的启动时间OPCServer.CurrentTime:服务器的当前时间,各个客户端可以通过这个属性值完成一些同步的操作OPCGroups.DefaultGroupIsActive:以后添加的Group是否默认激活OPCGroups.DefaultGroupDeadBand:Group的默认死区,变化量超过死区后将会触发DataChange事件,合理的设置该值可以提高程序性能OPCGroups.Count:下属组(Group)的数量OPCGroups.DefaultGroupLocalID:组(Group)的默认通信区域编号,如1024OPCGroups.DefaultGroupUpdateRate:组(Group)的默认刷新率,该属性也比较重要OPCGroups.DefaultGroupTimeBias:组(Group)的默认时间偏差(四):添加组(Group)和项(Item)添加组和项需要用到Groups.Add和Items.AddItem方法,以下是原型:Function Add(Optional ByVal Name As Object = Nothing) As OPCAutomation.OPCGroupFunction AddItem(ByVal ItemID As String, ByVal ClientHandle As Integer) As OPCAutomation.OPCItem组也有两个重要的属性Group.UpdateRate:刷新率,该属性通Groups的UpdateRate意义一样,如果这个值有设置,则以这个值为准Group.IsSubscribed:是否使用订阅功能以下是代码段'连接到指定的OPC服务器Private Sub btnConnectServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnectServer.ClickIf cbbServerList.Text <> ""ThenConnectedOPCServer = New OPCAutomation.OPCServerClass()TryConnectedOPCServer.Connect(cbbServerList.Text)ConnectedOPCServer.OPCGroups.DefaultGroupDeadband = 0'添加组ConnectedGroup = ConnectedOPCServer.OPCGroups.Add()ConnectedGroup.UpdateRate = 3 * 1000 '刷新虑,用于下面的DataChange事件ConnectedGroup.IsSubscribed = True'使用订阅功能'添加项GlobalOPCItems(0) = ConnectedGroup.OPCItems.AddItem("Reader_Device.OpenCard", 0)GlobalOPCItems(1) = ConnectedGroup.OPCItems.AddItem("Reader_Device.CloseCard", 1)GlobalOPCItems(2) = ConnectedGroup.OPCItems.AddItem("Reader_Device.CardNO", 2)RefreshServerStatus() '刷新服务器状态Catch ex As ExceptionConnectedOPCServer = NothingMessageBox.Show("OPC server connect failed : "+ ex.Message, "OPCSample", MessageBoxButtons.OK)End TryResetControlStatus()End IfEnd Sub(五):读写操作与事件控制读写操作包括同步和异步两种操作方式,以下是这几个方法的原型:Group的同步读事件Sub SyncRead(ByVal Source As Short, ByVal NumItems As Integer, ByRef ServerHandles As System.Array, ByRef Values As System.Array, ByRef Errors As System.Array, Optional ByRef Qualities As Object = Nothing, OptionalByRef TimeStamps As Object = Nothing)Group的同步写事件Sub SyncWrite(ByVal NumItems As Integer, ByRef ServerHandles As System.Array, ByRef Values As System.Array, ByRef Er rors As System.Array)Group的异步读事件Sub AsyncRead(ByVal NumItems As Integer, ByRef ServerHandles As System.Array, ByRef Errors As System.Array, ByVal Tr ansactionID As Integer, ByRef CancelID As Integer)Group的异步写事件Sub AsyncWrite(ByVal NumItems As Integer, ByRef ServerHandles As System.Array, ByRef Values As System.Array, ByRef Errors As System.Array, ByVal TransactionID As Integer, ByRef CancelID As Integer)如果使用异步的读写操作,那么还需要实现Group中的ReadComplete和WriteComplete两个事件PublicEvent AsyncReadComplete(ByVal TransactionID As Integer, ByVal NumItems As Integer, ByRef ClientHandles As System.Ar ray, ByRef ItemValues As System.Array, ByRef Qualities As System.Array, ByRef TimeStamps As System.Array, ByRef Errors As System.Array)PublicEvent AsyncWriteComplete(ByVal TransactionID As Integer, ByVal NumItems As Integer, ByRef ClientHandles As System.A rray, ByRef Errors As System.Array)其他相关的重要事件包括:Group数据变化时的通知事件PublicEvent DataChange(ByVal TransactionID As Integer, ByVal NumItems As Integer, ByRef ClientHandles As System.Array, ByR ef ItemValues As System.Array, ByRef Qualities As System.Array, ByRef TimeStamps As System.Array)Group的异步取消事件Public Event AsyncCancelComplete(ByVal CancelID As Integer)Server(服务器)关闭通知事件Public Event ServerShutDown(ByVal Reason As String)以下是这些实现的代码段'读取卡片指定的块号的值Private Sub btnReadCard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) If Not(ConnectedGroup Is Nothing) ThenTry'获取块号Dim BlockNo As Short= CByte(ReadBlockNo.Text)'如果要获取数据的块所对应的项还没有创建,就创建它If GlobalOPCBlockItems(BlockNo) Is Nothing ThenGlobalOPCBlockItems(BlockNo) =ConnectedGroup.OPCItems.AddItem("Reader_Device.Block"& CStr(BlockNo), 200 + BlockNo)End If'准备参数数组Dim ServerResults As System.ArrayDim ServerErrors As System.ArrayDim ServerHandles(1) As IntegerServerHandles(1) = GlobalOPCBlockItems(BlockNo).ServerHandle'读取值ConnectedGroup.SyncRead(OPCAutomation.OPCDataSource.OPCDevice, 1, ServerHandles, ServerResults, ServerErrors)If ServerErrors(1) <> 0 ThenMsgBox("Read Card Failed:"& ServerErrors(1))ElsetxtReadBlockNo.Text = ServerResults(1)End IfCatch ex As ExceptionMessageBox.Show("OPC server Read Card failed: "+ ex.Message, "OPCSample", MessageBoxButtons.OK)End TryEnd IfEnd Sub'写卡片指定块的值Private Sub btnWriteCard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) If Not(ConnectedGroup Is Nothing) ThenTry'获取块号If GlobalOPCBlockItems(BlockNo) Is Nothing ThenGlobalOPCBlockItems(BlockNo) =ConnectedGroup.OPCItems.AddItem("Reader_Device.Block"& CStr(BlockNo), 200 + BlockNo)End If'准备参数数组Dim ServerValues(1) As ObjectDim ServerErrors As ArrayDim ServerHandles(1) As IntegerServerHandles(1) = GlobalOPCBlockItems(BlockNo).ServerHandleServerValues(1) = txtWriteBlockNo.Text'写入值ConnectedGroup.SyncWrite(1, ServerHandles, ServerValues, ServerErrors)If ServerErrors(1) <> 0 ThenMsgBox("Write Card Failed:"& ServerErrors(1))ElseMsgBox("Write Card Succeed")End IfCatch ex As ExceptionMessageBox.Show("OPC server Write Card failed: "+ ex.Message, "OPCSample", MessageBoxButtons.OK)End TryEnd IfEnd Sub(六):断开服务器断开服务器只要使用OPCServer的Disconnect方法几个,以下是代码段:'断开到指定OPC服务器的连接Private Sub btnDisconnectServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Hand les btnDisconnectServer.ClickIf Not(ConnectedOPCServer Is Nothing) ThenTryConnectedOPCServer.Disconnect()Catch ex As ExceptionMessageBox.Show("OPC server disconnect failed: "+ ex.Message, "OPCSample", MessageBoxButtons.OK)FinallyConnectedOPCServer = NothingResetControlStatus()End TryEnd IfEnd Sub(七):相关链接非常好的一个OPC技术网站/OPC基金会网址/国内的一个比较好的OPC网站/Index.html(八):全部源码Dim GlobalOPCServer As OPCAutomation.OPCServerClassDim WithEvents ConnectedOPCServer As OPCAutomation.OPCServerClassDim WithEvents ConnectedGroup As OPCAutomation.OPCGroupClassDim GlobalOPCItems(4) As OPCAutomation.OPCItemDim GlobalOPCBlockItems(64) As OPCAutomation.OPCItem'枚举OPC服务器列表Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadTryGlobalOPCServer = New OPCAutomation.OPCServerClass()Dim ServerList As Object = GlobalOPCServer.GetOPCServersFor index As Short = LBound(ServerList) To UBound(ServerList) '加入控件列表中,注意这里使用LBound和UBoundcbbServerList.Items.Add(ServerList(index))NextIf cbbServerList.Items.Count > 0 ThencbbServerList.SelectedIndex = 0End IfResetControlStatus() '设置控件状态GlobalOPCServer = NothingCatch Ex As ExceptionMessageBox.Show("List OPC servers failed: " + Ex.Message, "OPCSample", MessageBoxButtons.OK) End TryEnd Sub'连接到指定的OPC服务器Private Sub btnConnectServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConne ctServer.ClickIf cbbServerList.Text <> "" ThenConnectedOPCServer = New OPCAutomation.OPCServerClass()TryConnectedOPCServer.Connect(cbbServerList.Text)'设置组集合的默认属性ConnectedOPCServer.OPCGroups.DefaultGroupIsActive = TrueConnectedOPCServer.OPCGroups.DefaultGroupDeadband = 0'添加组ConnectedGroup = ConnectedOPCServer.OPCGroups.Add()ConnectedGroup.UpdateRate = 3 * 1000 '刷新虑,用于下面的DataChange事件ConnectedGroup.IsSubscribed = True'使用订阅功能'添加项GlobalOPCItems(0) = ConnectedGroup.OPCItems.AddItem("Reader_Device.OpenCard", 0)GlobalOPCItems(1) = ConnectedGroup.OPCItems.AddItem("Reader_Device.CloseCard", 1)GlobalOPCItems(2) = ConnectedGroup.OPCItems.AddItem("Reader_Device.CardNO", 2)RefreshServerStatus() '刷新服务器状态Catch ex As ExceptionConnectedOPCServer = NothingMessageBox.Show("OPC server connect failed : " + ex.Message, "OPCSample", MessageBoxButtons.OK) End TryResetControlStatus()End Sub'服务器断开事件通知Private Sub OnServerShutDown(ByVal Reason As String) Handles ConnectedOPCServer.ServerShutDownbtnDisconnectServer_Click(Nothing, New EventArgs())End SubPrivate Sub OnGroupDataChange(ByVal TransactionID As Integer, ByVal NumItems As Integer, ByRef ClientHandles As System.Array, ByRef ItemValues As System.Array, ByRef Qualities As System.Array, ByRef TimeStamps As System.Arr ay) Handles ConnectedGroup.DataChangeFor i As Integer = 1 To NumItemsIf Qualities(i) = OPCAutomation.OPCQuality.OPCQualityGood ThenSelect Case ClientHandles(i)Case 2txtCardNo.Text = CStr(ItemValues(i))Case 200 '测试7张卡片txtValueBlock0.Text = CStr(ItemValues(i))Case 201txtValueBlock1.Text = CStr(ItemValues(i))Case 202txtValueBlock2.Text = CStr(ItemValues(i))Case 203txtValueBlock3.Text = CStr(ItemValues(i))Case 204txtValueBlock4.Text = CStr(ItemValues(i))Case 205txtValueBlock5.Text = CStr(ItemValues(i))Case 206txtValueBlock6.Text = CStr(ItemValues(i))Case 207txtValueBlock7.Text = CStr(ItemValues(i))Case ElseEnd SelectEnd IfNextEnd Sub'断开到指定OPC服务器的连接Private Sub btnDisconnectServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDis connectServer.ClickIf Not (ConnectedOPCServer Is Nothing) ThenTryConnectedOPCServer.Disconnect()Catch ex As ExceptionMessageBox.Show("OPC server disconnect failed: " + ex.Message, "OPCSample", MessageBoxButtons.OK) FinallyConnectedOPCServer = NothingResetControlStatus()End TryEnd If'开卡,并返回卡号Private Sub btnOpenCard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)If ConnectedGroup IsNot Nothing ThenTry'准备参数数组Dim ServerHandles(1) As IntegerDim ServerValues(1) As ObjectDim ServerErrors As System.ArrayServerHandles(1) = GlobalOPCItems(0).ServerHandleServerValues(1) = 1'写入值,用于执行OpenCard的操作ConnectedGroup.SyncWrite(1, ServerHandles, ServerValues, ServerErrors)If ServerErrors(1) <> 0 ThenMsgBox("OpenCardError: " & ServerErrors(1))End IfServerHandles(1) = GlobalOPCItems(2).ServerHandleDim ServerResult As System.Array'读取卡号ConnectedGroup.SyncRead(OPCAutomation.OPCDataSource.OPCDevice, 1, ServerHandles, ServerResult, Server Errors)If ServerErrors(1) <> 0 ThenMsgBox("ReadCardNoError: " & ServerErrors(1))ElsetxtCardNo.Text = ServerResult(1)End IfCatch ex As ExceptionMessageBox.Show("OPC server Open Card failed: " + ex.Message, "OPCSample", MessageBoxButtons.OK) End TryResetControlStatus()End IfEnd Sub'读取卡片指定的块号的值Private Sub btnReadCard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)If Not (ConnectedGroup Is Nothing) ThenTry'获取块号Dim BlockNo As Short = CByte(ReadBlockNo.Text)'如果要获取数据的块所对应的项还没有创建,就创建它If GlobalOPCBlockItems(BlockNo) Is Nothing ThenGlobalOPCBlockItems(BlockNo) = ConnectedGroup.OPCItems.AddItem("Reader_Device.Block" & CStr(Block No), 200 + BlockNo)End If'准备参数数组Dim ServerResults As System.ArrayDim ServerErrors As System.ArrayDim ServerHandles(1) As IntegerServerHandles(1) = GlobalOPCBlockItems(BlockNo).ServerHandle'读取值ConnectedGroup.SyncRead(OPCAutomation.OPCDataSource.OPCDevice, 1, ServerHandles, ServerResults, ServeIf ServerErrors(1) <> 0 ThenMsgBox("Read Card Failed:" & ServerErrors(1))ElsetxtReadBlockNo.Text = ServerResults(1)End IfCatch ex As ExceptionMessageBox.Show("OPC server Read Card failed: " + ex.Message, "OPCSample", MessageBoxButtons.OK) End TryEnd IfEnd Sub'写卡片指定块的值Private Sub btnWriteCard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)If Not (ConnectedGroup Is Nothing) ThenTry'获取块号Dim BlockNo As Short = CByte(WriteBlockNo.Text)'如果要写入数据的块所对应的项还没有创建,就创建它If GlobalOPCBlockItems(BlockNo) Is Nothing ThenGlobalOPCBlockItems(BlockNo) = ConnectedGroup.OPCItems.AddItem("Reader_Device.Block" & CStr(Block No), 200 + BlockNo)End If'准备参数数组Dim ServerValues(1) As ObjectDim ServerErrors As ArrayDim ServerHandles(1) As IntegerServerHandles(1) = GlobalOPCBlockItems(BlockNo).ServerHandleServerValues(1) = txtWriteBlockNo.Text'写入值ConnectedGroup.SyncWrite(1, ServerHandles, ServerValues, ServerErrors)If ServerErrors(1) <> 0 ThenMsgBox("Write Card Failed:" & ServerErrors(1))ElseMsgBox("Write Card Succeed")End IfCatch ex As ExceptionMessageBox.Show("OPC server Write Card failed: " + ex.Message, "OPCSample", MessageBoxButtons.OK) End TryEnd IfEnd Sub'重设控件状态Private Sub ResetControlStatus()If ConnectedOPCServer Is Nothing ThenbtnConnectServer.Enabled = TruebtnDisconnectServer.Enabled = FalsebtnReadCard.Enabled = FalsebtnWriteCard.Enabled = FalsebtnOpenCard.Enabled = FalsebtnCloseCard.Enabled = FalseReadBlockNo.Value = 0WriteBlockNo.Value = 0txtCardNo.Text = ""txtSrvStartTime.Text = ""txtSrvCurrTime.Text = ""txtSrvGroupCount.Text = ""txtSrvGroupDeadBand.Text = ""txtSrvGroupDefActive.Text = ""txtSrvGroupLocalID.Text = ""txtSrvGroupTimeBias.Text = ""txtSrvRequestRate.Text = ""ElsebtnConnectServer.Enabled = FalsebtnDisconnectServer.Enabled = TrueIf txtCardNo.Text = "" ThenbtnReadCard.Enabled = FalsebtnWriteCard.Enabled = FalsebtnOpenCard.Enabled = TruebtnCloseCard.Enabled = FalseElsebtnReadCard.Enabled = TruebtnWriteCard.Enabled = TruebtnOpenCard.Enabled = TruebtnCloseCard.Enabled = TrueEnd IfEnd IfEnd Sub'刷新服务器状态属性信息Private Sub RefreshServerStatus()If ConnectedOPCServer IsNot Nothing ThentxtSrvStartTime.Text = ConnectedOPCServer.StartTime.ToString()txtSrvCurrTime.Text = ConnectedOPCServer.CurrentTime.ToString()With ConnectedOPCServer.OPCGroupstxtSrvGroupCount.Text = CStr(.Count)txtSrvGroupDeadBand.Text = CStr(.DefaultGroupDeadband)If .DefaultGroupIsActive ThentxtSrvGroupDefActive.Text = "True"ElsetxtSrvGroupDefActive.Text = "False"End IftxtSrvGroupLocalID.Text = CStr(.DefaultGroupLocaleID)txtSrvGroupTimeBias.Text = CStr(.DefaultGroupTimeBias)txtSrvRequestRate.Text = CStr(.DefaultGroupUpdateRate)End WithEnd IfEnd Sub'关闭卡片Private Sub btnCloseCard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) If ConnectedGroup IsNot Nothing ThenTryDim ServerHandles(1) As IntegerDim ServerValues(1) As ObjectServerHandles(1) = GlobalOPCItems(1).ServerHandleServerValues(1) = 1ConnectedGroup.SyncWrite(1, ServerHandles, ServerValues, ServerErrors)If ServerErrors(1) <> 0 ThenMsgBox("Close Card Error: " & ServerErrors(1))End IfCatch ex As ExceptionMessageBox.Show("OPC server Close Card failed: " + ex.Message, "OPCSample", MessageBoxButtons.OK) End TryEnd IfEnd SubEnd ClassPrerequisites: ComboBox control named cbbServerList, Button1 and Button2 on Form1.Code BlockPublic Class Form1Dim GlobalOPCServer As OPCAutomation.OPCServerClassDim WithEvents ConnectedOPCServer As OPCAutomation.OPCServerClassDim WithEvents ConnectedGroup As OPCAutomation.OPCGroupClassPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles MyBase.Load TryGlobalOPCServer = New OPCAutomation.OPCServerClass()Dim ServerList As Object = GlobalOPCServer.GetOPCServersFor index As Short = LBound(ServerList) To UBound(ServerList)cbbServerList.Items.Add(ServerList(index))NextIf cbbServerList.Items.Count > 0 ThencbbServerList.SelectedIndex = 0End IfGlobalOPCServer = NothingCatch Ex As ExceptionMessageBox.Show("List OPC servers failed: " + Ex.Message, "OPCSample", MessageBoxButtons.OK)End TryEnd Sub' Connect to OPC serverPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles Button1.Cl ickIf cbbServerList.Text <> ""ThenConnectedOPCServer = New OPCAutomation.OPCServerClass()TryConnectedOPCServer.Connect(cbbServerList.Text)'Set property for Group connectionConnectedOPCServer.OPCGroups.DefaultGroupIsActive = TrueConnectedOPCServer.OPCGroups.DefaultGroupDeadband = 0'Add groupConnectedGroup = ConnectedOPCServer.OPCGroups.Add()ConnectedGroup.UpdateRate = 3 * 1000ConnectedGroup.IsSubscribed = True'Add itemsGlobalOPCItems(0) = ConnectedGroup.OPCItems.AddItem("Reader_Device.OpenCard", 0)GlobalOPCItems(1) = ConnectedGroup.OPCItems.AddItem("Reader_Device.CloseCard", 1)GlobalOPCItems(2) = ConnectedGroup.OPCItems.AddItem("Reader_Device.CardNO", 2)Catch ex As ExceptionConnectedOPCServer = NothingMessageBox.Show("OPC server connect failed : " + ex.Message, "OPCSample", MessageBoxButtons.OK) End TryEnd IfEnd Sub' Disconnect to OPC serverPrivate Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles Button2.Cl ickIf Not (ConnectedOPCServer Is Nothing) ThenTryConnectedOPCServer.Disconnect()Catch ex As ExceptionMessageBox.Show("OPC server disconnect failed: " + ex.Message, "OPCSample", MessageBoxButtons.OK) FinallyConnectedOPCServer = NothingEnd TryEnd If End Sub End ClassHierarchyThe OPC server and the client application communicate each other through the interface of COM. The root class is OPC server object, and it accesses the group object and the item object by using this class.The device datas of PLC (ex. 'X0' and 'D0' etc.) are constructed at the low hierarchy, and you can access the device datas as the unit of item or collection.Register OPC automation dllWhen the OPC server is set up, DLL necessary for OPC is automatically registered. For access to OPC Server from Visual Basic, it needs to check "OPC Automation 2.0".Declare OPC Objects (OPC Server / OPC Group / OPC Item)For hooking events of OPC Server, add to "WithEvents" in dimension statement or event handler named "OBJECTNAME_EVENTNAME".Dim WithEvents Myserver As OPCServerDim WithEvents Mygroup As OPCGroupDim WithEvents Mygroups As OPCGroupsDim Myitem As OPCItemDim Myitems As OPCItemsDim MyBrowser As OPCBrowserGet OPC Server ListIt is able to get installed OPC Server name by using OPC Server object. In this sample, it shows OPC Server name in list box and operator can select the target server.Dim Getserver As OPCServerDim Servers As VariantSet Getserver = New OPCServerServers = Getserver.GetOPCServersFor i = LBound(Servers) To UBound(Servers)List1.AddItem Servers(i)Next iSet Getserver=NothingIt is able to get device name registered in OPC Server by using OPC Server object. You can make the Group under device and OPC Server object is enabled to access this lower layer.Set Myserver = New OPCServerMyserver.Connect ServerName.Text, NodeName.TextSet MyBrowser = Myserver.CreateBrowserMyBrowser.ShowBranchesDim bname As VariantFor Each bname In MyBrowserItemList.AddItem "+" & bnameNext nameFor accessing client application to physical device data, it needs to generate OPC Group object in OPC group collection. The OPC Group object can configure update interval of tags. Normally, the device of accessing same cycle will register in same group. Also, you should be carefully CPU performance to create over groups because OPC Server create a thread for each group.Dim ClientHandles(16) As LongDim OPCItemIDs(16) As StringSet Mygroups = Myserver.OPCGroupsSet Mygroup = Mygroups.Add("Group1")Mygroup.UpdateRate = "1000"Mygroup.IsActive = FalseFor i = 1 To 16ClientHandles(i) = iOPCItemIDs(i) = "Device1" + ".D" + Format(i)Next iSet Myitems = Mygroup.OPCItemsMyitems.AddItems 16, OPCItemIDs, ClientHandles, ItemServerHandles, ItemServerErrorsMygroup.IsActive = TrueImplements event handler of OPC Group object for advice mode. The OPC Server read data for each cycle and if changing the value, callback to client application. The quality flag is normally '0xC0', when occurred error, it will be turn to other value. Mygroup.IsSubscribed = TruePublic Sub Mygroup_DataChange(ByVal TID As Long, _ByVal NumItems As Long, Chd() As Long, ItemValues() As Variant, _Qualities() As Long, TimeStamps() As Date)For i = 1 To NumItemsDebug.print ItemValues(i) + ":" + TimeStamps(i) + _":" + Qualities(i)Next iEnd SubThe OPC has two ways of data access, Synchronize and Asynchronous. In Synchronize, the client application must be wait for completing server work. But the client application can confirm server transaction is normally completed because the OPC Server returns the result on completing the communication work. This is a normally style of procedure.In Asynchronous mode, the OPC Server turns the handle to client as soon as receiving the request and proceed the transaction on background. After completing this work, calls handler of client application. Asynchronous mode cut down wait time for communication and be able to run client application.Caution: Asynchronous access is enabled under advice mode.'Sync ReadMygroup.SyncRead OPCDevice, 16, ItemServerHandles, ItemValues, ItemServerErrors, ItemQualities, ItemTimeStampsFor i = 1 To 16Debug.print ItemValues(i) + ":" + ItemTimeStamps(i) + ":" + ItemQuality(i)Next i'Sync WriteFor i = 1 To 16ItemVal(i) = iNext iMygroup.SyncWrite 16, ItemServerHandles, ItemVal, ItemServerErrorsFor i = 1 To 16If ItemServerErrors(i) <> 0 ThenMsgBox "Write ERROR " + Format(i)End IfNext i'Async Read(TransactionID=10, CancelID=11)Mygroup.AsyncRead 16, ItemServerHandles, ItemServerErrors, 10, 11Private Sub Mygroup_AsyncReadComplete(ByVal TransactionID As Long, ByVal NumItems As Long, _ClientHandles() As Long, ItemValues() As Variant, Qualities() As Long, _TimeStamps() As Date, Errors() As Long)Debug.print "AsyncRead Comp" + Chr$(9) + Time$ + Chr$(13) + Chr$(10)End Sub'Async WriteDim ItemVal(ItemCount) As VariantFor i = 1 To ItemCountItemVal(i) = iNext iMygroup.AsyncWrite 16, ItemServerHandles, ItemVal, ItemServerErrors, 100, 101Private Sub Mygroup_AsyncWriteComplete(ByVal TransactionID As Long, _ByVal NumItems As Long, ClientHandles() As Long, Errors() As Long)Debug.print "AsyncWrite Comp" + Chr$(9) + Time$ + Chr$(13) + Chr$(10)End SubIn cache read operation, OPC Server doesn't access the physical device and return the last data on memory. The OPC Server read and caches the value every each time.It will be able to access on high speed if not need newest value.Mygroup.SyncRead OPCCache, 16, ItemServerHandles, ItemValues, ItemServerErrors, ItemQualities, ItemTimeStampsFor i = 1 To 16Debug.print ItemValues(i) + ":" + ItemTimeStamps(i) + ":" + ItemQuality(i)Next iI am trying to develop an opc - da client using .net technology.Have gone through the documents on opc and opc client and all,but am still not sure how to implement it, can someone give me a direction on how to start with it?59 Answers FoundAnswer 1can you please provide some additional details on exactly what you're trying to do and any other relevant info that I can pass on to our support engineer?thanks,-brenda (ISV Buddy Team)Answer 2Hey Ksona,I was just speaking to a college of mine about DA cleints this morning. Have your checked out the opc Exchange at/ ?I know that Eric Murphy is an OPC genius, and he can probably give you a hand, or point you in a great direction.You can also email me and I can see if one of my college's has some time to help you out? I'm curious as to what devices you are trying to access?Answer 3Genius? That's a wee bit over the top, let's just say I've experienced a thing or two about OPC. However, if you're fishing for a response, flattery will get you everywhere :)As the other replies pointed out, the question is a bit open ended. 'using .NET technology' offers a few possibilites, depending on your develpoment language C#, , managed C++, etc.The easiest way, would be to make use of the OPC client .NET wrapper supplied by the OPC Foundation. You do have to be a member to access this, however that offers other advantages such as invitations to the OPC Interoperabilty events to test your client against other vendors.If that's not an option, I have seen applications that make use of the OPC Automation dll. This was originally intended for VB apps, but some vendors have upgraded the automation interface to work with You would have to ask specifically because not all versions do.Otherwise, you are looking at writing an application that interfaces to unmanaged COM interfaces. From an programatic point of view, an OPC client would be no different from any other COM client. If you're new to OPC, this is not a trivial task...。

相关主题