西门子PLC常用方法封装类(C#)V0.95b
2010-10-13 10:49
417 查看
希望大家能多多指教,我洗耳恭听,并将及时更改其中的错误和不足,还请大家多多给些意见和建议,谢谢。
同时希望对大家有用,网上的资料比较少,随时恭候文件资料和知识经验上的交流。
指出代码中的错误和不足,我将会完善它,贡献给大家使用,请大家多多批评。
同时希望对大家有用,网上的资料比较少,随时恭候文件资料和知识经验上的交流。
指出代码中的错误和不足,我将会完善它,贡献给大家使用,请大家多多批评。
/********************************************************************* * 模块名称:OPC服务器类 * 版 本:Version 0.95a * 作 者:longshaoye * 时 间:2010-09-28 16:43 * 备 注: * OPC服务器的常用操作:连接,断开,读,写,设置状态 * 附 注: * 该实例局限于一个服务器(IOPCServer)连接,一个组(Group)对象, * 多个读写(Item)对象的情况。针对一个服务器连接,多个组,多个 * 读写对象的情况,不适用于本实例方法。 * * 历史修改记录 * 作 者:longshaoye * 修改时间:2010-10-13 10:43 * 备 注: * 经使用发现之前的添加Item项,并不方便,还需在项目中引入opcrcw.common.dll * 和opcrcw,data.dll两个dll文件,比较不方便,所以有重新封装了一个item结构体, * 然后重新封装AddItems方法,就可以不用再在项目中引入那两个dll文件了。 * * *******************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using OpcRcw.Da; using OpcRcw.Comn; namespace PLC { /// <summary> /// OPC服务器类 By longshaoye 2010 /// </summary> public class OPCServer : IOPCDataCallback { #region Enum public enum ReturnValue { Success, Failed, Existed, InvalidObjectReference } #endregion #region Fields private OpcRcw.Da.IOPCServer ServerObj;//OPCServer private OpcRcw.Da.IOPCAsyncIO2 IOPCAsyncIO2Obj = null;//异步读写对象 private OpcRcw.Da.IOPCGroupStateMgt IOPCGroupStateMgtObj = null;//组管理对象 private IConnectionPointContainer pIConnectionPointContainer = null; private IConnectionPoint pIConnectionPoint = null; internal const int LOCALE_ID = 0x407; private Object MyobjGroup1 = null; private int[] ItemServerHandle; private int pSvrGroupHandle = 0; private Int32 dwCookie = 0; #endregion #region Constructor public OPCServer() { } #endregion #region Methods /// <summary> /// 建立PC到PLC的连接,返回OPC服务器对象 /// </summary> /// <param name="programID">将要连接的进程ID</param> /// <param name="server">服务器IP地址</param> /// <returns>OPC服务器对象</returns> public ReturnValue Connect(string programID, string server) { if (ServerObj != null) return ReturnValue.Existed; Type svrComponenttyp; try { svrComponenttyp = Type.GetTypeFromProgID(programID, server);//OPCServer ServerObj = (IOPCServer)Activator.CreateInstance(svrComponenttyp);//注册 return ReturnValue.Success; } catch (Exception) { return ReturnValue.Failed; } } /// <summary> /// 添加一个组对象,并返回该组对象的引用 /// </summary> /// <param name="form">回调对象</param> /// <returns>是否执行成功</returns> public ReturnValue AddGroup(object form) { if (MyobjGroup1 != null) return ReturnValue.Existed; Int32 dwRequestedUpdateRate = 1000; Int32 hClientGroup = 1; 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, out dwCookie); return ReturnValue.Success; } catch (Exception)// catch for group adding { return ReturnValue.Failed; } finally { if (hDeadband.IsAllocated) hDeadband.Free(); if (hTimeBias.IsAllocated) hTimeBias.Free(); } } /// <summary> /// 添加一个读写的Items数组对象 /// Ex: /// OpcRcw.Da.OPCITEMDEF[] ItemArray = new OPCITEMDEF[3];// /// ItemArray[0].szAccessPath = ""; /// ItemArray[0].szItemID = "S7:[S7 connection_1]DB13,DWORD0"; /// //地址,不同数据类型表示方法不同 /// ItemArray[0].bActive = 1;//是否激活 /// ItemArray[0].hClient = 1;//表示ID /// ItemArray[0].dwBlobSize = 0; /// ItemArray[0].pBlob = IntPtr.Zero; /// ItemArray[0].vtRequestedDataType = 2; /// </summary> /// <param name="items">Items读写对象数组</param> /// <returns>Items是否执行成功</returns> private ReturnValue AddItems(OPCITEMDEF[] items) { 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 ReturnValue.Success; } catch (System.Exception) // catch for add item { return ReturnValue.Failed; } finally { // Free the memory if (pResults != IntPtr.Zero) { Marshal.FreeCoTaskMem(pResults); pResults = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } } /// <summary> /// 添加一个读写的Items数组对象 /// Ex: /// OPCITEm[] ItemArray = new OPCITEM[3];// /// ItemArray[0].szAccessPath = ""; /// ItemArray[0].szItemID = "S7:[S7 connection_1]DB13,DWORD0"; /// //地址,不同数据类型表示方法不同 /// ItemArray[0].bActive = 1;//是否激活 /// ItemArray[0].hClient = 1;//表示ID /// ItemArray[0].dwBlobSize = 0; /// ItemArray[0].pBlob = IntPtr.Zero; /// ItemArray[0].vtRequestedDataType = 2; /// </summary> /// <param name="items">Items读写对象数组</param> /// <returns>Items是否执行成功</returns> public ReturnValue AddItems(OPCItem[] items) { OPCITEMDEF[] models = new OPCITEMDEF[items.Length]; for (int i = 0; i < items.Length; i++) { models[i].szAccessPath = items[i].szAccessPath; models[i].szItemID = items[i].szItemID; models[i].bActive = items[i].bActive;//是否激活 models[i].hClient = items[i].hClient;//表示ID models[i].dwBlobSize = items[i].dwBlobSize; models[i].pBlob = items[i].pBlob; models[i].vtRequestedDataType = items[i].vtRequestedDataType; models[i].wReserved = items[i].wReserved; } return AddItems(models); } /// <summary> /// 发送异步读命令,结果的读取要通过实现IOPCDataCallback接口的OnReadComplete函数实现 /// </summary> /// <param name="itemServerHandles">Item读写对象句柄数组</param> /// <returns>是否执行成功</returns> public ReturnValue Read() { 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 ReturnValue.Success; } catch (Exception) { return ReturnValue.Failed; } } else return ReturnValue.InvalidObjectReference; } /// <summary> /// 发送异步写命令,结果的状态,要通过实现IOPCDataCallback接口的OnWriteComplete函数实现 /// </summary> /// <param name="asyncIOObject">异步读写对象</param> /// <param name="itemServerHandles">Item读写对象句柄数组</param> /// <param name="values">要写入到PLC中的值数组</param> /// <returns>是否执行成功</returns> public ReturnValue Write(object[] values) { 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 ReturnValue.Failed; } return ReturnValue.Success; } catch (Exception) { return ReturnValue.Failed; } } else return ReturnValue.InvalidObjectReference; } /// <summary> /// 设置PLC状态,使之处罚OnDataChange事件函数 /// </summary> /// <param name="group"></param> /// <param name="value"></param> /// <returns></returns> public ReturnValue SetState(bool value) { 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); if (value != true) hActive.Target = 0; else hActive.Target = 1; try { IOPCGroupStateMgtObj.SetState(pRequestedUpdateRate, out nRevUpdateRate, hActive.AddrOfPinnedObject(), pTimeBias, pDeadband, pLCID, hClientGroup); return ReturnValue.Success; } catch (Exception) { return ReturnValue.Failed; } finally { hActive.Free(); } } /// <summary> /// 断开PC到PLC的连接 /// </summary> /// <returns>是否成功执行</returns> public ReturnValue DisConnect() { 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; } return ReturnValue.Success; } catch (Exception) { return ReturnValue.Failed; } } #endregion #region IOPCDataCallback 成员 void IOPCDataCallback.OnCancelComplete(int dwTransid, int hGroup) { if (OnCancelCompleted != null) OnCancelCompleted(dwTransid, hGroup); } void IOPCDataCallback.OnDataChange(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors) { OPCTime[] timeStamps = new OPCTime[pftTimeStamps.Length]; for (int i = 0; i < pftTimeStamps.Length; i++) { timeStamps[i].dwHighDateTime = pftTimeStamps[i].dwHighDateTime; timeStamps[i].dwLowDateTime = pftTimeStamps[i].dwLowDateTime; } if (OnDataChanged != null) OnDataChanged(dwTransid, hGroup, hrMasterquality, hrMastererror, dwCount, phClientItems, pvValues, pwQualities, timeStamps, pErrors); } void IOPCDataCallback.OnReadComplete(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors) { OPCTime[] timeStamps = new OPCTime[pftTimeStamps.Length]; for (int i = 0; i < pftTimeStamps.Length; i++) { timeStamps[i].dwHighDateTime = pftTimeStamps[i].dwHighDateTime; timeStamps[i].dwLowDateTime = pftTimeStamps[i].dwLowDateTime; } if (OnReadCompleted != null) OnReadCompleted(dwTransid, hGroup, hrMasterquality, hrMastererror, dwCount, phClientItems, pvValues, pwQualities, timeStamps, pErrors); } void IOPCDataCallback.OnWriteComplete(int dwTransid, int hGroup, int hrMastererr, int dwCount, int[] pClienthandles, int[] pErrors) { if (OnWriteCompleted != null) OnWriteCompleted(dwTransid, hGroup, hrMastererr, dwCount, pClienthandles, pErrors); } #endregion #region Events #region Delegates public delegate void CancelCompletedHandler(int dwTransid, int hGroup); public delegate void DataChangedHandler(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OPCTime[] pftTimeStamps, int[] pErrors); public delegate void ReadCompletedHandler(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OPCTime[] pftTimeStamps, int[] pErrors); public delegate void WriteCompletedHandler(int dwTransid, int hGroup, int hrMastererr, int dwCount, int[] pClienthandles, int[] pErrors); #endregion public event CancelCompletedHandler OnCancelCompleted; public event DataChangedHandler OnDataChanged; public event ReadCompletedHandler OnReadCompleted; public event WriteCompletedHandler OnWriteCompleted; #endregion } /// <summary> /// OPC操作ITEM项定义 /// (重新封装了OpcRcw.Da.OPCITEMDEF项定义) /// </summary> public struct OPCItem { /// <summary> /// 是否启用 /// </summary> public int bActive; /// <summary> /// dwBlobSize /// </summary> public int dwBlobSize; /// <summary> /// ID /// </summary> public int hClient; /// <summary> /// pBlob /// </summary> public IntPtr pBlob; /// <summary> /// szAccessPath /// </summary> public string szAccessPath; /// <summary> /// szItemID /// </summary> public string szItemID; /// <summary> /// vtRequestedDataType /// </summary> public short vtRequestedDataType; /// <summary> /// wReserved /// </summary> public short wReserved; } /// <summary> /// OPC时间戳定义 /// </summary> public struct OPCTime { public int dwHighDateTime; public int dwLowDateTime; } }
相关文章推荐
- 西门子PLC常用方法封装类(C#)V0.95b 测试程序(未调试版本)
- C# Windows Api的一些方法 封装 以及 常用参数
- C# HTTP网络常用方法封装
- C# HTTP网络常用方法封装
- C# Windows Api的一些方法 封装 以及 常用参数 .
- C#常用字符串加密解密方法封装代码
- C# Windows Api的一些方法 封装 以及 常用参数
- C#中常用的字符串加密,解密方法封装,包含只加密,不解密的方法
- C#常用字符串加密解密方法封装代码
- C# Windows Api的一些方法 封装 以及 常用参数
- C#中常用的字符串加密,解密方法封装
- C#常用字符串加解密方法封装
- c#.net常用函数和方法集
- C#封装程序集自定义类方法注释提示
- 自己整理的一些开发时候常用的js方法封装
- C#常用函数及方法集
- c#常用函数和方法集
- c#.net常用的小函数和方法集
- C#的File类中常用的文件操作函数(方法)及其使用
- C# 多线程 简单使用方法以及常用参数