C# OPC使用
OPC用戶端操作主要有4個步驟:
1.連接配接OPC伺服器
2.建立組和項
3.讀寫資料
4.斷開伺服器連接配接
全部代碼:
複制代碼
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using OPCAutomation;
namespace ConsoleOPC
{
public class OPCClient
{
private OPCServer KepServer;
private OPCGroups KepGroups;
public OPCGroup KepGroup;
private OPCItems KepItems;
private OPCItem KepItem;
int itmHandleClient = 0;
int itmHandleServer = 0;
public object readValue;
public List<string> serverNames = new List<string>();
public List<string> Tags = new List<string>();
/// <summary>
/// 枚舉本地OPC SERVER
/// </summary>
public void GetOPCServers()
{
IPHostEntry IPHost = Dns.GetHostEntry(Environment.MachineName);
Console.WriteLine("MAC Address:");
foreach (IPAddress ip in IPHost.AddressList)
{
Console.WriteLine(ip.ToString());
}
Console.WriteLine("Please Enter IPHOST");
string strHostIP = "localhost";//Console.ReadLine();
IPHostEntry ipHostEntry = Dns.GetHostEntry(strHostIP);
try
{
KepServer = new OPCServer();
object serverList = KepServer.GetOPCServers(ipHostEntry.HostName.ToString());
int i = 0;
foreach (string serverName in (Array)serverList)
{
Console.WriteLine(i.ToString() + "." + serverName);
serverNames.Add(serverName);
}
}
catch (Exception ex)
{
Console.WriteLine("Connect Error:" + ex.Message);
}
}
/// <summary>
/// 連接配接OPC SERVER
/// </summary>
/// <param name="serverName">OPC SERVER名字</param>
public void ConnectServer(string serverName)
{
try
{
KepServer.Connect(serverName, "");
CreateGroup("");
CreateItems();
}
catch (Exception ex)
{
Console.WriteLine("Connect Error:" + ex.Message);
}
}
/// <summary>
/// 建立組,組名無所謂
/// </summary>
private void CreateGroup(string groupName)
{
try
{
KepGroups = KepServer.OPCGroups;
KepGroup = KepGroups.Add(groupName);
KepServer.OPCGroups.DefaultGroupIsActive = true;
KepServer.OPCGroups.DefaultGroupDeadband = 0;
KepGroup.UpdateRate = 250;
KepGroup.IsActive = true;
KepGroup.IsSubscribed = true;
}
catch (Exception ex)
{
Console.WriteLine("Create group error:" + ex.Message);
}
}
private void CreateItems()
{
KepItems = KepGroup.OPCItems;
KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
}
private void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
for (int i = 1; i <= NumItems; i++)
{
readValue = ItemValues.GetValue(i).ToString();
}
}
private void GetTagValue(string tagName)
{
try
{
readValue = "";
if (itmHandleClient != 0)
{
Array Errors;
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
//注:OPC中以1為數組的基數
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandle = (Array)temp;
//移除上一次選擇的項
KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
}
itmHandleClient = 12345;
KepItem = KepItems.AddItem(tagName, itmHandleClient);
itmHandleServer = KepItem.ServerHandle;
}
catch (Exception err)
{
//沒有任何權限的項,都是OPC伺服器保留的系統項,此處可不做處理。
itmHandleClient = 0;
Console.WriteLine("Read value error:" + err.Message);
}
}
public void WriteValue(string tagName, object _value)
{
GetTagValue(tagName);
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandles = (Array)temp;
object[] valueTemp = new object[2] { "", _value };
Array values = (Array)valueTemp;
Array Errors;
int cancelID;
KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, 2009, out cancelID);
//KepItem.Write(txtWriteTagValue.Text);//這句也可以寫入,但并不觸發寫入事件
GC.Collect();
}
public object ReadValue(string tagName)
{
GetTagValue(tagName);
Thread.Sleep(500);
try
{
return KepItem.Value;
}
catch
{
return null;
}
}
public void ReadValue(string tagName,bool wtf)
{
GetTagValue(tagName);
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandles = (Array)temp;
Array Errors;
int cancel;
KepGroup.AsyncRead(1, ref serverHandles, out Errors, 2009, out cancel);
GC.Collect();
}
}
}
步驟:
1.使用GetOPCServers方法,将本地所有OPC Server上所有OPC伺服器服務枚舉并寫入serverNames變量中
2.使用ConnectServer方法,連接配接伺服器。此方法自動建立OPC Group,建立方法中的groupname任意寫
3.使用ReadValue及WriteValue方法讀寫資料。
PS:
1.OPCItems是一個清單,每次将舊資料移除,插入新資料,即清單中永遠隻有一個元素;
2.讀的時候有可能舊資料移除,新資料未寫入,報對象為null的錯誤,sleep一下即可
第二條不一定對,使用模拟器的時候也有此問題,連PLC時無此問題
轉載于:https://www.cnblogs.com/punkrocker/archive/2012/09/01/2666307.html