OPC工具箱作OPC客户端的应用研究.docx
《OPC工具箱作OPC客户端的应用研究.docx》由会员分享,可在线阅读,更多相关《OPC工具箱作OPC客户端的应用研究.docx(18页珍藏版)》请在冰豆网上搜索。
![OPC工具箱作OPC客户端的应用研究.docx](https://file1.bdocx.com/fileroot1/2022-11/27/15944416-11a3-45bd-9067-3717f775633e/15944416-11a3-45bd-9067-3717f775633e1.gif)
OPC工具箱作OPC客户端的应用研究
OPC工具箱作OPC客户端的应用研究
邹绍云
武汉理工大学湖北武汉430063
e-mail:
Zoushaoyun123@
摘要
本文分析了OPC工具箱的工作原理,并利用OPC工具箱实现对OPC服务器包含项的值的读写操作。
关键字:
MATLABOPC服务器OPC工具箱
Abstract
ThispaperanalyzestheworkingprincipleofOPCToolbox,andachievesreadingfromorwritingtoOPCserver.
KeyWords:
MATLABOPCServerOPCToolbox
绪论
OPC工具箱扩展了MATLAB工具箱仿真功能,使MATLAB能够和OPC服务器相互交换数据。
OPC工具箱可以从符合OPC基金会数据存取标准的设备中读、写、记录OPC数据,如分布式控制系统、监督控制系统和数据采集系统,以及可编程逻辑控制器(PLC)。
OPC工具箱使MATLAB和仿真器(Simulink)相应OPC服务器或工具箱初始化事件,如关机、服务器错误或项值改变。
化学、制药、发电及其它连续制造工业的工程师应用OPC工具箱输入设备数据到MATLAB里进行分析、可视化、仿真和快速原形算法。
OPC工具箱使仿真模型能方便地应用于在线监控软件和控制器测试软件。
本次仿真采用KEPWare.KEPServerEx.V4作为OPC服务器,模拟从编程逻辑控制器(PLC)读取和写入数据,并通过返回的数据绘出图形。
1OPC通讯技术简介
OPC(用于过程控制的OLE)规范是由OPC基金会建立的硬件和软件接口标准,它基于现有的OLE、组件对象模型COM(ComponentObjectModel)和分布式组件对象模型DCOM(DistributedCOM)技术,已得到越来越多的硬件和软件制造商的承认和支持,成为事实上的国际标准。
[1]OPC通讯技术免去了硬件生产厂家为各种应用软件编写单独的驱动程序的重复劳动,使各种软、硬件组成的复杂系统能够可靠地交换数据并稳定地运行。
OPC采用客户端/服务器结构。
OPC通讯包含三类对象:
服务器(Server)、组(Group)和数据项(Item),其层次模型如图1所示。
图1OPC对象层次模型
2OPC工具箱的基本工作原理
(1)搜索可用的OPC服务器
为了建立与OPC服务器的连接,首先要知道OPC服务器的ID及其所在的主机名。
1)在本地计算机上查询所有可用的OPC服务器。
hostInfo=opcserverinfo('localhost')
得到结果如下:
hostInfo=
Host:
'localhost'
ServerID:
{1x4cell}
ServerDescription:
{1x4cell}
OPCSpecification:
{'DA2''DA2''DA2''DA2'}
ObjectConstructor:
{1x4cell}
其中,Host:
'localhost'表明搜索到的OPC服务器在本地计算机上;ServerID:
{1x4cell}表明在本地计算机上搜索到四个OPC服务器。
四个OPC服务器所遵循的OPC规范都是DA2.0。
ObjectConstructor是指四个OPC服务器的制造商。
2)验证返回的OPC详细信息:
将OPC服务器ID信息赋值给allSevers数组
allServers=hostInfo.ServerID'
执行结果如下:
allServers=
'Matrikon.OPC.TI5.1'
'KEPware.KEPServerEx.V4'
'Takebishi.Melsec.1'
'OPC.SimaticHMI.HmiRTm.1'
本次仿真所用的OPC服务器是'KEPware.KEPServerEx.V4'。
(2)创建一个OPC数据访问客户端对象
获得主机名称和OPC服务器ID后与OPC服务器进行连接,需要创建一个与服务器相对应的opcda(OPC数据访问)对象,其代码如下:
da=opcda('localhost','KEPware.KEPServerEx.V4')
这样就建立了一个与KEPware.KEPServerEx.V4对应的OPC数据访问对象。
da=
SummaryofOPCDataAccessClientObject:
localhost/KEPware.KEPServerEx.V4
ServerParameters
Host:
localhost
ServerID:
KEPware.KEPServerEx.V4
Status:
disconnected
Timeout:
10seconds
从上面执行结果可以看到Status:
disconnected,也就是还没有与OPC服务器建立连接。
(3)建立MATLAB与指定OPC服务器之间的连接
1)连接服务器
connect(da)
2)显示客户端信息,确认客户端已经建立了连接
da
执行结果如下:
SummaryofOPCDataAccessClientObject:
localhost/KEPware.KEPServerEx.V4
ServerParameters
Host:
localhost
ServerID:
KEPware.KEPServerEx.V4
Status:
connected
Timeout:
10seconds
ObjectParameters
Group:
0-by-1dagroupobject
EventLog:
0of1000events
从执行结果Status:
connected可以看出,OPC客户端,也就是matlab与服务器建立了连接。
(4)浏览服务器的命名空间
1)依据KEPware.KEPServerEx.V4服务器中已经存在的项,通过部分匹配查找出所有需要的OPC项。
KepItems=serveritems(da,'*Channel_1.Device_1.Tag*')
执行结果如下:
KepItems=
'Channel_1.Device_1.Tag_1'
'Channel_1.Device_1.Tag_2'
'Channel_1.Device_1.Tag_3'
执行结果显示了所有包含Channel_1.Device_1.Tag字符串的OPC变量。
2)将需要的OPC项名存储到数组itmIDs中
itmIDs={'Channel_1.Device_1.Tag1',…
'Channel_1.Device_1.Tag2',…
'Channel_1.Device_1.Tag3};
本次仿真的三个项模拟PLC的模拟量,是整型数据。
(5)创建一个OPC数据访问组对象
grp=addgroup(da,'Group1')
(6)将项添加到组对象中
创建组后才能够添加项,下面将步骤四中定义的项(itmIDs)全部添加到创建的组对象(grp)中。
itmCollection=additem(grp,itmIDs)
执行后itmCollection数组中存放着Group1中所有项的集合。
(7)配置OPC工具箱的属性
用SET命令配置OPC工具箱的属性,用GET命令取回其属性。
下面的代码是在两分钟内,每隔0.2秒登入一次数据,numRecords是登入数据的次数。
logDuration=2*60;
logRate=0.2;
numRecords=ceil(logDuration./logRate)
配置组对象属性,使其能获取所有的数据。
set(grp,'UpdateRate',logRate,'RecordsToAcquire',numRecords);
(8)从OPC服务器中获取数据
调用START函数获取数据。
为了在程序继续往下执行前得到所有的数据,调用WAIT函数。
start(grp)
wait(grp)
上面语句执行后,数据都登入到了内存里面,需要从OPC工具箱引擎里取回。
因为读取上来的数据是时间序列数据,需要将读取上来的数据存储到各个独立的数组中。
[logIDs,logVal,logQual,logTime,logEvtTime]=getdata(grp,'double');
查看工作区间中各个数据的大小
whoslog*
(9)绘制数据图形
下列代码将数据图形绘制在一条坐标轴上,数据格式标记(DATETICK)函数将X轴标记转换成格式化数据字符串。
plot(logTime,logVal);
axistight
datetick('x','keeplimits')
legend(logIDs)
图1模拟量数据绘制结果
上图注释框控标出红线是Tag1的数据值变化曲线,绿线是Tag2的数据值变化曲线,蓝线是Tag3的数据值变化曲线。
通过上图尚不能判断所得数据的品质,所以通过下面的一段代码将品质不好的数据点用红色标出,品质不确定的数据用橙色标出。
holdon
isBadQual=strncmp(logQual,'Bad',3);
isRepeatQual=strncmp(logQual,'Repeat',6);
fork=1:
size(logQual,2)
badInd=isBadQual(:
k);
plot(logTime(badInd,k),logVal(badInd,k),'ro',...
'MarkerFaceColor','r','MarkerEdgeColor','k')
repInd=isRepeatQual(:
k);
plot(logTime(repInd,k),logVal(repInd,k),'ro',...
'MarkerFaceColor',[0.80.50],'MarkerEdgeColor','k')
end
holdoff
图2数据品质标志结果
由于所有的数据品质良好,所以没有显示标识红点或橙色点。
(10)清除
结束OPC工具箱对象后必须将其从OPC工具箱引擎中删除,并自动删除组对象和项对象。
disconnect(da)
delete(da)
清除组对象
isvalid(grp)
从工作区间清除项的集合
cleardagrpitmCollection
以上分析的是MATLAB从OPC服务器读取某个组中所有项的字段值,并用图形显示ItemID、Value、Quality、TimeStamp的全过程,及其使用的底层代码的分析。
其M文件代码见附录1。
3.OPC工具箱的数据交换
3.1同步读写
用OPC工具箱的同步读写操作与OPC服务器交换数据。
(1)与OPC服务器建立连接并建立相关对象
da=opcda('localhost','KEPware.KEPServerEx.V4');
connect(da);
grp=addgroup(da,'Group1');
itmIDs={'Channel_1.Device_1.Tag_1',...
'Channel_1.Device_1.Tag_2',...
'Channel_1.Device_1.Tag_3'};
itmCollection=additem(grp,itmIDs);
(2)执行同步读操作
默认读操作从OPC服务器的高速缓存中获取数据。
1)读一个值
r=read(itmCollection
(1))
执行结果如下:
r=
ItemID:
'Channel_1.Device_1.Tag_1'
Value:
1004
Quality:
'Good:
Non-specific'
TimeStamp:
[2010611184539.4680]
Error:
''
2)读全部值
r=read(itmCollection)
执行结果如下:
r=
3x1structarraywithfields:
ItemID
Value
Quality
TimeStamp
Error
查看项的具体数值
r
(1).Value
执行结果为:
ans=
3305
当OPC服务器在网络上或不在本地上时,从设备读取数据将花费更多的时间。
从设备被读取数据时,要将数据源指定为’device’。
r=read(itm1,'device')
(3)执行同步写操作
1)给一个项赋值0
write(itmCollection
(1),0)
再将数据读取回来
r=read(itmCollection
(1))
执行结果:
r=
ItemID:
'Channel_1.Device_1.Tag_1'
Value:
6
Quality:
'Good:
Non-specific'
TimeStamp:
[201061184933.4060]
Error:
''
从执行结果可以看到其Value值由3350这样的大数值变成了6,这是因为这个项的值是自动线性增长,当写入值0再读回来的间隙增长到6了,但是仍可判断出写操作是成功执行了的。
2)给多个项赋值
write(itmCollection,{0,0,0})
(4)清除
disconnect(da)
delete(da)
cleardagrpitmCollection
3.2从OPC服务器采集数据
(1)创建OPC工具箱对象层次结构
da=opcda('localhost','KEPware.KEPServerEx.V4');
connect(da);
itmIDs={'Channel_1.Device_1.Tag_1',...
'Channel_1.Device_1.Tag_2',...
'Channel_1.Device_1.Tag_3'};
grp=addgroup(da,'Group1');
itmCollection=additem(grp,itmIDs);
(2)配置数据采集持续时间
Set(grp,’UpdateRate’,0.2);
Set(grp,’RecordsToAcquire’,40);
(3)配置数据采集目标
数据被采集到磁盘和内存。
磁盘文件名是LoggingExample.olf,如果该文件名已存在,那么该文件原有的数据会被OPC工具箱引擎采集上来的数据覆盖。
set(grp,'LoggingMode','disk&memory');
set(grp,'LogFileName','LoggingExample.olf');
set(grp,'LogToDiskMode','overwrite');
(4)开始采集数据
启动组对象,等待两秒钟,并显示最后获取的数据值。
start(grp)
pause
(2)
sPeek=peekdata(grp,1)
显示项的ID和值
disp({sPeek.Items.ItemID;sPeek.Items.Value});
等待数据采集完成后,才继续执行后面的代码。
wait(grp,inf)
(5)获取数据
[logIDs,logVal,logQual,logTime,logEvtTime]=getdata(grp,'double');
whoslog*;
(6)清除
disconnect(da)
delete(da)
cleardagrpitmCollection
4OPC工具箱的事件
4.1查看事件
(1)创建OPC工具箱对象层次结构
da=opcda('localhost','KEPware.KEPServerEx.V4');
connect(da);
itmIDs={'Channel_1.Device_1.Tag_1',...
'Channel_1.Device_1.Tag_2',...
'Channel_1.Device_1.Tag_3'};
grp=addgroup(da,'Group1');
itmCollection=additem(grp,itmIDs);
(2)开始数据采集
将数据采集数设定为10条,并开始采集
grp.RecordsToAcquire=10;
start(grp)
等待数据采集完毕
wait(grp)
(3)查看事件日志
在组对象采集数据时产生了两个事件:
开始和停止。
客户端的时间日志属性值是一行二列的事件型数组。
events=da.EventLog
列出记录在事件日志中的事件类型
{events.Type}
使用事件结构中的字段获取特定事件的信息。
下面代码显示了停止事件的信息。
stopdata=events
(2).Data
用停止时间减去开始时间,得到采集数据用掉的时间。
loggingDuration=datenum(events
(2).Data.LocalEventTime)-...
datenum(events
(1).Data.LocalEventTime);
loggingSeconds=loggingDuration*24*60*60
(4)清除
disconnect(da)
delete(da)
cleardagrpitmCollection
4.2使用默认回传
(1)创建OPC工具箱对象层次结构
da=opcda('localhost','KEPware.KEPServerEx.V4');
connect(da);
itmIDs={'Channel_1.Device_1.Tag_1',...
'Channel_1.Device_1.Tag_2',...
'Channel_1.Device_1.Tag_3'};
grp=addgroup(da,'Group1');
itmCollection=additem(grp,itmIDs);
(2)配置数据采集参数
grp.RecordsToAcquire=20;
grp.UpdateRate=0.5;
(3)配置回传
用默认数据回传显示在数据采集过程中的开始、数据获取、停止事件。
grp.StartFcn=@opccallback;
grp.StopFcn=@opccallback;
grp.RecordsAcquiredFcn=@opccallback;
grp.RecordsAcquiredFcnCount=5;
(4)开始数据采集
start(grp)
执行结果:
OPCStarteventoccurredatlocaltime15:
35:
47
Group'Group1':
0recordsacquired.
等待数据采集完毕
wait(grp)
(5)清除
disconnect(da)
delete(da)
cleardagrpitmCollection
4.3使用自定义回传
使用自定义回传,用display_opcdata函数将获取的数据实时绘制在图形窗口中。
(1)创建OPC工具箱对象层次结构
da=opcda('localhost','KEPware.KEPServerEx.V4');
connect(da);
itmIDs={'Channel_1.Device_1.Tag_1',...
'Channel_1.Device_1.Tag_2',...
'Channel_1.Device_1.Tag_3'};
grp=addgroup(da,'Group1');
itmCollection=additem(grp,itmIDs);
(2)设置相关参数值
设置数据更新速率为0.2秒,要获取的数据为200条,每5秒钟执行一次回传。
set(grp,'UpdateRate',0.5);
set(grp,'RecordsToAcquire',200);
set(grp,'RecordsAcquiredFcnCount',5);
set(grp,'RecordsAcquiredFcn',@display_opcdata);
(3)获取数据
start(grp)
wait(grp)
执行结果为动态绘制变量曲线的图形窗口,下图是执行结束时的图片。
图3自定义数据回传结束时数据图
(4)清除
disconnect(da)
delete(da)
cleardagrpitmCollection
5.使用OPC工具箱模块读写数据
在MATLAB的Simulink工具箱中,已经有OPC配置模块、OPC读取数据模块、OPC写入数据模块。
OPCWrite模块将输入信号写入到OPC服务器中,OPCRead模块将数据从OPC服务器中读取上来,并在Scope中显示。
另外,数据品质显示在Display模块中,如果数值为192就说明数据品质好。
只要建立适当的模型就可以完成对OPC服务器中数据的读写操作,并可以利用其他仿真工具完成复杂的控制。
本次仿真采用KEPWare.KEPServerEx.V4作为OPC服务器,模拟从编程逻辑控制器(PLC)读取和写入数据,并通过返回的数据绘出图形。
首先设置“OPC配置模块参数”,选择OPC服务器KEPWare.KEPServerEx.V4。
图4OPC服务器配置
(1)数字量写与读
使用KEPWare.KEPServerEx.V4中的数字量Channel_1.Device_1.K0.0作为数字量变量。
首先利用“OPC写模块”将数值在0、1间变换的方波信号写入OPC服务器中并赋值给Channel_1.Device_1.K0.0,然后再将该变量的值从OPC服务器重读取出来,如图5所示。
图5数字量写与读
图6数字量读取结果
运行图5所示模型后会得到图6所示结果。
图6显示,OPC服务器中的变量值随着方波信号改变了,并且写进去1后,变量值变为-1。
其中,0值表示False,-1表示True。
(2)短整型数据写与读
首先在OPC服务器中建立一个Short型变量Channel_1.Device_1.TagK2。
然后将一个整型常量20写入给该项,再将该项的值读取出来。
图7短整型数据写与读
图8短整型数据读取结果
运行后,可以从图8中看到该整型变量的值已经变成了20。
(3)浮点型数据写与读
首先在OPC服务器中建立一个浮点型变量Channel_1.Device_1.TagK4Float。
然后将一个正弦信号写入到该项,再将该项的值读取上来,并将原正弦信号与采集上来