程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#使用OpcNetApi.dll和OpcNetApi.Com.dll操作OPC

C#使用OpcNetApi.dll和OpcNetApi.Com.dll操作OPC

編輯:關於C#

本人學習了一下.Net,恰好,又要用這個。而網上很多VC6,VB6,VB .Net的但,很少C#的。現在研究一下,給出例子:

測試平台,是VS2008,KEPServer,OpcNetApi.dll和OpcNetApi.Com.dll。當然我也同時安裝了,西門子的Net2006和Step7,其中Net2006是負責OPC的,可能會在系統中創建一些dll之類的,因為我的程序換到一台沒有Net2006的機子上既然有問題,不知其電腦問題還是因為沒裝Net2006。不過,理論上,OpcNetApi.dll和OpcNetApi.Com.dll足矣。還有,Net2006的安裝路徑下會有寫dll和例子。例如我的是默認安裝,C:\Program Files\Siemens\SIMATIC.NET\opc2\samples下有Automation、Custom、dotnet、xml四種應用的例子,有興趣的可以研究研究。

下面給出我的代碼,是基於控制台的,代碼不長,如果 您有C#經驗和OPC基礎應不難理解,而且還有注釋,希望您能喜歡:)

以下是Program.cs,有些測試操作我注釋掉了,大家也可以玩玩。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Opc;
using Opc.Da;
using OpcCom;

namespace OPCAPITest
{
  class Tester
  {
    private Opc.Da.Server m_server = null;//定義數據存取服務器
    private Opc.Da.Subscription subscription = null;//定義組對象(訂閱者)
    private Opc.Da.SubscriptionState state = null;//定義組(訂閱者)狀態,相當於OPC規范中組的參數
    private Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//定義枚舉基於COM服務器的接口,用來搜索所有的此類服務器。
    public void Work()
    {
      //查詢服務器
      Opc.Server[] servers = m_discovery.GetAvailableServers(Specification.COM_DA_20,"TX1" , null);
      //daver表示數據存取規范版本,Specification.COMDA_20等於2.0版本。
      //host為計算機名,null表示不需要任何網絡安全認證。
      if (servers != null)
      {
        foreach (Opc.Da.Server server in servers)
        {
          //server即為需要連接的OPC數據存取服務器。
          if (String.Compare(server.Name,"TX1.KEPware.KEPServerEx.V4",true) == 0)//為true忽略大小寫
          //if (String.Compare(server.Name, "localhost.KEPware.KEPServerEx.V4", true) == 0)//不帶計算機名為本地訪問
          {
            m_server = server;//建立連接。
            break;
          }
        }
      }

      //連接服務器
      if (m_server != null)//非空連接服務器
        m_server.Connect();
      else
        return;

      //設定組狀態
      state = new Opc.Da.SubscriptionState();//組(訂閱者)狀態,相當於OPC規范中組的參數
      state.Name = "測試";//組名
      state.ServerHandle = null;//服務器給該組分配的句柄。
      state.ClientHandle = Guid.NewGuid().ToString();//客戶端給該組分配的句柄。
      state.Active = true;//激活該組。
      state.UpdateRate = 100;//刷新頻率為1秒。
      state.Deadband = 0;// 死區值,設為0時,服務器端該組內任何數據變化都通知組。
      state.Locale = null;//不設置地區值。

      //添加組
      subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//創建組
      //定義Item列表
      //對應類型為:{Byte,Byte,Char,Short,String,Word,Boolean}
      string[] itemName = { "BPJ.DB1.dbb0", "BPJ.DB1.dbb1", "BPJ.DB1.dbc2", "BPJ.DB1.dbi3",
                  "BPJ.DB1.dbs4", "BPJ.DB1.dbw5", "BPJ.DB1.dbx6" };

      //定義item列表
      Item[] items = new Item[7];//定義數據項,即item
      int i;
      for (i = 0; i < items.Length; i++)//item初始化賦值
      {
        items[i] = new Item();//創建一個項Item對象。
        items[i].ClientHandle = Guid.NewGuid().ToString();//客戶端給該數據項分配的句柄。
        items[i].ItemPath = null; //該數據項在服務器中的路徑。
        items[i].ItemName = itemName[i]; //該數據項在服務器中的名字。
      }

      //添加Item
      subscription.AddItems(items);

      //注冊回調事件
      subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);

