赞
踩
一:Kepserver分为客户端和服务端。
1.服务端负责通过自己集成的各个厂家设备的驱动与PLC进行交互(数据读、写)。
2.客户端通过与服务端交互,完成PLC数据的采集,供我们使用,通过服务端把数据写入PLC,进行控制。
二:通过DA方式访问PLC,采用C#开发
1.如果Client与Server不在同一台机器上,那么两台机器都需要配置DCOM授权模式。
2.若OPC连接时找不到COM类工厂对象,可以试试regsvr32 OPCDAAuto.dll, 一般在system32或 sysWOW64目录下。
3.我们用C#通过Kepserver访问PLC时,其实的原理为我们调用动态库Interop.OPCAutomation.dll,这个动态库可以理解为是KepServer的一个客户端,这个客户端给我我们提供读写PLC的接口,我们通过接口调用,与KepServer服务端交互,实现PLC操作。一下步骤开始简单介绍下具体操作。
4.新建C#工程后,在引用处添加动态库的引用,
5.首先实例化一个OPCServer对象
OPCServer server = new OPCServer();
然后调用server对象的Connect()方法。这个方法需要提供两个参数。这个方法的源代码声明为
- [DispId(1610743826)]
- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
- void Connect([MarshalAs(UnmanagedType.BStr), In] string ProgID, [MarshalAs(UnmanagedType.Struct), In, Optional] object Node);
这个两个参数的格式非常固定。比如连接V6版本,ProgID写"KEPware.KEPServerEx.V6",Node其实就是KepServer服务端所在电脑的IP地址,如果Client 和 Server在同一台机器,那可以写127.0.0.1
说远了,我们这就开始连接
server.Connect(ProgID, Node);
接下来我们声明4个变量
- OPCGroups groups;
- OPCGroup group;
- OPCItems items;
- OPCItem item;
OPCGroups是“Server”下面最大概念。它是OPCGroup的集合。在下面可以看到这4者的关系。
“Server”中直接有OPCGroups这个属性,我们可以直接拿到。
- groups = server.OPCGroups; //拿到组jih
- groups.DefaultGroupIsActive = true; //设置组集合默认为激活状态
- groups.DefaultGroupDeadband = 0; //设置死区
- groups.DefaultGroupUpdateRate = 200;//设置更新频率
这里提到OPCGroups是组的集合,调用它的Add(string)方法就可以拿到一个组,即OPCGroup,后面会发现,我们好多操作都是以OPCGroup为单位来操作的。
- group = server.OPCGroups.Add(tmpGroupName);
- group.IsSubscribed = true; //是否为订阅
- group.UpdateRate = 200; //刷新频率
- group.DataChange += mygroup.onDataChange; //组内数据变化的回调函数
- group.AsyncReadComplete += mygroup.onAsyncReadComplete; //异步读取完成回调
- group.AsyncWriteComplete += mygroup.onAsyncWriteComplete; //异步写入完成回调
- group.AsyncCancelComplete += mygroup.onAsyncCancelComplete;//异步取消读取、写入回调
这里注意Add()方法的参数,这个方法的声明为
- [DispId(1610743822)]
- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
- [return: MarshalAs(UnmanagedType.Interface)]
- OPCGroup Add([MarshalAs(UnmanagedType.Struct), In, Optional] object Name);
看起来是不是很吓人,其实很简单,就是这个组的名字而已。就想我们的名字一样。哈哈。这里最重要的其实是订阅模式下,DataChange 这个事件,这个组内任何数据变化都会触发这个事件,调用我们处理数据的回调函数。
- //组对象事件处理虚函数:数据改变
- public virtual void onDataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
- {
- if (DataChange != null)
- DataChange(this, TransactionID, NumItems, ref ClientHandles, ref ItemValues, ref Qualities, ref TimeStamps);
- }
也就是说,当PLC值变化时,就是触发这个事件,然后我们就可以在这里拿到变化的变量的值,用于我们的程序逻辑的处理了。
接下来是items(离我们越来越近了),它是item的集合。什么是item呢,item就对应到我们kepserver中具体的变量,对应于我们PLC的地址。
就是这些。拿到items方法很简单,Groups直接包含这个属性
items = group.OPCItems;
拿到items后,调用items.Add(para1,para2)方法,就可以把item加入到items中,并返回item对象。这个方法的源代码为
- [DispId(1610743819)]
- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
- [return: MarshalAs(UnmanagedType.Interface)]
- OPCItem AddItem([MarshalAs(UnmanagedType.BStr), In] string ItemID, [In] int ClientHandle);
Add()的两个参数特别需要注意。尤其第一个参数:ItemID,这个必须和kepserver中的item保持一致,如果不一致,这个方法就会报异常,添加失败。ItemID 是一个字符串,它的组成为 Kepserver中的Channel名.+Device名.+Group名.+标记名。比如:
PLC地址为K0058这个item的ItemID为:CX62KX63.ER.Alarm.Fault_RB01_Fault_ProgNo_Match 这里必须注意,最好复制,别写错了。第二个参数是组内 item句柄。这个参数在组内是唯一的,用来表示这个item。
到这里就大功告成了。PLC数据变化后,就可以触发DataChannge回调函数了,我们就可以拿到变化的数。
但是有时候,我们需要主动去读、写PLC。同步读,同步写。有两种方式:
方式一:通过item。直接调用iem.read() 、item.write(),填写响应参数,就可以实现读写。
方式二:通过item所在组。
- //同步读
- group.SyncRead((short)OPCDataSource.OPCDevice, NumItems, ServerHandles, out Values, out Errors, out Qualities, out TimeStamps);
- //同步写
- group.SyncWrite(NumItems, ServerHandles, Values, out Errors);
如果采用异步的话,那就只能通过item所在组了。
- //异步读
- group.AsyncRead(NumItems, ServerHandles, out Errors, TransactionID, out CancelID);
- //异步写
- group.AsyncWrite(NumItems, ServerHandles, Values, out Errors, TransactionID, out CancelID);
我们对PLC的操作也无非就这些了。数据变化自动反馈、同步读、异步读、同步写、异步写。对数据的操作就写到这里。
接下来我们用完了资源要记得释放。释放资源很简单。
移除组
- OPCGroups groups;
- groups = server.OPCGroups;
- groups.Remove(group.GroupName);
断开连接
- //断开KEPServer
- public static void DisconnectServer()
- {
- server.Disconnect();
- }
好了,DA操作KepServer的步骤就写到这里。这里就不贴源码了,因为我的源码是项目中的,单独拿出来也没法直接用,里面依赖好多辅助类,数据库操作等。有问题可加QQ群:633204942 一起讨论咨询:下章写UA的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。