- 二、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.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的开发,主要将各种不同类型的远程设备通过同一手段进行数据采集,并集成到企业信息化平台中去。
复制代码 |