使用示例程序
该程序包括多个元素,操作员可使用这些元素触发以下动作:
启动程序时,仅启用“启动示例” (start sample) 按钮。单击此按钮后,程序将生成所需的 opc 对象。随即会启用其它按钮。
单击“ 启动示例” (start sample) 按钮后,以 c# 编写并使用 .net- framework 的 opc 自定义接口(异步通信)的示例程序的启动对话框 .
程序说明 :
1 选择 .net 组件
2 将 progid 转换为 clsid
3 建立与 opc 服务器的连接
4 创建 opc 组
5 添加数据项
6 请求 iconnectionpointcontainer 接口
7 请求 iopcasyncio2 接口
8 创建回调对象
9 连接 opc 服务器与客户端的回调对象
10 执行所需的写入和读取操作
11 接收 opc 服务器的通知
12 删除对象并释放内存
步骤 1:选择 .net 组件
要配合使用 opc 数据访问的自定义接口和 .net,必须在您的 visual basic 项目中使用上述运行时可调用包装 (rcw) 。在该示例项目中,opcrcw.da 和 opcrcw.comn 组件已添完毕。
如果它们未出现在选项中,也可使用“浏览” (browse) 按钮从下列文件夹中进行选择: “ siemens simatic.net opc2in”
步骤 2:将 progid 转换为 clsid
为了对其进行标识,每个 com 服务器都有一个 progid 且该 progid 分配给世界上唯一的类型。使用 gettypefromprogid() 函数可实现上述操作。simatic net 的 opc 服务器的 progid 是 lopc.simaticnet:
type svrcomponenttyp = type.get typefromprogid(lopc.simaticnet);
步骤 3:建立与 opc 服务器的连接
activator 类的 createinstance() 函数生成一个具有之前指定类型的类的实例:
piopcserver =
(iopcserver)activato r.createinstance(svrcomponenttyp
);
该程序段的结果是 iopcserver 类型的接口变量 piopcserver。
步骤 4:创建 opc 组
iopcserver 接口具有用于创建组的 addgroup() 方法:
piopcserver.addgroup(group_name,
0,
dwrequestedupdaterate,
hclientgroup,
htimebias..addrofpinnedobject(),
hdeadban d.addrofpinnedobject(),
dwlcid,
out psvrgrouphandle,
out prevupdaterate,
ref out pobjgroup1)
注意
hdeadband 和 htimebias 的内存分配由 gchandle.alloc() 函数完成。
gchandle htimebias;
htimebias = gchandle.alloc(tim ebias,gchandletype.pinned);
gchandle hdeadband;
hdeadband = gchandle.alloc(deadband,gchandletype.pinned);
这些函数处理传送变量时间偏倚和死区(百分比死区)的非管理型内存。
当不再需要管理句柄时,必须按如下所示再次将其释放:
if (htimebias.isallocated) htimebias. free();
if (hdeadband.isallocated) hdeadband.free();
该程序段的结果是一个具有指定名称和所需属性的组。addgroup() 还返回 pobjgroup1变量作为返回参数,即组对象的接口。
使用类型调整调用 iopcgroupstatemgt ,可以只从返回的组接口 pobjgroup1 获取该接口。该调用的简化形式对应于 com 方法 queryinterface()。
稍后需使用 iopcgroupstatemgt 接口的 s etstate() 方法激活和禁用组。
piopcgroupstatemgt = (iopcgroupstatemgt)pob jgroup1;
步骤 5:添加数据项
iopcitemmgt 接口具有用于创建 opc 数据项的 additems() 方法:
((iopcitemmgt)pobjgroup1).additems(2,itemdeffarray,out
presults,out perrors);
该程序段的结果是服务器添加两个具有 itemd efs 参数中所指定属性的数据项。此外,还会对结果结构 opcitemresult 的变量(服务器句柄、目标系统上数据项的数据类型等)进行初始化。
由于结果通过基础 com 接口写入至非管理型内存,因此来自管理型 .net 代码的访问必须利用封送函数:
opcitemresult result = (opcitemresult)marshal.ptrtostructure(pos,
typeof(opcitemresult));
ite msvrhandlearray[0] = result.hserver;
pos = new intptr(pos.toint32() +
marshal.sizeof(typeof(opcitemresult)));
opcitemresult result = (opcitemresult)marshal.ptrtostructure
(pos,typ eof(opcitemresult));
itemsvrhandlearray[1] = result.hserver;
步骤 6:请求 iconnectionpointcontainer 接口
iconnectionpointcontainer 类型的 piconnectionpointcontainer 变量可源自 m_group_1 变量。
piconnectionpointcontai ner =
(iconnectionpointcontainer)pobjgroup1;
定位 iconnectionpoint 接口需要使用该接口。
步骤 7:请求 iopcasyncio2 接口
piopcasyncio2 类型的 piopcasyncio2 变量可源自 pobjgroup1 变量。
piopcasyncio2 = (iopcasyncio2)pobjgroup1;
该接口提供用于异步读取和写入值的方法。
步骤 8:创建回调对象
为了允许 opc 服务器返回异步操作的值,必须在客户端上执行 i opcdatacallback 接口。
public class opcasync :system.windows.forms.form ,
iopcdatacallback
使用 iconnectionpointcontainer 接口的 findconnectionpoint() 方法建立 opc 服务器的 iconnectionpoint 和 iopcdatacallback 接口间的连接。该连接将为异步调用生成一个回调对象。
guid iid = typeof(io pcdatacallback).guid;
piconnectionpointcontainer.findconnectionpoint(ref iid,
out
piconnectionpoint);
步骤 9:连接 opc 服务器与客户端的回调对象
opc 服务器的回调对象与客户端应用程序间的连接通过 advise() 方法来建立。返回变量 dwcookie 是该连接的 id 。
piconnectionpoint.advise(this,out dwcookie);
步骤 10:执行所需的写入或读取操作
在步骤 7 中生成的 read() 和 write() 方法可通过 iopcasyncio2 接口来访问:
piopcasyncio2.read(1,itemsvrhandlearray,ntransactionid+1,
out ncancelid,out perrors);
步骤 11:接收 opc 服务器的通知
如果激活组中激活数据项的数据发生更改,服务器将调用回调对象的 ondatac hange 方法。读取操作完成后,服务器调用 onreadcomplete() 方法;写入操作完成后,服务器调用 onwritecomplete() 方法。服务器将返回值以参数的形式传递至方法。
virtual void ondatachange(
int32 dwtransid,
int32 hgroup,
int32 hrmasterquality,
int32 hrmastererror,
int32 dwcount,
int[] phclientitems,
object[] pvvalues,
short[] pwqualities,
filetime[] pfttimestamps,
int[] perrors,
)
步骤 12:删除对象并释放内存
退出程序前或单击“ 停止”(stop) 后,必须删除已生成的 opc 对象并释放所占用的内存。
piconnectionpoint.unadvise(dwcookie);
marshal.releasecomobject(piconnectionpoint);
mar shal.releasecomobject (piconnectionpointcontainer);
marshal.releasecomobject(piopcasyncio2);
marshal.releasecomobject(piopcgroupstatemgt);
marshal.releasecomobject(pobjgroup1);
marshal.releasecomobject(piopcserver);
释放内存
使用 com 时,客户端有时需要释放服务器所请求的内存。相关规则如下:
• [out]:将从服务器请求具有该属性的参数的内存。
• [in,out] :将从客户端请求此类参数的内存。服务器可以再次释放内存并对其进行重新分配。
• [in] :客户端将请求内存。服务器不负责释放内存。
原文标题:以 c# 编写的 opc 自定义接口(异步通信)
文章出处:【微信公众号:机器人及plc自动化应用】欢迎添加关注!文章转载请注明出处。
三星Galaxy Lite AR眼镜渲染图曝光
16 × 16模拟交叉点开关矩阵ADV3226芯片
RFID技术助力万物标签加密,从而保护供应链
用于双极性A至D转换器的单电源RS232接口
投影界新秀 性能与资源双优 当贝投影仪F1——体验满满的诚意
以C#编写并使用NET-Framework的OPC自定义接口
为电动汽车充电需要多少太阳能电池板
传音成功IPO!非洲手机之王登陆科创板,市值400亿
对于蓝牙耳机我们该怎么选,续航时间长的蓝牙耳机推荐
苹果Mac OS X如何维护和保养
基于区块链智能合约的去中心化农业技术和食品科学项目ATFS介绍
转子流量计怎么使用
三星和LG宣布退出LCD产业 中国企业的机会和挑战来了
IEDM:28nm嵌入式MRAM即将问世
腾讯云推出了物联网边缘计算平台五大优势破解物联网落地难题
智能手环测血压准不准_智能手环测血压原理详解
无铅工艺实施注意事项
盘点各大机器人企业的发展现状
回收利用难题待解决,退役锂电池派上新用场
探讨新一代网络技术革命浪潮下的IoT物联网革命