zoukankan      html  css  js  c++  java
  • OPC DA 客户端实例[.net]

    来源:https://blog.csdn.net/ryanzll/article/details/42109739
     
    准备工作
    下载   Opc.NET Api,可以从 OPC Foundation网站,也可以google,csdn上也有。下载到安装包之后,安装即可,相应的文件会拷贝到
    “C:WindowsassemblyGAC_MSILOpcNetApi2.0.2.0__9a40e993cbface53OpcNetApi.dll”
    “C:WindowsassemblyGAC_MSILOpcNetApi.Com2.0.1.0__9a40e993cbface53OpcNetApi.Com.dll”
    ...
    这样在这台电脑上的所有.net项目都可以使用   Opc.NET Api了。但这也有不方便的地方,如果是团队开发,那么就要求团队所有人都必须按照这个库。那么你也可以把这些dll从GAC里面放到你工程的第三方库中,然后让工程的引用指向那里就可以了。
    BTW:只要在本地新建个指向本机”C$Windows “的网络映射,然后通过这个映射就可以任性的操作这些文件了。
     
    新建工程
    打开VS,新建c#工程,并添加OpcNetApi.dll,OpcNetApi.Com.dll的引用
     
    读写数据项(Item)
     
            static void Main( string [] args)
            {
                // Create a server object and connect to the TwinCATOpcServer
                Opc. URL url = new Opc. URL ( "opcda://localhost/BECKHOFF.TwinCATOpcServerDA" );
                Opc.Da. Server server = null ;
                OpcCom. Factory fact = new OpcCom. Factory ();
                server = new Opc.Da. Server (fact, null );
                server.Connect(url, new Opc. ConnectData ( new System.Net. NetworkCredential ()));
     
                // Create a group
                Opc.Da. Subscription group;
                Opc.Da. SubscriptionState groupState = new Opc.Da. SubscriptionState ();
                groupState.Name = "Group" ;
                groupState.Active = false ;
                group = (Opc.Da. Subscription )server.CreateSubscription(groupState);
     
                // add items to the group
                Opc.Da. Item [] items = new Opc.Da. Item [3];
                items[0] = new Opc.Da. Item ();
                items[0].ItemName = "PLC1.Value1" ;
                items[1] = new Opc.Da. Item ();
                items[1].ItemName = "PLC1.Value2" ;
                items[2] = new Opc.Da. Item ();
                items[2].ItemName = "PLC1.Value3" ;
                items = group.AddItems(items);
     
                // write items
                Opc.Da. ItemValue [] writeValues = new Opc.Da. ItemValue [3];
                writeValues[0] = new Opc.Da. ItemValue ();
                writeValues[1] = new Opc.Da. ItemValue ();
                writeValues[2] = new Opc.Da. ItemValue ();
                writeValues[0].ServerHandle = group.Items[0].ServerHandle;
                writeValues[0].Value = 0;
                writeValues[1].ServerHandle = group.Items[1].ServerHandle;
                writeValues[1].Value = 0;
                writeValues[2].ServerHandle = group.Items[2].ServerHandle;
                writeValues[2].Value = 0;
                Opc. IRequest req;
                group.Write(writeValues, 321, new Opc.Da. WriteCompleteEventHandler (WriteCompleteCallback), out req);
     
                // and now read the items again
                group.Read(group.Items, 123, new Opc.Da. ReadCompleteEventHandler (ReadCompleteCallback), out req);
                Console .ReadLine();
            }
     
            static void WriteCompleteCallback( object clientHandle, Opc. IdentifiedResult [] results)
            {
                Console .WriteLine( "Write completed" );
                foreach (Opc. IdentifiedResult writeResult in results)
                {
                    Console .WriteLine( " {0} write result: {1}" , writeResult.ItemName, writeResult.ResultID);
                }
                Console .WriteLine();
            }
     
            static void ReadCompleteCallback( object clientHandle, Opc.Da. ItemValueResult [] results)
            {
                Console .WriteLine( "Read completed" );
                foreach (Opc.Da. ItemValueResult readResult in results)
                {
                    Console .WriteLine( " {0} val:{1}" , readResult.ItemName, readResult.Value);
                }
                Console .WriteLine();
            }
     
    这里有个要注意的地方,在创建 Opc.Da.Subscription 的时候,会设置其Name属性,这个名称仅仅是给 Subscription 个名字,与OPC服务器中的组(group)名是两回事。
    同时,在创建Item的时候,如果它是属于某个group的话,在设置其ItemName属性的时候,需要加上group的名字。
    下面以MatrikonOPC Server for Simulation为例,如下图。当中有个名为"Group"的组,其下面有名为“Item”数据项,那么连接这个服务器,创建Item的时候,Item的名字应该是“ New_Intouch_000.Item ”。否则连接不上的,但是大小写貌似不区分的。
    监视数据项变化(subscriptions)
    所谓监视数据项变化,就是添加关心的数据项,也可设定更新频率,然后当这些数据项的值变化时就会通知你(事件机制)。

            static void Main(string[] args)

            {

                // Create a server object and connect to the TwinCATOpcServer

                Opc.URL url = new Opc.URL("opcda://localhost/BECKHOFF.TwinCATOpcServerDA");

                Opc.Da.Server server = null;

                OpcCom.Factory fact = new OpcCom.Factory();

                server = new Opc.Da.Server(fact, null);

                server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

                // Create a group

                Opc.Da.Subscription group;

                Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();

                groupState.Name = "Group";

                groupState.Active = true;

                group = (Opc.Da.Subscription)server.CreateSubscription(groupState);

                // add items to the group.

                Opc.Da.Item[] items = new Opc.Da.Item[3];

                items[0] = new Opc.Da.Item();

                items[0].ItemName = "PLC1.dyn_R8[1]";

                items[1] = new Opc.Da.Item();

                items[1].ItemName = "PLC1.dyn_R4[1]";

                items[2] = new Opc.Da.Item();

                items[2].ItemName = "PLC1.dyn_I4[1]";

                items = group.AddItems(items);

                group.DataChanged += new Opc.Da.DataChangedEventHandler(OnTransactionCompleted);

                Console.ReadLine();

            }

            static void OnTransactionCompleted( object group, object hReq, Opc.Da.ItemValueResult[] items)

            {

                Console.WriteLine("------------------->");

                Console.WriteLine("DataChanged ...");

                for (int i = 0; i < items.GetLength(0); i++)

                {

                    Console.WriteLine("Item DataChange - ItemId: {0}", items[i].ItemName);

                    Console.WriteLine(" Value: {0,-20}", items[i].Value);

                    Console.WriteLine(" TimeStamp: {0:00}:{1:00}:{2:00}.{3:000}",

                    items[i].Timestamp.Hour,

                    items[i].Timestamp.Minute,

                    items[i].Timestamp.Second,

                    items[i].Timestamp.Millisecond);

                }

                Console.WriteLine("-------------------<");

                }
    如果需要撤销监视,可以通过“Array.Clear(subscription.Items,0,subscription.Items.Length)”的方式。此外添加监视必须调用Subscription.AddItems函数,通过直接修改Subscription.Items的方式貌似无效。
    “OnTransactionCompleted”第一次被调用会传回所有监视项(很好理解,如果都没有变化,你怎么知道当前是什么值),第二次及以后 传回的是监视的数据项中变化项。
     

    //删除仪表
    //Opc.Da.Item[] items1 = new Opc.Da.Item[1];
    //items1[0] = items[1];
    //group.RemoveItems(items1);

  • 相关阅读:
    idea安装破解
    项目中邮件发送
    (转)四种复制文件的效率高低
    备份
    关于时间
    转 累加含小数点的数据:parseFloat、toFixed等
    转 Java将PDF转换成图片
    (转)JAVA实现SFTP实例
    获取浏览器参数
    js 中日期转换
  • 原文地址:https://www.cnblogs.com/zouhao/p/14011499.html
Copyright © 2011-2022 走看看