      //以下測試同步讀
      //以下讀整個組
      ItemValueResult[] values = subscription.Read(subscription.Items);
      //以下檢驗item的quality
      /*if (values[0].Quality .Equals(Opc.Da.Quality.Good))
        Console.WriteLine("檢測質量成功!");*/
      //以下讀部分組
      Item[] r_items=new Item[2];
      for (i = 1; i < 3; i++)
        r_items[i-1] = subscription.Items[i];
      ItemValueResult[] values2 = subscription.Read(r_items);
      //以下遍歷讀到的全部值
      /*foreach (ItemValueResult value in values2)
      {
        Console.WriteLine("同步讀:ITEM:{0},value:{1},quality:{2}", value.ItemName, value.Value, value.Quality);
      }*/

      //以下測試異步讀
      IRequest quest=null ;
      subscription.Read(subscription.Items,1,this.OnReadComplete,out quest ) ;

      //以下測試同步寫
      //以下寫整個組
      ItemValue[] itemvalues= new ItemValue[subscription.Items.Length];
      for (i = 0; i < subscription.Items.Length; i++)
        itemvalues[i] = new ItemValue((ItemIdentifier)subscription.Items[i]);
      itemvalues[0].Value = 255;
      itemvalues[1].Value = 126;
      itemvalues[2].Value = 'A';
      itemvalues[3].Value = -128;
      itemvalues[4].Value = "Good Lucky!";
      itemvalues[5].Value = 65535;
      itemvalues[6].Value = true;
      subscription.Write(itemvalues);
      Thread.Sleep(500);//暫停線程以讓DataChange反映
      //以下寫部分組
      ItemValue[] itemvalues2 = new ItemValue[3];
      itemvalues2[0] = new ItemValue((ItemIdentifier)subscription.Items[1]);//TItem類要先轉成ItemIdentifier,才能轉成ItemValue
      itemvalues2[1] = new ItemValue((ItemIdentifier)subscription.Items[2]);//TItem類要先轉成ItemIdentifier,才能轉成ItemValue
      itemvalues2[2] = new ItemValue((ItemIdentifier)subscription.Items[3]);//TItem類要先轉成ItemIdentifier,才能轉成ItemValue   
      itemvalues2[0].Value = 12;
      itemvalues2[1].Value = 112;
      itemvalues2[2].Value = 122;
      subscription.Write(itemvalues2);

      //以下測試異步寫
      Thread.Sleep(500);//暫停線程以讓DataChange反映
      subscription.Write(itemvalues, 1, this.OnWriteComplete, out quest);

      //END
      Console.WriteLine("************************************** hit <return> to close...");
      Console.ReadLine();

      //取消回調事件
      subscription.DataChanged -= new Opc.Da.DataChangedEventHandler(this.OnDataChange);
      //移除組內item
      subscription.RemoveItems(subscription.Items);
      //結束:釋放各資源
      m_server.CancelSubscription(subscription);//m_server前文已說明,通知服務器要求刪除組。
      subscription.Dispose();//強制.NET資源回收站回收該subscription的所有資源。
      m_server.Disconnect();//斷開服務器連接
    }

    //DataChange回調
    public void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
    {
      Console.WriteLine("_____________________DataChange事件");
      foreach (ItemValueResult item in values)
      {
        Console.WriteLine("發生DataChange事件");
        Console.WriteLine("ITEM:{0},value:{1}", item.ItemName,item.Value);
        Console.WriteLine("ITEM:{0},value:{1}", item.Quality,item.Timestamp);
        Console.WriteLine("事件信號句柄為{0}", requestHandle);

      }

    }

    //ReadComplete回調
    public void OnReadComplete(object requestHandle, Opc.Da.ItemValueResult[] values)
    {
      /*Console.WriteLine("發生異步讀name:{0},value:{1}", values[0].ItemName, values[0].Value);
      if ((int)requestHandle == 1)
        Console.WriteLine("事件信號句柄為{0}", requestHandle);*/
    }

    //WriteComplete回調
    public void OnWriteComplete(object requestHandle, Opc.IdentifiedResult[] values)
    {
      /*Console.WriteLine("發生異步寫name:{0},value:{1}", values[0].ItemName, values[0].GetType());
      if ((int)requestHandle == 2)
        Console.WriteLine("事件信號句柄為{0}", requestHandle);*/
    }

    static void Main(string[] args)
    {
      Tester tst = new Tester();
      tst.Work();
    }
  }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved