您的位置:首页 > 编程语言 > C#

西门子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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: