[电气]用VB编写OPC客户端访问WINCC
- 格式:doc
- 大小:45.00 KB
- 文档页数:6
(1)建立新工程或项目,在“工程”菜单下选择“引用”,如图5-3所示。
只有引用OPCDAAuoto.DLL后,在程序中才能创建服务器对象,然后进行一系列的操作。
(2)在弹出的引用窗口里单击“浏览(B)…”按钮,弹出添加引用窗口,选择OPCDAAuoto.DLL 文件。
(3)在引用窗口里的OPC Automation 2.0前面打钩,按“确定”按钮。
(4)定义全局变量,这样可以在窗体的任何方法的代码内应用。
变量类型应该指定为对象型。
这些对象最好在窗体的通用部分声明加上“Option Explicit”语句,表示模块里的所有变量都需要显式声明。
由于OPC自动化接口的数组的索引要求必须从1开始,而系统默认是从0开始,为了避免错误最好在代码的最初加上“Option Base 1”语句。
为了使对象可以处理事件,必须将objTestGrp和objServer的声明中加上“WithEvents”语句,表示声明的对象可以响应事件。
Option ExplicitOption Base 1Dim WithEvents objServer As OPCServerDim objGroups As OPCGroupsDim WithEvents objTestGrp As OPCGroupDim objItems As OPCItems(5)连接OPC服务器和建立OPC组考虑到代码的可反复使用性,采用子程序进行编程。
Sub Connect(strProgID As String, Optional strNode As String)If objServer Is Nothing Then' 建立一个OPC服务器对象Set objServer = New OPCServerEnd If服务器状态ServerState属性一共有OPCRunning、OPCFailed、OPCNoconfig、OPCSuspended、OPCTest和OPCDisconnected六个值,分别表示正在运行、失败、没有配置、暂停、测试和没有连接六种OPC服务器当前的状态。
如何从外部使用VBS脚本访问WinCC变量?
通过Windows 脚本宿主可以访问WinCC Tag,用这种方法可以非常简单的与WinCC运行系统交换数据。
我们已Windows VBS 脚本为例说明这个功能的用法:
1. 首先,在WinCC中建立Tag 用于被外部VBS访问,比如:新建一个WinCC 内部Tag:a ,类型为16位整型。
2. 在WinCC中新建一个画面用来显示Tag a的值,激活该画面。
3. 打开Windows中纯文本编辑器,比如:写字板。
保存为后缀为.vbs文件,比如:tag.vbs 。
4. 双击执行tag.vbs这个文件。
5. 在弹出对话框中输入WinCC Tag名:a,
6. 然后点击“OK”,会出另外一个对话框,输入要付给WinCC Tag的值,比如:10。
点击“OK”。
7. 这时,WinCC画面的值会立刻变为10:
该方法的使用方法,与WinCC的VBS类似,可以参考WinCC VBS的帮助文档。
这种通过外部脚本访问运行时WinCC变量的方法,同样可以用于Excel的VBA中。
OPC组态软件与WINCC通讯1、 OPC软件设置打开KEPServerEx软件,到Tool->Options进入OPC DX选项卡下面。
将Enable OPC Date Exchange打勾,详细功能请参照下面帮助,点击确定。
2、 OPC软件下添加通讯变量。
这里新建一个三菱的驱动,通过485串口通讯(非编程口),选择驱动名称为Mitsubishi FX Net,点击下一步。
设置通讯接口,将Flow设置成始终。
点击下一步。
三菱的协议数据位为7位,这个要注意。
下面为默认。
再点击完成。
然后点击新建驱动。
选择PLC型号为FX3U,点击下一步。
设置PLC地址。
关于三菱里面的PLC地址与通讯参数设置请参照三菱PLC帮助,与KEPServerEx帮助。
以下是KEPServerEx软件帮助。
KEPServerEx软件支持的PLC型号与通讯协议。
需要在三菱PLC中选择格式一,和校验。
下面全部选择默认参数。
点击完成。
在PLC1上点右键新建变量或者变量组。
如果变量很多推荐使用变量组功能,这里就不再演示,这里直接新建变量了。
填写变量名,变量地址,注释,变量类型,还有读写权限。
点击确定。
此时新建变量已完成。
3、 OPC软件与PLC通讯测试点击工具栏中的OPC进行测试。
到FX3U.PLC1下监控变量的值。
后面有质量是Bad,还是Good,说明是已建立通讯还是通讯失败。
另外软件下面也有相关信息这个报警说明我的COM1已被使用。
如果WINCC需要监控OPC软件与PLC是否连接成功,可以监控FX3U.PLC1._System中的Error变量的值,如果是TRUE说明通讯失败。
4、 WINCC建立连接在变量管理上点击右键,选择添加新的驱动程序。
选择OPC.chn。
WINCC 7.0以后软件中集成的Modbus TCPIP驱动。
这样是WINCC应用更方便。
在OPC Groups上点击右键选择系统参数,此时WINCC开始查询电脑中的OPC服务器。
用VB编写OPC客户端访问WinCC的实现
秦胜利;王锬
【期刊名称】《安徽冶金》
【年(卷),期】2011(000)004
【摘要】介绍了OPC自动化接口在VB中的使用,并详细描述如何利用WinCC提供的OPC服务器接口编写客户应用程序的步骤。
【总页数】3页(P33-35)
【作者】秦胜利;王锬
【作者单位】马鞍山钢铁股份有限公司
【正文语种】中文
【中图分类】TP3
【相关文献】
1.VB6.0编程客户端访问组态王OPC服务器的实现方法 [J], 邹治军
2.VB中利用OPC访问WinCC实现下位机实时报警 [J], 叶海涛;苏建元
3.通过OPC实现VB访问WINCC数据 [J], 吴晓蕾;李逸;胡国军;刘渤;张细兰
4.用VB编写OPC客户端程序实现数据共享的方法 [J], 李晓诗;赵志峰
5.VB环境下通过OPC接口访问WinCC数据的实现 [J], 李新军
因版权原因,仅展示原文概要,查看原文内容请购买。
使用VB或VBS访问WINCC6.0历史数据库从WINCC6.0开始,就开始采用SQL3000SP3做为WINCC的后台数据了.而这个SQL2000SP3是由SIEMENS为WINCC做了二次开发的,采用了一些独有的技术,一些是我们知道的,一些是我们所不知道的.所以当我们打开SQL管理器和用高级语言访问时,和常规的SQL访问的方法是有一些出入的.即使我们能够很轻易的访问ACCESS,普通的SQL2000的数据库,不见的你就能顺利的访问到WINCC的历史数据.官方的资料显示:1:WINCC的数据有设计时数据库和运行时数据库,分别放在相关的目录,对于数据使用者而言,我们知道就可以了.设计时数据库我们了解没有什么意义.但运行时数据库至少我们要知道它的名.他的名一般是"CC_工程名_年_月_日_时_分_秒R"的名,这个对于我们使用者而言,是很重要的的,无论你准备以DSN或OLEDB的方式访问数据库,你都需要它.如果你实在不知道它的名,你可以将WINCC激活,然后在'ODBC管理器"或"SQL企业管理器下的"DATABASE"可以看到它,它就蹲在那里.....2:运行时库的表的问题.其实,这个是很多的用户很关心的问题,包括我自己在内.常规的使用过高级语言访问SQL的技术人员都知道,很多的SQL语句,如SELECT ,INSERT INTO等等,都需要指明在某一库的表中对它进行操作.因此,这个表的问题可能就是你访问SQL的拦路虎.先告诉大家:WINCC6.0的SQL库操作是不需要表名的,因为他有自己定义的SQL语句.细节一会儿在描述.其实,WINCC在运行时,根据WINCC的设置,数据归档是以一定时间做为基准,形成数据片段. 大体上有三个用户需要了解的表.在数据片段下,有三个表是我们所关心的1:ARCHIVE(用户归档记录)2:TAGPRESSED(TAGUNPRESSED)(压缩/非压缩变量归档记录)3:MSARCLONG(报警记录)事实上,我们在操作数据时,还是并不能直接使用常规的SQL来操作这些表,甚至不允许修改它,MSARCLONG情况好一些,允许插入/修改等.TAGPRESSED的数据和WINCC内设置的变量管理下的归档是对应的,MSARCLONG的数据和WINCC内设置的报警记录下的设置是对应的.ARCHIVE的数据和WINCC内的用户归档数据是对应的.一般的,当我们使用WINCC制作在线表格和在线趋势使用的都是变量管理器下的归档.因此,我们打开TAGPRESSED的表,可以看到的一些都是变量记录的内容,通常也是在这里归档了用户的生产数据.因此,我们访问WINCC历史数据库,实际上是访问这里的变量记录3:访问历史数据库的方法/连接字符/SQL语句访问数据库的方法:A:WINCCOLEDB访问压缩归档,也可以访问非压缩归档B:MS ADO/OLEDB只能访问非压缩归档对于这种说法,我只严正了WINCCOLEDB的方法,后者没有测试.连接字符:WINCCOLEDB的连接字符为(本地):provider=winccoledbprovider.1,catalog=.\wincc,data source=数据库名,user id=DBA,password=SQL对于远程连接,因为没有条件测试,所以就不说了,希望有哪位朋友日后通过了测试,到这里告诉一下现在开始讲访问用户归档,过程值归档和消息归档的方法和语法:1:查询过程值归档和消息归档的连接字符串SET CON=Createobject("adodb.connection")con.openProvider=winccoledbprovider.1;catalog=cc_工程名_年_月_日_时_分_秒R,data source=.\wincc,user id=DBA,password=SQL说明:按照WINCC规定的连接字符串,创建到数据库的连接,并且打开这个连接.其中,我们经常需要修改的是Catalog的值,这个值根据不同的工程和创建的时间不同,我们可以在ODBC管理器下或SQL的库中看到.查询过程值归档和用户归档的SQL语句TAG:R,'变量名1','起始时间','终止时间' where条件说明:WHERE子句只对用户归档有效,对过程值归档无效.变量名:这个变量名要和WINCC下的变量管理器的过程值归档名要一致.其格式为:归档名/变量名.起始时间和终止时间可以用相对时间和绝对时间,一般绝对时间比较容易理解,就是从开始时间到终止时间就好了.例如,查询从2006/3/12 12:20:20秒到2006/3/13/ 12:20:20秒的数据,则应该写成'2006-3-12 12:20:20' '2006-3-13 12:20:20'就好了.当然拉,也可以用相对时间格式,就是比目前时间的相对值,有个前移后移的问题,很简单的.这里特别需要注意的是:记录到SQL数据库的时间都是格林威治时间,和中国的东8区有8个小时的时间差,也就是说记录的时间比本机PC时区晚8小时,这一点我们在测试是尤其重要.因为你是时间不正确,可能数据就没有显示,而导致你怀疑连接/命令/记录的有效性访问SQL数据库的方法过程描述.这和访问普通的数据库的方法大致上是相同,唯一的就是由于WINCC的数据是经过了压缩的.1:定义连接字符串,就是前面所讲到的.2:创建ADODB的CONNECTION对象,在VB中直接用CREATEOBJECT(ADODB.CONNECTION)函数,在ASP的VB脚本中,需要使用内置SERVER 对象创建CONNECTIONG对象.3:打开到数据库的连接,使用CONNECTION的OPEN函数4:创建COMMAND对象,并定义COMMAND对象采用用CMDTEXT方法,表明将要使用命令文本的方式来获取数据记录.5:创建RECORDSET对象,并用COMMAND对象的返回记录集填充这个记录集.6:RECORDSET对象的数据就可以被你任意的使用了查询过程值归档和用户归档的SQL语句TAG:R,'变量名1','起始时间','终止时间' where条件-----------------------------------------------这就是怪怪的SQL语句,在ADO下,会出错!解决了肯定设法要给200分的,关键有没有双料精英呀,这年头“计算机”与“工控”都会的不好找呀。
Private Sub Command1_Click()Dim AllOPCServers As VariantDim i As IntegerSet AnOPCServer = New OPCServerList1.ClearAllOPCServers = AnOPCServer.GetOPCServersFor i = LBound(AllOPCServers) To UBound(AllOPCServers)List1.AddItem AllOPCServers(i)Next iSet AnOPCServer = NothingEnd Sub试了一下果然可以。
点击list中某一个opcserver,然后调用opcserver对象的connect方法就可以连接上去了。
网上的例子里面是做了个示范,标签名用了个循环赋值,For I=1To17strItemIDs(I)="Server.Group.TAG"&IlClientHandles(I)=INext’添加OPC项Call objItems.AddItems(17,strItemIDs,lClientHandles,lServerHandles,lErrors)但是例子里面也承认“OPC客户端程序要按照用户指定的标签或者从组态文件里读取需要添加的OPC标签。
”那么,实际上来说,要么用browse标签的方法去一个一个选择标签,要么事先在程序里面指定好各个标签名字了(当然可以用一个类似与ini配置文件的方法存储好要各个标签的名字,这个以后再说吧)。
从实际应用考虑,我觉得browse的方法没有必要,因为一般来说直接确定好哪些标签就行了,而且如果用参数文件的话也算比较容易后期进行配置(前提应该是tag名字要写正确)。
Items有个additems的方法,用于添加标签,参数比较多,认真看了下例子,还是有点技巧的,从第二个参数开始都是数组类型的参数,而前两个数组必须指定好长度,后面三个数组则无须指定长度,很怪啊,反正vb认可就ok了,难怪例子里面这么定义的几个数组。
如何用VB编写OPC客户端程序一、引言在工业自动化领域,计算机早已成为必不可少的工具,计算机技术的不断发展,大大加速了工业自动化技术的进步,而各种各样的工业控制应用软件正是具体实现这一进程的最重要的工具;以往,应用软件开发商要为每一种硬件开发驱动程序,由于硬件的种类繁多,特征各异,软件开发商的负担异常繁重,尤其是如果硬件特征发生了变化,整个应用软件相应的驱动程序也要相应地修改,这对软件开发商,对整个工程都是很不利的;而且由于驱动程序的不统一,不同应用程序访问同一硬件设备时常常发生冲突;OPCOLE for Process Control技术标准正是在这种情况下产生的;OPC基于微软的OLE、COM和DCOM技术,而且它本身就是一种特殊的COM,也正因为有微软的参与,以及以已经成熟的技术为基础,它比一般的工业标准制定的效率更高,它从开始制定到第一个可运行的规范开始运行,只用了不到一年的时间;二、OPC原理及应用OPC技术为工业自动化软件面向对象的开发提供了统一的标准;它大大减轻了软件开发商的负担,软件开发商不必再为每一硬件单独编写驱动程序,只要硬件的特征符合统一的OPC接口程序标准,或者硬件生产商提供OPC服务器,如图一所示,不同的应用软件开发商都可以采用OPC标准设计工控软件,以标准规定的统一接口通过OPC服务器存取现场数据;这样,当现场设备发生变化或系统中加入新设备时,OPC服务器的提供商需要重新实现服务器接口,以适应硬件的变化,但由于服务器所提供的接口的一致性,工控软件不作更改即可继续使用,只是某些情况下可能需要重新组态如添加新的PLC站点等,这样,软件开发商可以节省大量的时间致力于工控软件的性能方面的提高,不必再考虑硬件变化带来的影响,大大减小了软件维护的工作量;这正如OPC规范里所说,OPC将应用软件和硬件设备划清了界限;2.1 OPC基本结构OPC服务器有两类接口:定制接口Custom Interface 、自动化接口Automation Interface,定制接口比较低级,它提供更多的功能,效率也比后者高,可以用C++语言调用此类接口,自动化接口主要用于VB、DELPHI等开发工具;按照OPC 规范,定制接口是服务商必须提供的,而自动化接口则是可选的,不过,OPC基金会管理OPC标准的国际组织提供了一个叫做“自动化包装器”的动态连接库,用于在两者间转换;如图二所示:在OPC的早期规范里主要包括OPC数据存取规范、OPC报警和事件、OPC 历史数据存取规范;OPC数据存取规范详细规定了客户程序和服务器程序进行数据通信的机制,其它类型的OPC服务器往往是在数据存取服务器的基础上通过增加对象、扩展接口而来的,所以该规范也是其它OPC规范的基础;OPC数据存取规范规定的基本对象有三类:OPC Server、OPC Group和OPC Item,OPC Server包含服务器的所有信息,也是OPC Group的容器,OPC Group除了包含它自身信息外,还负责管理OPC Item;它们的结构如图三所示;每一个OPC Item 代表到数据源的一个连接,但它没有提供外部接口,客户端程序无法对OPC Item 直接进行操作,应用程序必须依靠OPC Item的容器OPC Group来对它进行操作,这在下面的程序中会有具体说明;2.2 OPC数据访问方式OPC客户程序对OPC服务器中数据的存取方式分为同步读写方式和异步读写方式;客户程序可按照一定的周期调用OPC Group对象的IOPCSyncIO接口对服务器程序进行数据同步存取操作,此时客户方的调用函数一直运行到所有数据读写完成,然后才能执行其它操作,因此,这种方法适合与读取少量数据,如果数据多的话,会使系统处于假死状态,无法进行操作;IOPCSyncIO2是从3.0版才出现的,是对IOPCSyncIO的增强;IOPCAsyncIO2和IOPCAsyncIO3是异步方式中使用的接口,异步访问时,当客户端对服务器提出访问要求后,立即返回到OPC应用程序执行其它操作,无须等待,当OPC服务器完成数据读取后通知OPC应用程序,应用程序从而得到数据;其中前者是在2.0版本中新定义的,具有较高的通信性能;后者则是在3.0版本中才刚刚出现,同IOPCSyncIO2类似,IOPCAsyncIO3是对IOPCAsyncIO2的增强;在异步方式下,服务器程序收到读请求后,调用客户程序方的IOPCDataCallback接口,将数据发送给客户程序;异步方式中允许服务器将读写操作进行排队,使客户方的调用函数可立刻返回,当服务器读写操作完成后再通知客户程序;显然,异步通报方式的通信效率更高,这种方式也是本文所要讨论的方式,但有多个客户程序与服务器相连时,同步读写方式更具时效性;对于每个组对象,客户程序可根据需要采用其中一种数据存取方式,而不能两者都使用;异步读取还有一种特殊的方式,叫做订阅方式Subscribe这种情况下,应用程序不需要发出读请求,OPC服务器在定期更新数据的时候,如果发现数据有一定变化,则自动向应用程序发出通知和传输变化的数据;2.3 编写OPC客户端应用程序VB简单实用,是比较理想的OPC应用程序快速开发工具,若要用VB开发OPC应用程序,必须要使用OPC自动化包装器,这在前文已经提过,这种包装器一般由OPC服务器的供应商以DLL形式提供,下面就以SIEMENS提供的sopcdaauto.dll为例,介绍如何开发OPC应用程序,这也正是笔者在最近的工程中实际应用到的,这是基于DA2.0的版本;首先,新建VB工程后,作图四所示的引用:2.3.1 建立OPC对象首先申明OPC对象:Option Base 1Dim WithEvents ServerObj As OPCServer 'OPC Server对象,连接OPC服务器Dim GroupsObj As OPCGroups 'OPC Groups对象,添加OPC组Dim WithEvents GroupObj As OPCGroup 'OPC Group对象Dim ItemsObj As OPCItems 'OPC Item集合Dim ServerHandles As Long '服务器端OPC Item的句柄Dim ClientHandles as Long '客户端OPC Item的句柄Dim ItemId2 As StringDim Errors As Long接下来,生成各个对象:If ServerObj Is Nothing Then Set ServerObj = New OPCServer'连接OPC服务器If ServerObj.ServerState = OPCDisconnected ThenServerObj.Connect "OPC.SimaticNET" '假设OPC服务器运行在本机End IfIf GroupsObj Is Nothing Then Set GroupsObj = ServerObj.OPCGroupsIf GroupObj Is Nothing Then Set GroupObj = GroupsObj.AddIf ItemsObj Is Nothing Then Set ItemsObj = GroupObj.OPCItems GroupObj.IsActive = True '设置组为活动状态'假设有两个数据源,一个是8位开关量输入,一个是8位开关量输出ItemId1 = "S7:S7 connection_1IB0"ItemId2 = "S7:S7 connection_1QB0"ClientHandles1 = 1ClientHandles2 = 2'添加组项目,ServerHandles数组的值为各个OPC Item的服务器句柄,' ClientHandles数组的值为各个OPC Item的客户端句柄,由应用程序设定Call ItemsObj.AddItems2, ItemId, ClientHandles, ServerHandles, Errors2.3.2异步数据读取' OPC Item的服务器句柄,添加OPC Item时由服务器分配Dim TempServerHandles1 As Long'事务标志符,由客户端产生,它包含的信息提供给OnReadComplete事件Dim TransactionID As Long'取消标志符,服务器端产生,用于操作需要被取消的时候Dim CancelID As Long'包含读取每个OPC Item时返回的信息Dim ErrorNr As LongTempServerHandles1 = ServerHandles1 '对应第一个OPC ItemGroupObj.AsyncRead 1, TempServerHandles, ErrorNr, TransactionID, CancelID第一个参数是要读的OPC Item的个数,这里只含有一个OPC Item;读取的结果由OPC服务器通过IconnectionPointContainer接口配合IOPCDataCallback 接口反调用应用程序的事务处理程序:Private Sub GroupObj_AsyncReadCompleteByVal TransactionID As Long, ByVal NumItems As Long, ClientHandles As Long, ItemValues As Variant, Qualities As Long, TimeStamps As Date, Errors As Long这里的参数ClientHandles和AddItems方法中的ClientHandles是对应的,用于判断哪一个OPC Item在被读取;其它参数的说明如下:TransactionID:客户端自由使用,应用程序开发商自定义;NumItems:表示读取的OPC Item的个数;ItemValues:各个OPC Item连接的数据源的值,类型为Variant;Qualities:OPC Item的品质值;TimeStamps:时间戳;Errors:记录服务器返回的信息;2.3.3 异步数据写入Dim TempServerHandles 1 As LongDim VValue1 As VariantDim ErrorNr As LongDim TransactionID As LongDim CancelID As LongTempServerHandles1=ServerHandles2VValue1=1'假设要将“1”写入ClientHandle为2的OPC ItemGroupObj.AsyncWrite 1,TempServerHandles,VValue, ErrorNr, TransactionID, CancelID同样,AsyncWrite也对应一个事务处理程序:Private Sub groupObj_AsyncWriteCompleteByVal TransactionID As Long, ByVal NumItems As Long, ClientHandles As Long, Errors As Long它的参数的含义和AsuncReadComplete中的含义是类似的,这里一般需要处理的是写数据之后的返回状态,这里不再赘述;2.3.4断开与服务器的连接ItemsObj.Remove ItemsObj.Count,ServerHandles, Errors '清除OPC ItemSet ItemsObj = Nothing '释放资源,下同If Not GroupObj Is Nothing ThenGroupsObj.Remove GroupObj.ServerHandle '删除组End IfIf Not GroupsObj Is Nothing ThenSet GroupsObj = NothingEnd IfIf Not ServerObj Is Nothing ThenIf ServerObj.ServerState <> OPCDisconnected ThenServerObj.Disconnect '断开与服务器的连接End IfSet ServerObj = NothingEnd If三、结束语由于OPC技术的不断发展,现场设备与系统软件的连接越来越方便和灵活,应用程序的制作和升级也越来越简单;正是因为OPC显著的优越性,越来越多的工业硬件制造商开始支持OPC,近年来,除了以前的一些知名大公司,如ABB、西门子等,又有许多公司加入了OPC基金会,随着OPC规范的广泛使用,整个自动化领域必将得到更快的发展;。
用VB编写OPC客户端访问WINCCOPC是一个工业标准,它是由一些世界上著名的自动化系统和硬件、软件公司和Microsoft(微软)紧密合作而建立的。
〔O代表OLE(对象链接和嵌入),P (process过程),C (control控制)。
OLE已从面向对象重新定义为基于对象并更名为Active X〕。
WinCC是西门子公司在自动化领域采用最先进的技术与微软公司在共同开发的居于世界领先地位的工控软件。
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的标签数组与值数,注意,值数组一定要设为Variant。
'OPC处理:只对WINCCConst ServerName = "OPCServer.WinCC" 'OPC的类型Const NodeName = "GUK" '结点名,即计算机名'Dim NodeName As StringDim WithEvents MyOPCServer As OPCServer 'OPC服务Dim MyOPCGroupColl As OPCGroups 'Dim WithEvents MyOPCGroupOut As OPCGroup 'OPC组,本程序用两个组进行OPC连接Dim WithEvents MyOPCGroupIn As OPCGroupDim MyOPCItemCollIn As OPCItems 'OPC标签组Dim MyOPCItemCollOut As OPCItemsDim ServerHandlesIn() As Long '句柄Dim ServerHandlesOut() As LongDim ErrorsIn() As Long '错误句柄Dim ErrorsOut() As LongDim 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 IntegerDim TarnscationID As LongDim CanceID As LongDim ClientHandles1(100) As LongDim ii As IntegerOn Error GoTo HANDLEeRRORFor ii = 0 To 100ClientHandles1(ii) = ii 先配置名柄索引,这将在读取OPC标签的值时可要用到Next iiTarnscationID = 1' NodeName = xProfile.GetValue("SYSTEM", "NodeName")'生成OPC对象,Set MyOPCServer = New OPCServerMyOPCServer.Connect ServerName, NodeNameSet MyOPCGroupColl = MyOPCServer.OPCGroupsMyOPCGroupColl.DefaultGroupIsActive = TrueSet MyOPCGroupIn = MyOPCGroupColl.Add("MYGROUPIN")Set MyOPCGroupOut = MyOPCGroupColl.Add("MYGROUPOUT")Set MyOPCItemCollIn = MyOPCGroupIn.OPCItemsSet MyOPCItemCollOut = MyOPCGroupOut.OPCItems'进行OPC标签连接If WriteItemIdex > 0 ThenMyOPCItemCollOut.AddItems WriteItemIdex, WatchDataWriteItem, ClientHandles1, ServerHandlesOut, ErrorsOut '初始化OCP连接MyOPCGroupOut.IsSubscribed = TrueEnd IfIf ReadItemIdex > 0 ThenMyOPCItemCollIn.AddItems ReadItemIdex, WatchDataReadItem, ClientHandles1, ServerHandlesIn, ErrorsIn '初始化OCP连接MyOPCGroupIn.IsSubscribed = TrueEnd IfExit SubHANDLEeRROR:needOPCRestart = TruexLog1.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 NumItemsWatchDataWriteValue(ClientHandles(ii) - 1) = ItemValues(ii) '对改变的值读入本数组Next iiEnd Sub对OPC的写可以有同步与异步之分,对于大量的数据传输,异步是更佳的选择,但对少量的数据传输,同步表现得更好。
要进行数据传输,先要将值数据进行赋值,注意:值数据要由0开始,也就是说,值数组与标签数据不是一、一对应,值要比标签前一位,这一点,在WINCC说明中没有,但在我的实际的使用中一直要这样,不然数据就产生错位,看下面程序。
这是一个拔号完毕后返回的数据进行OPC传递的程序。
包含解包过程,Private Sub showSuccess(msg As String)Dim location As StringDim nowTime As StringDim logStr As StringDim Value() As StringDim ii, temp As IntegerDim isPack As BooleanDim sHead, sDelimited, sTail As Stringlocation = xProfile.GetValue(WatchPoint(nowRunID), "LOCATION")nowTime = NowlogStr = "拔" & location & "取数成功" & msgxLog1.log logStrlogStr = " " & msgxLog2.log logStr '记录数据'数据上传'如果有包结构,则显示包结构,isPack = xProfile.GetValue(WatchPoint(nowRunID), "ISRECHEAD")If WatchPointRBegin(nowRunID) < 0 Then Exit SubIf isPack ThensHead = xProfile.GetValue(WatchPoint(nowRunID), "RECHEAD")sDelimited = xProfile.GetValue(WatchPoint(nowRunID), "RECDELIMITER")sTail = xProfile.GetValue(WatchPoint(nowRunID), "RECEND")V alue = Split(msg, sDelimited)For ii = 0 To UBound(Value) - 1temp = WatchPointRBegin(nowRunID) + iiIf temp > WatchPointREnd(nowRunID) Then Exit ForWatchDataReadValue(temp - 1) = Value(ii + 1) 'V ALUE要从0开始,比ITEM少1,所以减一。