为了方便用户使用组态王OPCSERVER的功能,对组态王的实时数据进行访问,组态王提供了KINGVEWCLIEN.dll供用户进行使用,方便了用户的编程。此接口可以支持VB、VC、DELPHI(未进行测试)访问。提供的接口如下:intStartCliend(char*node);//与组态王OPCSERVER建立连接//返回错误码intReadItemNo();//得到组态王OPC中列出的项目总数//返回组态王OPC中列出的项目总数intGetItemNames(char*sName,WORDIndex);//得到某个项目的名称//返回错误码,sName将返回组态王的项目的名称,wItemId为用户写入的其要取的变量的索引号//其为ReadItemNo返回的范围内的某个数(0Index=ReadItemNo())intAddTag(BSTRsRegName,WORD*TagId,WORD*TagDataType);//将某个项目添加如采集列中//返回错误码,sRegName是要加入采集的项目名称,TagId项目采集的标识号,TagDataType项目的数据类型intWriteTag(WORDTagId,BOOLbVal,longlVal,floatfVal,char*sVal);//返回错误码,TagId为要采集项目的标识号,其他为设定的数值,用户将根据变量的类型设定数值intReadTag(WORDTagId,BOOL*bVal,long*lVal,float*fVal,char*sVal);//返回错误码,TagId为要采集的变量的表示号,其他为返回的数值,用户将根据变量的类型读取intStopCliend();//断开与组态王OPC的连接//返回错误码////////////////////////////////////////////////////////////////////////////////////错误码列表//0成功//-1OPCSERVER已经被非法关闭//-2找不道OPCSERVER的PROGID//-3连接OPCSERVER不成功//-4枚举ITEMS错误//-5OPCSERVER没有定义ITEMS//-6内存分配错误//-7在向GROUP中加入ITEMS时出现错误//-8未使用//-9读ITEMS时出现错误//-10不能识别的数据类型//-11读ITEMS的质量戳时出现错误//-12想ITEMS中写入数据时出现错误//-13用户添加变量的变量名错误//-14用户读取的变量序号越界使用方法:以上提供的函数,在整个的调用的过程中有相应的次序和功能,用户需要先调用STARTCLIEND函数,启动与组态王的连接,用户可以通过此函数的NODE参数,来控制与哪台计算机的组态王进行连接。如用户不知道应该读取的项目在组态王中的表现形式,用户可以通过调用READITEMNO函数,然后通过返回的数目,依次调用GETITEMNAMES得到项目的名称。如用户已经知道了要读取的变量名称,用户可以通过以下方法合成项目名称,因为组态王的OPC服务器对外部暴露的项目支持到域,用户可以使用组态王变量名称+”.”+域名称,如变量名为锅炉温度,如果用户需要读取他的值,用户合成项目名称是锅炉温度.Value,Value是变量的数值域。当用户合成了要采集的项目名称后,用户得调用ADDTAG函数将要采集的项目添加到采集的列表中,用户必须进行次操作,否则不能进行项目的采集。当用户调用此函数后,函数将返回项目在采集列表中的位置(TAGID),和项目的数据类型(TagDataType),用户将根据返回的信息进行采集。用户添加完成采集项目列表后,可以通过调用READTAG和WRITETAG来对项目进行读写,其参数中TAGID是通过ADDTAG得到的项目的位置号,后面的四个变量是项目的数值,用户根据项目的数据类型,得到或者写入项目的数值。用户在程序退出之前,将调用STOPCLIEND函数,挂断与组态王的连接。OPC通信遵循于服务器---客户端式的基本结构。也就是说,OPC服务器和客户端是构成OPC通信的基本要素,也是OPC通信发生的必要条件。OPC服务器之间不能直接对话,OPC客户端之间也不能,除非借助于其他OPC工具或产品(比如MatrikonOPCDataManager,它可以实现两个OPC服务器之间的通信)。用VB开发OPC客户端程序的步骤与实现(1)建立新工程或项目,在“工程”菜单下选择“引用”,如图5-3所示。只有引用OPCDAAuoto.DLL后,在程序中才能创建服务器对象,然后进行一系列的操作。(2)在弹出的引用窗口里单击“浏览(B)…”按钮,弹出添加引用窗口,选择OPCDAAuoto.DLL文件。(3)在引用窗口里的OPCAutomation2.0前面打钩,按“确定”按钮。(4)定义全局变量,这样可以在窗体的任何方法的代码内应用。变量类型应该指定为对象型。这些对象最好在窗体的通用部分声明加上“OptionExplicit”语句,表示模块里的所有变量都需要显式声明。由于OPC自动化接口的数组的索引要求必须从1开始,而系统默认是从0开始,为了避免错误最好在代码的最初加上“OptionBase1”语句。为了使对象可以处理事件,必须将objTestGrp和objServer的声明中加上“WithEvents”语句,表示声明的对象可以响应事件。OptionExplicitOptionBase1DimWithEventsobjServerAsOPCServerDimobjGroupsAsOPCGroupsDimWithEventsobjTestGrpAsOPCGroupDimobjItemsAsOPCItems(5)连接OPC服务器和建立OPC组考虑到代码的可反复使用性,采用子程序进行编程。SubConnect(strProgIDAsString,OptionalstrNodeAsString)IfobjServerIsNothingThen'建立一个OPC服务器对象SetobjServer=NewOPCServerEndIf服务器状态ServerState属性一共有OPCRunning、OPCFailed、OPCNoconfig、OPCSuspended、OPCTest和OPCDisconnected六个值,分别表示正在运行、失败、没有配置、暂停、测试和没有连接六种OPC服务器当前的状态。如果OPC服务器没有连接,我们才执行objServer.ConnectstrProgID,strNode语句。strProgID就是ProgID,strNode就是用于远程通信的IP地址。IfobjServer.ServerState=OPCDisconnectedThen'连接OPC服务器objServer.ConnectstrProgID,strNodeEndIf在VisualBasic中,通过执行一个Set操作实现调用其它接口的方法。IfobjGroupsIsNothingThen'建立一个OPC组集合SetobjGroups=objServer.OPCGroupsEndIfIfobjTestGrpIsNothingThen'添加一个OPC组SetobjTestGrp=objGroups.Add(Group)EndIfEndSub(6)添加OPC标签对服务器进行访问前,必须先在OPC组里添加要访问的OPC标签。OPC客户端程序要按照用户指定的标签或者从组态文件里读取需要添加的OPC标签。SubAddItem()DimstrItemIDs(17)AsStringDimlClientHandles(17)AsLongDimlErrors()AsLongDimIAsIntegerIfobjTestGrpIsNothingThenExitSubEndIfIfNotobjItemsIsNothingThenIfobjItems.Count0ThenExitSubEndIfEndIf'设置组活动状态。只有处于活动状态的OPC才进行定期的数据更新。非活动状态的OPC组,除了在接到显然的数据读写要求外,并不收集任何数据。IfmnuSubscribtion.Checked=TrueThenobjTestGrp.IsActive=TrueElseobjTestGrp.IsActive=FalseEndIf'启动组异步通知。进行订阅的OPC组可以自动收到从服务器送来的数据变化通知。objTestGrp.IsSubscribed=True'建立OPC项集合SetobjItems=objTestGrp.OPCItems'生成从TAG1到TAG17的项标识符ForI=1To17strItemIDs(I)=Server.Group.TAG&IlClientHandles(I)=INext'添加OPC项CallobjItems.AddItems(17,strItemIDs,lClientHandles,lServerHandles,lErrors)EndSub(7)异步读取代码的实现在定时器事件内进行执行AsyncRead子程序的读取代码,而在读取完成事件处理返回的数据访问结果。SubAsyncRead()DimlErrors()AsLongIfobjTestGrpIsNothingThenExitSubEndIfIfobjTestGrp.OPCItems.Count0Then'异步读取lTransID_Rd=lTransID_Rd+1objTestGrp.AsyncRead17,lServerHandles,lErrors,lTransID_Rd,lCancelID_RdEndIfEndSubPrivateSubobjTestGrp_AsyncReadComplete(_ByValTransactionIDAsLong,ByValNumItemsAsLong,_ClientHandles()AsLong,ItemValues()AsVariant,_Qualities()AsLong,TimeStamps()AsDate,Errors()AsLong)……Sub(8)在按钮中执行AsyncWrite子程序,完成异步写的操作。SubAsyncWrite(nIndexAsInteger,ByRefvtItemValues()AsVariant,_ByReflErrors()AsLong)DimlHandle(1)AsLongIfobjTestGrpIsNothingThenExitSubEndIfIfobjTestGrp.OPCItems.Count0ThenlHandle(1)=lServerHandles(nIndex)'异步写入lTransID_Wt=lTransID_Wt+1objTestGrp.AsyncWrite1,lHandle(),vtItemValues,_lErrors,lTransID_Wt,lCancelID_WtEndIfEndSub(9)断开OPC服务器连接着OPC服务器的OPC客户应用程序,在退出前必须断开和OPC服务器的连接。因为OPC服务器并不知道OPC客户应用程序的退出。如果不先断开连接,那么OPC服务器使用的计算机资源就不会被释放。如果这样的问题反复发生,久而久之,连续运转的自动控制系统可能会计算机资源渐渐枯竭从而发生严重问题,可以显式地把它设置为“Nothing”。SubDisconnect()DimlErrors()AsLongIfNotobjItemsIsNothingThenIfobjItems.Count0ThenobjItems.Remove17,lServerHandles,lErrors'清除OPC项EndIfSetobjItems=NothingEndIfIfNotobjTestGrpIsNothingThenobjGroups.RemoveGroup'清除OPC组SetobjTestGrp=Not