zoukankan      html  css  js  c++  java
  • C#使用OpcNetApi.dll和OpcNetApi.Com.dll操作OPC

    本人学习了一下.Net,恰好,51自学网,又要用这个。而网上很多VC6,VB6,VB .Net的但,很少C#的。现在研究一下,给出例子:

    测试平台,是VS2008,KEPServer,OpcNetApi.dll和OpcNetApi.Com.dll。当然我也同时安装了,51自学网,西门子的Net2006和Step7,其中Net2006是负责OPC的,可能会在系统中创建一些dll之类的,自学,因为我的程序换到一台没有Net2006的机子上既然有问题,不知其电脑问题还是因为没装Net2006。不过,理论上,OpcNetApi.dll和OpcNetApi.Com.dll足矣。还有,Net2006的安装路径下会有写dll和例子。例如我的是默认安装,C:Program FilesSiemensSIMATIC.NETopc2samples下有Automation、Custom、dotnet、xml四种应用的例子,有兴趣的可以研究研究。

    下面给出我的代码,是基于控制台的,代码不长,如果 您有C#经验和OPC基础应不难理解,而且还有注释,希望您能喜欢:)

    以下是Program.cs,有些测试操作我注释掉了,大家也可以玩玩。

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading;
      6 using Opc;
      7 using Opc.Da;
      8 using OpcCom;
      9 
     10 namespace OPCAPITest
     11 {
     12   class Tester
     13   {
     14     private Opc.Da.Server m_server = null;//定义数据存取服务器
     15     private Opc.Da.Subscription subscription = null;//定义组对象(订阅者)
     16     private Opc.Da.SubscriptionState state = null;//定义组(订阅者)状态,相当于OPC规范中组的参数
     17     private Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//定义枚举基于COM服务器的接口,用来搜索所有的此类服务器。
     18     public void Work()
     19     {
     20       //查询服务器
     21       Opc.Server[] servers = m_discovery.GetAvailableServers(Specification.COM_DA_20,"TX1" , null);
     22       //daver表示数据存取规范版本,Specification.COMDA_20等于2.0版本。
     23       //host为计算机名,null表示不需要任何网络安全认证。
     24       if (servers != null)
     25       {
     26         foreach (Opc.Da.Server server in servers)
     27         {
     28           //server即为需要连接的OPC数据存取服务器。
     29           if (String.Compare(server.Name,"TX1.KEPware.KEPServerEx.V4",true) == 0)//为true忽略大小写
     30           //if (String.Compare(server.Name, "localhost.KEPware.KEPServerEx.V4", true) == 0)//不带计算机名为本地访问
     31           {
     32             m_server = server;//建立连接。
     33             break;
     34           }
     35         }
     36       }
     37 
     38       //连接服务器
     39       if (m_server != null)//非空连接服务器
     40         m_server.Connect();
     41       else
     42         return;
     43 
     44       //设定组状态
     45       state = new Opc.Da.SubscriptionState();//组(订阅者)状态,相当于OPC规范中组的参数
     46       state.Name = "测试";//组名
     47       state.ServerHandle = null;//服务器给该组分配的句柄。
     48       state.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
     49       state.Active = true;//激活该组。
     50       state.UpdateRate = 100;//刷新频率为1秒。
     51       state.Deadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。
     52       state.Locale = null;//不设置地区值。
     53 
     54       //添加组
     55       subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//创建组
     56       //定义Item列表
     57       //对应类型为:{Byte,Byte,Char,Short,String,Word,Boolean}
     58       string[] itemName = { "BPJ.DB1.dbb0", "BPJ.DB1.dbb1", "BPJ.DB1.dbc2", "BPJ.DB1.dbi3",
     59                   "BPJ.DB1.dbs4", "BPJ.DB1.dbw5", "BPJ.DB1.dbx6" };
     60 
     61       //定义item列表
     62       Item[] items = new Item[7];//定义数据项,即item
     63       int i;
     64       for (i = 0; i < items.Length; i++)//item初始化赋值
     65       {
     66         items[i] = new Item();//创建一个项Item对象。
     67         items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
     68         items[i].ItemPath = null; //该数据项在服务器中的路径。
     69         items[i].ItemName = itemName[i]; //该数据项在服务器中的名字。
     70       }
     71 
     72       //添加Item
     73       subscription.AddItems(items);
     74 
     75       //注册回调事件
     76       subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
     77 
     78       //以下测试同步读
     79       //以下读整个组
     80       ItemValueResult[] values = subscription.Read(subscription.Items);
     81       //以下检验item的quality
     82       /*if (values[0].Quality .Equals(Opc.Da.Quality.Good))
     83         Console.WriteLine("检测质量成功!");*/
     84       //以下读部分组
     85       Item[] r_items=new Item[2];
     86       for (i = 1; i < 3; i++)
     87         r_items[i-1] = subscription.Items[i];
     88       ItemValueResult[] values2 = subscription.Read(r_items);
     89       //以下遍历读到的全部值
     90       /*foreach (ItemValueResult value in values2)
     91       {
     92         Console.WriteLine("同步读:ITEM:{0},value:{1},quality:{2}", value.ItemName, value.Value, value.Quality);
     93       }*/
     94 
     95       //以下测试异步读
     96       IRequest quest=null ;
     97       subscription.Read(subscription.Items,1,this.OnReadComplete,out quest ) ;
     98 
     99       //以下测试同步写
    100       //以下写整个组
    101       ItemValue[] itemvalues= new ItemValue[subscription.Items.Length];
    102       for (i = 0; i < subscription.Items.Length; i++)
    103         itemvalues[i] = new ItemValue((ItemIdentifier)subscription.Items[i]);
    104       itemvalues[0].Value = 255;
    105       itemvalues[1].Value = 126;
    106       itemvalues[2].Value = 'A';
    107       itemvalues[3].Value = -128;
    108       itemvalues[4].Value = "Good Lucky!";
    109       itemvalues[5].Value = 65535;
    110       itemvalues[6].Value = true;
    111       subscription.Write(itemvalues);
    112       Thread.Sleep(500);//暂停线程以让DataChange反映
    113       //以下写部分组
    114       ItemValue[] itemvalues2 = new ItemValue[3];
    115       itemvalues2[0] = new ItemValue((ItemIdentifier)subscription.Items[1]);//TItem类要先转成ItemIdentifier,才能转成ItemValue
    116       itemvalues2[1] = new ItemValue((ItemIdentifier)subscription.Items[2]);//TItem类要先转成ItemIdentifier,才能转成ItemValue
    117       itemvalues2[2] = new ItemValue((ItemIdentifier)subscription.Items[3]);//TItem类要先转成ItemIdentifier,才能转成ItemValue   
    118       itemvalues2[0].Value = 12;
    119       itemvalues2[1].Value = 112;
    120       itemvalues2[2].Value = 122;
    121       subscription.Write(itemvalues2);
    122 
    123       //以下测试异步写
    124       Thread.Sleep(500);//暂停线程以让DataChange反映
    125       subscription.Write(itemvalues, 1, this.OnWriteComplete, out quest);
    126 
    127       //END
    128       Console.WriteLine("************************************** hit <return> to close...");
    129       Console.ReadLine();
    130 
    131       //取消回调事件
    132       subscription.DataChanged -= new Opc.Da.DataChangedEventHandler(this.OnDataChange);
    133       //移除组内item
    134       subscription.RemoveItems(subscription.Items);
    135       //结束:释放各资源
    136       m_server.CancelSubscription(subscription);//m_server前文已说明,通知服务器要求删除组。
    137       subscription.Dispose();//强制.NET资源回收站回收该subscription的所有资源。
    138       m_server.Disconnect();//断开服务器连接
    139     }
    140 
    141     //DataChange回调
    142     public void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
    143     {
    144       Console.WriteLine("_____________________DataChange事件");
    145       foreach (ItemValueResult item in values)
    146       {
    147         Console.WriteLine("发生DataChange事件");
    148         Console.WriteLine("ITEM:{0},value:{1}", item.ItemName,item.Value);
    149         Console.WriteLine("ITEM:{0},value:{1}", item.Quality,item.Timestamp);
    150         Console.WriteLine("事件信号句柄为{0}", requestHandle);
    151 
    152       }
    153 
    154     }
    155 
    156     //ReadComplete回调
    157     public void OnReadComplete(object requestHandle, Opc.Da.ItemValueResult[] values)
    158     {
    159       /*Console.WriteLine("发生异步读name:{0},value:{1}", values[0].ItemName, values[0].Value);
    160       if ((int)requestHandle == 1)
    161         Console.WriteLine("事件信号句柄为{0}", requestHandle);*/
    162     }
    163 
    164     //WriteComplete回调
    165     public void OnWriteComplete(object requestHandle, Opc.IdentifiedResult[] values)
    166     {
    167       /*Console.WriteLine("发生异步写name:{0},value:{1}", values[0].ItemName, values[0].GetType());
    168       if ((int)requestHandle == 2)
    169         Console.WriteLine("事件信号句柄为{0}", requestHandle);*/
    170     }
    171 
    172     static void Main(string[] args)
    173     {
    174       Tester tst = new Tester();
    175       tst.Work();
    176     }
    177   }
    178 }

    用OpcNetApi.dll连接上opc服务器后,如何展现opc服务器上所有的数据项名。
    是不是用BrowseElement[] elements = m_server.Browse(itemID, m_filters, out position)函数,如果是这个函数怎么用啊,参数是什么?有没有例子?

    http://bbs.csdn.net/topics/390777396
    
     Opc.Da.BrowseFilters filters = new Opc.Da.BrowseFilters();
                filters.BrowseFilter = Opc.Da.browseFilter.all;
                Opc.Da.BrowsePosition pos = null;
    
                Opc.Da.BrowseElement[] elements = m_server.Browse(null, filters,out pos);
  • 相关阅读:
    Word中如何删除目录页的页码
    在java程序代码中打开文件
    Web程序报错:Error instantiating servlet
    将日期类型数据写入到数据库中
    《将博客搬至CSDN》
    软件测试工程师常见的面试题
    我对需求文档的理解
    简单的学生管理系统,实现增删改查
    如何求两个数的最大公约数
    【转载】LoadRunner监控window系统各项指标详解
  • 原文地址:https://www.cnblogs.com/zouhao/p/6386805.html
Copyright © 2011-2022 走看看