using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpcRcw.Da; using OpcRcw.Comn; using System.Runtime.InteropServices; namespace Common { public class PlcRead { /// /// 进行写的数据 /// public object writeDataValue; /// /// 进行读的数据 /// public object readDataValue; /// /// 生成的server对象,主要用于异步时调用 /// public IOPCServer ObjectServerPlc { get { return ServerObj; } } /// /// 进行写的数据 /// public object WriteDataValue { get { return writeDataValue; } set { writeDataValue = value; } } /// /// 进行读的数据 /// public object ReadDataValue { get { return readDataValue; } set { readDataValue = value; } } private bool boolValueChang = true; /// /// 该属性用于是否检测plc数据改成,异步订阅 /// public bool ValueChang { set { boolValueChang = value; } } #region 参数值 /// /// 设置db模块的值 /// public string itemDvalue = "0"; /// /// 异步读写对象 /// public IOPCAsyncIO2 IOPCAsyncIO2Obj = null; /// /// 组管理对象 /// public IOPCGroupStateMgt IOPCGroupStateMgtObj = null; /// /// 表示item的id /// public int hClient = 1; public const int LOCALE_ID = 0x407; /// /// OPCServer /// public IOPCServer ServerObj;//OPCServer public int pSvrGroupHandle = 0; /// /// 返回增加的group /// public Object MyobjGroup1 = null; /// /// plc是否读写 /// public bool Write = true; /// /// 此处应该是返回连接的cookie值 /// public Int32 dwCookie = 0; public IConnectionPointContainer pIConnectionPointContainer = null; public IConnectionPoint pIConnectionPoint = null; /// /// item的数组句柄 /// public int[] ItemServerHandle; /// /// item的值。 /// public OpcRcw.Da.OPCITEMDEF[] ItemArray; #endregion /// /// 连接服务器的名字 /// public string remoteServerName = "OPC.SimaticNet"; /// /// 连接服务器的名字 /// public string ServerName { set { remoteServerName = value; } } public string remoteServerIP = "localhost"; /// /// 连接服务器的ip地址 /// public string ServerIP { set { remoteServerIP = value; } } /// /// 错误内容 /// protected string errText = string.Empty; /// /// 错误内容 /// public string ErrText { get { return errText; } set { errText = value; } } /// /// 该属性用于传触发 plc的form窗体() /// public object formthis; #region plc的链接 /// /// plc的链接 /// /// 链接的名字() /// 链接的ip地址 /// public string ConnectRemoteServer() { try { ////建议一个连接 Type svrComponenttyp = Type.GetTypeFromProgID(remoteServerName, remoteServerIP); ServerObj = (IOPCServer)Activator.CreateInstance(svrComponenttyp); } catch (Exception ex) { errText = "连接远程服务器出现错误:" + ex.Message.ToString(); } return errText; } #endregion public int hClientGroup =1; #region 增加一个group /// /// 增加一个group /// /// /// public string PLCGroupAdd(object Form_Main) { string errText = string.Empty; Int32 dwRequestedUpdateRate = 250; Int32 pRevUpdateRate; float deadband = 0; int TimeBias = 0; GCHandle hTimeBias, hDeadband; hTimeBias = GCHandle.Alloc(TimeBias, GCHandleType.Pinned); hDeadband = GCHandle.Alloc(deadband, GCHandleType.Pinned); Guid iidRequiredInterface = typeof(IOPCItemMgt).GUID; try { ServerObj.AddGroup("MyOPCGroup1",//组对象 0, dwRequestedUpdateRate, hClientGroup, hTimeBias.AddrOfPinnedObject(), hDeadband.AddrOfPinnedObject(), LOCALE_ID, out pSvrGroupHandle, out pRevUpdateRate, ref iidRequiredInterface, out MyobjGroup1); IOPCAsyncIO2Obj = (IOPCAsyncIO2)MyobjGroup1; //Query interface for Async calls on group object IOPCGroupStateMgtObj = (IOPCGroupStateMgt)MyobjGroup1; pIConnectionPointContainer = (IConnectionPointContainer)MyobjGroup1; //定义特定组的异步调用连接 Guid iid = typeof(IOPCDataCallback).GUID; // Establish Callback for all async operations pIConnectionPointContainer.FindConnectionPoint(ref iid, out pIConnectionPoint); // Creates a connection between the OPC servers's connection point and this client's sink (the callback object) pIConnectionPoint.Advise(Form_Main, out dwCookie); } catch (Exception ex) { errText = ex.Message.ToString(); } return errText; } #endregion #region 添加一个读写的Items数组对象 /// /// 添加一个读写的Items数组对象 /// /// Items读写对象数组 /// Items是否执行成功 public string PlcItemAdd(OPCITEMDEF[] items) { string errText = string.Empty; IntPtr pResults = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; try { ((IOPCItemMgt)MyobjGroup1).AddItems(items.Length, items, out pResults, out pErrors); int[] errors = new int[items.Length]; Marshal.Copy(pErrors, errors, 0, items.Length); ItemServerHandle = new int[items.Length]; IntPtr pos = pResults; OPCITEMRESULT result; if (errors[0] == 0) { result = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT)); ItemServerHandle[0] = result.hServer; } for (int i = 1; i < errors.Length; i++) { if (errors[i] == 0) { pos = new IntPtr(pos.ToInt32() + Marshal.SizeOf(typeof(OPCITEMRESULT))); result = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT)); ItemServerHandle[i] = result.hServer; } } return errText; } catch (System.Exception ex) // catch for add item { return ex.Message.ToString().Trim(); } finally { // Free the memory if (pResults != IntPtr.Zero) { Marshal.FreeCoTaskMem(pResults); pResults = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } } #endregion #region 写plc的值 /// /// 写plc的值 /// /// 写的值 /// public string WirtePlc(object[] values) { string errText = string.Empty; int nCancelid; IntPtr pErrors = IntPtr.Zero; if (IOPCAsyncIO2Obj != null) { try { IOPCAsyncIO2Obj.Write(ItemServerHandle.Length, ItemServerHandle, values, ItemServerHandle.Length, out nCancelid, out pErrors); int[] errors = new int[ItemServerHandle.Length]; Marshal.Copy(pErrors, errors, 0, ItemServerHandle.Length); if (errors[0] != 0)//Error in reading item { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; return errText; } return errText; } catch (Exception ex) { errText = ex.Message.ToString().Trim(); return errText; } } return errText; } #endregion /// /// 读取plc的值 /// /// public string ReadPlc() { string errText = string.Empty; int nCancelid; IntPtr pErrors = IntPtr.Zero; if (IOPCAsyncIO2Obj != null) { try { IOPCAsyncIO2Obj.Read(ItemServerHandle.Length, ItemServerHandle, ItemServerHandle.Length, out nCancelid, out pErrors); int[] errors = new int[ItemServerHandle.Length]; Marshal.Copy(pErrors, errors, 0, ItemServerHandle.Length); return errText; } catch (Exception ex) { errText = ex.Message.ToString().Trim(); } } return errText; } #region 检测plc数据改变时,触发事件 /// /// 检测plc数据改变时,触发事件 /// /// public string DataChange() { string errText = string.Empty; IntPtr pRequestedUpdateRate = IntPtr.Zero; int nRevUpdateRate = 0; IntPtr hClientGroup = IntPtr.Zero; IntPtr pTimeBias = IntPtr.Zero; IntPtr pDeadband = IntPtr.Zero; IntPtr pLCID = IntPtr.Zero; int nActive = 0; // activates or deactivates group according to checkbox status GCHandle hActive = GCHandle.Alloc(nActive, GCHandleType.Pinned); hActive.Target = 1; try { IOPCGroupStateMgtObj.SetState(pRequestedUpdateRate, out nRevUpdateRate, hActive.AddrOfPinnedObject(), pTimeBias, pDeadband, pLCID, hClientGroup); } catch (System.Exception error) { errText = error.Message.ToString(); } finally { hActive.Free(); } return errText; } #endregion #region 断开PLC的连接 /// /// 断开PLC的连接 /// /// public string DisConnection() { string errText = string.Empty; try { if (dwCookie != 0) { pIConnectionPoint.Unadvise(dwCookie); dwCookie = 0; } // Free unmanaged code Marshal.ReleaseComObject(pIConnectionPoint); pIConnectionPoint = null; Marshal.ReleaseComObject(pIConnectionPointContainer); pIConnectionPointContainer = null; if (IOPCAsyncIO2Obj != null) { Marshal.ReleaseComObject(IOPCAsyncIO2Obj); IOPCAsyncIO2Obj = null; } ServerObj.RemoveGroup(pSvrGroupHandle, 0); if (IOPCGroupStateMgtObj != null) { Marshal.ReleaseComObject(IOPCGroupStateMgtObj); IOPCGroupStateMgtObj = null; } if (MyobjGroup1 != null) { Marshal.ReleaseComObject(MyobjGroup1); MyobjGroup1 = null; } if (ServerObj != null) { Marshal.ReleaseComObject(ServerObj); ServerObj = null; } } catch (System.Exception error) { errText = error.Message.ToString().Trim(); } return errText; } #endregion } }