软件课程设计报告.docx
《软件课程设计报告.docx》由会员分享,可在线阅读,更多相关《软件课程设计报告.docx(23页珍藏版)》请在冰豆网上搜索。
软件课程设计报告
软件设计课程设计报告
班级:
姓名:
学号:
同组成员:
2010年12月
课设名称OPC客户端的编程
一、课设目的:
通过对课程设计的实际操作进一步了解OPC的各种概念,掌握OPC客户端的编写方法。
并对微软的DCOM有一定的了解,要求通过合适的DCOM配置,使客户端能够读取网络上服务器中的数据。
二、课设内容:
1)利用VB语言编写出一个简单的OPC客户端程序,要求这个客户端能够读取服务器中的数据,并显示出来。
2)配置DCOM,使客户端能够能过DCOM读取另一台服务器上的数据。
三、课设步骤:
(一)运行环境的设置
本步骤的主要内容是设置用VB开发的应用程序计算机运行环境。
主要是就OPC服务器和OPC客户应用程序分别在不同的计算机上运行的远程连接形式,说明OPC运行环境的设置方法。
OPC服务器和OPC客户应用程序在相同的计算机上运行的本地连接形式形态,几乎使用分布式COM的默认设置就可以运行,或者参考下面介绍的远程连接设置方法,将OPC服务器的设置和OPC客户应用程序的设置在同一台计算机上也可以解决问题。
操作系统不同,DCOM的配置方法也稍有不同。
下面介绍Windows2000/NTDCOM及其windowsXP系统的环境配置的步骤:
1)Windows2000/NTDCOM设置
首先运行DCOMCNFG进入DCOM配置程序
设置默认属性为以下设置
设置默认安全机制
设置默认访问权限如下,即加入Everyone允许访问
设置默认启动权限如下,即加入Everyone允许调用
设置引用程序OpcEnum属性
安全性设置如下
身份标识设置如下
然后设置OPC服务器程序,实际应用过程中服务器的注册信息是不同的,本例的OPC服务器为kingview.view,其设置与OpcEnum相同。
客户端设置默认安全设置,设置同服务器4、5、6步骤。
客户端登录的用户必须是服务器中合法的用户。
例如在服务其中包括aaaa用户,客户端可以以aaaa用户登录而且密码与服务器中aaaa用户的密码相同就可以访问访问服务器了。
如果经过以上各步还有问题,那么让客户端和服务器以相同用户名和口令登录,一定可以正确连接.
1)windowsXP系统设置
首先需要关闭SP2的防火墙,具体可由开始——>控制面板——>安全中心——>windows防火墙——>关闭
接着,按以下步骤配置DCOM
点击开始——>运行,再输入DCOMCNFG,如下图
点确定,进入XP的DCOM配置界面:
再依次选择组件服务——>计算机——>我的电脑——>属性
进入我的电脑属性界面,之后选择COM安全页:
首先选择访问权限,编辑限制,从中加入everyone,并将本地连接与远程连接前的复选框都选上
同样,再选择启动激活权限编辑限制,并接下图配置:
然后点击确定,则XP的DCOM就已经配置完成。
(二)VB编程及实现
(1)建立一个VisualBasic工程
1)启动VisualBasic,新建一个VisualBasic工程。
图1VisualBasic工程的建立
2)设置OPC包装DLL
因为在新建的VisualBasic工程OPC包装DLL还没有被注册,必须用下述方法对OPC包装DLL进行注册。
设置方法:
1.从VisualBasic菜单里选择[Project]-[References]。
2.在[AvailableReferences]表示中,选择对应OPC包装DLL的文件名。
这里我们选择[OPCAutomation2.0]。
图2引用的设置
(2)建立一个OPC对象
在VisualBasic里,是以对象的单位对OPC服务器进行访问。
OPC自动化接口是由以下四种对象所定义。
OPC服务器
OPC组(OPC组集合)
OPC标签(OPC标签集合)
OPC浏览器
这里只说明OPC服务器,OPC组以及OPC标签对象的使用方法。
具体的来说,先连接一个特定的OPC服务器,然后建立OPC组,最后添加OPC标签。
1)变量声明
参考图3-3所示的示范代码,先对OPC对象变量进行声明。
变量的数据类型应该指定为对象型。
这些对象变量最好在窗体代码的(General)部分声明。
因为在(General)部分声明的变量,可以在窗体的任何方法的代码内引用。
变量申明中定义整型数据n用于做出温度和液位变化曲线。
表1OPC对象变量的声明
OptionBase1
OptionExplicit
DimWithEventsobjServerAsOPCServer
DimobjGroupsAsOPCGroups
DimobjTestGrpAsOPCGroup
DimobjItemsAsOPCItems
DimnAsInteger'定义新的变量n,用于画出反应罐温度和液位变化曲线
DimlServerHandles()AsLong
有关定义OPC对象的声明及其说明列于表3-1
表2OPC对象变量的声明
变量名
说明
objServer
OPCServer对象,用于连接OPC服务器。
objGroups
OPCGroups对象,用于添加OPC组的OPC组集合
objTestGrp
OPCGroup对象,演示用的OPC组。
objItems
OPCItems对象,用于添加OPC标签的OPC标签集合。
lServerHandles()
长整型的数组,用于保存OPC标签的服务器句柄。
2)连接OPC服务器和建立OPC组
下面说明如何连接OPC服务器和建立OPC组。
考虑到代码的可反复使用性,这里采用子程序进行编程。
这里用“NEW”关键词生成OPC服务器的对象,然后调用OPC服务器对象的“Connect”方法,和OPC服务器连接。
在连接远程服务器的时候,需要指定作为选用参数的远程计算机名(表3)
表3Connect子程序
SubConnect(strProgIDAsString,OptionalstrNodeAsString)
IfobjServerIsNothingThen
'建立一个OPC服务器对象
SetobjServer=NewOPCServer
EndIf
IfobjServer.ServerState=OPCDisconnectedThen
'连接OPC服务器
objServer.ConnectstrProgID,strNode
EndIf
IfobjGroupsIsNothingThen
'建立一个OPC组集合
SetobjGroups=objServer.OPCGroups
EndIf
IfobjTestGrpIsNothingThen
'添加一个OPC组
SetobjTestGrp=objGroups.Add("TestGrp")
EndIf
EndSub
3)添加OPC标签
对OPC服务器进行访问前,必须先在OPC组里添加要访问的OPC标签。
这里添加OPC标签的标识符和数目是固定的,但是实际的OPC应用程序往往要按照用户的指定或读取组态文件取得和处理需要添加OPC标签(表4)
表4AddItem子程序
SubAddItem()
DimstrItemIDs
(2)AsString
DimlClientHandles
(2)AsLong
DimlErrors()AsLong
DimIAsInteger
IfobjTestGrpIsNothingThen
ExitSub
EndIf
IfNotobjItemsIsNothingThen
IfobjItems.Count>0Then
ExitSub
EndIf
EndIf
'设置组活动状态
objTestGrp.IsActive=True
'取消组非同期通知
objTestGrp.IsSubscribed=False
'建立OPC项集合
SetobjItems=objTestGrp.OPCItems
'生成标签的项标识符
strItemIDs
(1)="反应罐温度.Value"
strItemIDs
(2)="反应罐液位.Value"
lClientHandles
(1)=1
lClientHandles
(2)=2
'添加OPC项
CallobjItems.AddItems(2,strItemIDs,_
lClientHandles,lServerHandles,lErrors)
EndSub
4)断开OPC服务器
连接着OPC服务器的OPC应用程序,在退出前必须断开和OPC服务器的连接(表5)。
因为OPC服务器并不知道OPC应用程序已经退出,如果不先断开连接,那么OPC服务器所使用的计算机资源就不被释放。
如果这样的问题反复发生,久而久之,连续运转的自动控制系统可能会使计算机资源渐渐枯竭从而发生严重问题。
表5Disconnect子程序
SubDisconnect()
DimlErrors()AsLong
IfNotobjItemsIsNothingThen
IfobjItems.Count>0Then
'清除OPC项
objItems.Remove2,lServerHandles,lErrors
EndIf
SetobjItems=Nothing
EndIf
IfNotobjTestGrpIsNothingThen
'清除OPC组
objGroups.Remove"TestGrp"
SetobjTestGrp=Nothing
EndIf
IfNotobjGroupsIsNothingThen
SetobjGroups=Nothing
EndIf
IfNotobjServerIsNothingThen
IfobjServer.ServerState<>OPCDisconnectedThen
'断开OPC服务器.
objServer.Disconnect
EndIf
SetobjServer=Nothing
EndIf
EndSub
(3)同步数据读写
到此为止,我们已经基本说明了OPC对象。
现在,让我们制作一个实际的OPC数据访问应用程序。
我们采用同步方式的数据访问。
1)窗体设计
让我们制做如图3所示窗体的OPC应用程序。
图3窗体设计
这个程序读取2点的数据,并用棒图表示读取的数据。
棒图的更新周期为0.1s(100ms),使用定时器以0.1秒的周期对OPC服务器进行同期数据读取。
并且假定规定温度上限为150,液位上限为600。
窗体中所使用的控件种类如表6所示
表6OPC_zj的控件表
控件
名称
窗体(Form)
OPC_zj
命令按钮(CommandButton)
zjConnect
命令按钮(CommandButton)
zjAddItem
命令按钮(CommandButton)
zjQuit
命令按钮(CommandButton)
zjStop
定时器(Timer)
zjTmUpdate
图像(PictureBox)
picBar(作为数组使用,从左开始1~2)
图像(PictureBox)
Picture1(作为数组使用,从左开始1~2)
标签(Label)
lbBar(作为数组使用。
从左开如1~2)
标签(Label)
Label1(反应罐温度)
标签(Label)
Label2(反应罐液位)
标签(Label)
Label3(显示即时日期)
标签(Label)
Label4(显示即时时间)
标签(Label)
Label5(显示反应罐温度变化趋势)
标签(Label)
Label6(显示反应罐液位变化趋势)
标签(Label)
Label7(显示反应罐温度情况)
标签(Label)
Label8(显示反应罐液位情况)
2)命令按钮的事件
当按下在窗体上的命令按钮的事件发生时,通过调用在第一部分说明的各种方法对发生的事件进行处理(表7,表8,表9,表10)
表7zjConnect命令按钮的单击事件处理
PrivateSubzjConnect_Click()
'调用Connect子程序
CallConnect("kingview.view.1","192.168.0.1")
EndSub
表8zjAddItem命令按钮的单击事件处理
PrivateSubzjAddItem_Click()
'调用AddItem子程序
CallAddItem
IfNotobjTestGrpIsNothingThen
IfobjTestGrp.OPCItems.Count>0Then
'启动定时器
tmUpdate.Enabled=True
Else
EndIf
EndIf
EndSub
表9zjQuit命令按钮的单击事件处理
PrivateSubzjQuit_Click()
'卸载窗体
UnloadOPC_zj
EndSub
表10zjStop命令按钮的单击事件处理
PrivateSubzjStop_Click()
IfzjtmUpdate.Enabled=FalseThen
CallAddItem'调用AddItem子程序
IfNotobjTestGrpIsNothingThen
IfobjTestGrp.OPCItems.Count>0Then
'启动定时器
zjtmUpdate.Enabled=True
Else
EndIf
EndIf
Else
zjtmUpdate.Enabled=False
EndIf
EndSub
为了在中止应用程序时断开和OPC服务器的连接,在窗体的Unload事件处理中调用了断开OPC服务器连接子程序(表11)
表11OPC_zj窗体的卸载事件处理
PrivateSubForm_Unload(CancelAsInteger)
'调用Disconnect子程序
CallDisconnect
EndSub
为了在操作界面上同步显示日期和时间,定义方法zjdate,并且在同步读取数据过程中进行调用以便实时更新,显示时间代码如表12所示。
表12方法zjdate的定义处理
'日期时间显示方法
Subzjdate()
Label3.Caption=Trim(Str(Year(Date)))+"年"+Trim(Str(Month(Date)))+"月"_
+Trim(Str(Day(Date)))+"日"
Label4.Caption="现在时间:
"+Trim(Str(Hour(Time)))+"时"+Trim(Str(Minute(Time)))_
+"分"+Trim(Str(Second(Time)))+"秒"
EndSub
3)同步数据读取
在本示范程序中是利用定时器事件进行数据更新的显示。
这时所有的数据是采用同步方式对OPC服务器进行读取的。
表13是定时器事件处理以及同步读取处理的代码。
表13zjtmUpdate定时器的定时事件处理
PrivateSubzjtmUpdate_Timer()
DimvtItemValues()AsVariant
DimlErrors()AsLong
DimstrBufAsString
DimnWidthAsInteger
DimnHeightAsInteger
DimnDrawHeightAsInteger
DimsglScaleAsSingle
DimIAsInteger
'同期读取
SyncReadOPCCache,vtItemValues,lErrors
'棒图的表示
ForI=1To2
'数据的格式化
strBuf=Format(vtItemValues(I),"###.000")
'表示数据字符串
lbBar(I).Caption=strBuf
'计算棒的宽和高
nWidth=picBar(I).ScaleWidth
nHeight=picBar(I).ScaleHeight
sglScale=vtItemValues(I)/800
nDrawHeight=CInt(nHeight*sglScale)
'清除现棒图
picBar(I).Cls
'绘制棒图
picBar(I).Line(0,nHeight-nDrawHeight)-(nWidth,nHeight),_
RGB(0,255,0),BF
'绘制温度和液位的变化曲线
n=n+1
Picture1(I).Line(n-1,nHeight-nDrawHeight)-(n-1,nHeight),_
RGB(0,0,255)
'判断反应罐温度和液位正常情况
IfvtItemValues
(1)>150Then
Label7.Caption="温度过高!
"
Else
Label7.Caption="温度正常!
"
EndIf
IfvtItemValues
(2)>600Then
Label8.Caption="液位过高!
"
Else
Label8.Caption="液位正常!
"
EndIf
Next
EndSub
定时器事件处理内调用的“SyncRead”子程序如表14所示。
再有在读取前为了避免错误发生,对OPC组和OPC标签进行检查。
表14SyncRead子程序
SubSyncRead(nSourceAsInteger,ByRefvtItemValues()AsVariant,_
ByReflErrors()AsLong)
DimlServerHandlesTemp
(2)AsLong
DimjAsInteger
IfobjTestGrpIsNothingThen
ExitSub
EndIf
'调用日期和时间显示方法
Callzjdate
IfobjTestGrp.OPCItems.Count>0Then
'同期读取
objTestGrp.SyncReadnSource,2,lServerHandles,_
vtItemValues,lErrors
EndIf
EndSub
在窗体开始加载时对定时器进行初始化,如表15所示
表15窗体载入时定时器的初始化
PrivateSubForm_Load()
zjtmUpdate.Enabled=False
zjtmUpdate.Interval=100
'初始化n
n=0
EndSub
至此,窗体上的各项控件所对应的事件及方法全部定义完毕,通过连接OPC并读取服务器数据,可以实现对所取数据的其他操作.
四、运行结果
经过上述的计算机环境设置、窗体设计和代码编写,整个设计过程便已完成了,经调试无误后便可以观察运行结果,基于自己的设计功能,可以从窗体界面读取当前日期和时间,时刻观察到反应罐温度和液位数据大小及其相应的变化趋势,并且能够观察到温度和液位是否超过了规定的上限,其运行结果如下图所示:
图4温度和液位正常的情况
图5温度和液位过高的情况
5、课设总结及心得
本次软件课程设计让我们进一步通过实际操作熟悉对OPC的各种概念,并且掌握OPC客户端的编写方法,由于设计前老师已经提供了课设范例,经过对所提供的范例进行分析和研究,我们对课程设计的步骤和重点都有了更好的了解,在老师所给的源程序的基础上进行改进,这使我们对OPC客户端的编程有了一定的了解,并且更加熟悉和掌握了VisualBasic这种编程语言,经过计算机环境的设置,对微软的DCOM有一定的了解,虽然实验室中的所有机子都是已经配置好了的,但是仍然了解了其配置的重要性。
在实验过程中我们的确遇到过一些困难,但是我们努力去图书馆努力查找资料,并且在老师和同学的帮助都顺利解决了难题,得到了自己想要的结果。
本次课程设计极大地锻炼了我的动手能力,让我进一步学会了用理论联系实际的解决问题的方法,为进一步学习网络及服务器相关内容打下了坚实的基础,获益匪浅。