520 lines
14 KiB
C#
520 lines
14 KiB
C#
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
|
||
{
|
||
|
||
/// <summary>
|
||
/// 进行写的数据
|
||
/// </summary>
|
||
public object writeDataValue;
|
||
/// <summary>
|
||
/// 进行读的数据
|
||
/// </summary>
|
||
public object readDataValue;
|
||
/// <summary>
|
||
/// 生成的server对象,主要用于异步时调用
|
||
/// </summary>
|
||
public IOPCServer ObjectServerPlc
|
||
{
|
||
get { return ServerObj; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进行写的数据
|
||
/// </summary>
|
||
public object WriteDataValue
|
||
{
|
||
get { return writeDataValue; }
|
||
set { writeDataValue = value; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进行读的数据
|
||
/// </summary>
|
||
public object ReadDataValue
|
||
{
|
||
get { return readDataValue; }
|
||
set { readDataValue = value; }
|
||
}
|
||
|
||
|
||
private bool boolValueChang = true;
|
||
|
||
/// <summary>
|
||
/// 该属性用于是否检测plc数据改成,异步订阅
|
||
/// </summary>
|
||
public bool ValueChang
|
||
{
|
||
set { boolValueChang = value; }
|
||
}
|
||
|
||
#region 参数值
|
||
|
||
/// <summary>
|
||
/// 设置db模块的值
|
||
/// </summary>
|
||
public string itemDvalue = "0";
|
||
/// <summary>
|
||
/// 异步读写对象
|
||
/// </summary>
|
||
public IOPCAsyncIO2 IOPCAsyncIO2Obj = null;
|
||
|
||
/// <summary>
|
||
/// 组管理对象
|
||
/// </summary>
|
||
public IOPCGroupStateMgt IOPCGroupStateMgtObj = null;
|
||
|
||
/// <summary>
|
||
/// 表示item的id
|
||
/// </summary>
|
||
public int hClient = 1;
|
||
public const int LOCALE_ID = 0x407;
|
||
/// <summary>
|
||
/// OPCServer
|
||
/// </summary>
|
||
public IOPCServer ServerObj;//OPCServer
|
||
public int pSvrGroupHandle = 0;
|
||
/// <summary>
|
||
/// 返回增加的group
|
||
/// </summary>
|
||
public Object MyobjGroup1 = null;
|
||
|
||
|
||
/// <summary>
|
||
/// plc是否读写
|
||
/// </summary>
|
||
public bool Write = true;
|
||
/// <summary>
|
||
/// 此处应该是返回连接的cookie值
|
||
/// </summary>
|
||
public Int32 dwCookie = 0;
|
||
|
||
public IConnectionPointContainer pIConnectionPointContainer = null;
|
||
public IConnectionPoint pIConnectionPoint = null;
|
||
/// <summary>
|
||
/// item的数组句柄
|
||
/// </summary>
|
||
public int[] ItemServerHandle;
|
||
/// <summary>
|
||
/// item的值。
|
||
/// </summary>
|
||
public OpcRcw.Da.OPCITEMDEF[] ItemArray;
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 连接服务器的名字
|
||
/// </summary>
|
||
public string remoteServerName = "OPC.SimaticNet";
|
||
|
||
/// <summary>
|
||
/// 连接服务器的名字
|
||
/// </summary>
|
||
public string ServerName
|
||
{
|
||
set { remoteServerName = value; }
|
||
}
|
||
|
||
public string remoteServerIP = "localhost";
|
||
/// <summary>
|
||
/// 连接服务器的ip地址
|
||
/// </summary>
|
||
public string ServerIP
|
||
{
|
||
set { remoteServerIP = value; }
|
||
}
|
||
/// <summary>
|
||
/// 错误内容
|
||
/// </summary>
|
||
protected string errText = string.Empty;
|
||
/// <summary>
|
||
/// 错误内容
|
||
/// </summary>
|
||
public string ErrText
|
||
{
|
||
get { return errText; }
|
||
set { errText = value; }
|
||
}
|
||
/// <summary>
|
||
/// 该属性用于传触发 plc的form窗体()
|
||
/// </summary>
|
||
public object formthis;
|
||
#region plc的链接
|
||
/// <summary>
|
||
/// plc的链接
|
||
/// </summary>
|
||
/// <param name="remoteServerName">链接的名字()</param>
|
||
/// <param name="remoteServerIP">链接的ip地址</param>
|
||
/// <returns></returns>
|
||
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
|
||
/// <summary>
|
||
/// 增加一个group
|
||
/// </summary>
|
||
/// <param name="Form_Main"></param>
|
||
/// <returns></returns>
|
||
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数组对象
|
||
/// <summary>
|
||
|
||
/// 添加一个读写的Items数组对象
|
||
|
||
/// </summary>
|
||
|
||
/// <param name="items">Items读写对象数组</param>
|
||
|
||
/// <returns>Items是否执行成功</returns>
|
||
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的值
|
||
/// <summary>
|
||
/// 写plc的值
|
||
/// </summary>
|
||
/// <param name="values">写的值</param>
|
||
/// <returns></returns>
|
||
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
|
||
|
||
|
||
/// <summary>
|
||
/// 读取plc的值
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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数据改变时,触发事件
|
||
/// <summary>
|
||
/// 检测plc数据改变时,触发事件
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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的连接
|
||
|
||
/// <summary>
|
||
/// 断开PLC的连接
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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
|
||
|
||
|
||
}
|
||
}
|