C#通过KepServer采用DA、UA两种方式访问PLC

1.通过KepServer访问PLC整体结构介绍

一: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#工程后,在引用处添加动态库的引用,C#通过KepServer采用DA、UA两种方式访问PLC_第1张图片

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的地址。C#通过KepServer采用DA、UA两种方式访问PLC_第2张图片

就是这些。拿到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名.+标记名。比如:

C#通过KepServer采用DA、UA两种方式访问PLC_第3张图片

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的。

你可能感兴趣的:(KepServer)