• C# OPC使用


    OPC客户端操作主要有4个步骤:

    1.连接OPC服务器

    2.创建组和项

    3.读写数据

    4.断开服务器连接

    全部代码:

    View Code
    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时无此问题

  • 相关阅读:
    .NET中使用嵌入的资源
    C#操作注册表
    .Net中大数加减乘除运算
    CYQ.Data 轻量数据层之路 V4.5 版本发布[更好的使用体验,更优的缓存机制]
    关于性能比较的应用误区
    秋色园QBlog技术原理解析:性能优化篇:打印页面SQL,全局的SQL语句优化(十三)
    CYQ.DBImport 数据库反向工程及批量导数据库工具 V1.0 发布
    框架设计之菜鸟漫漫江湖路系列 一:菜鸟入门
    MySql折腾小记二:text/blog类型不允许设置默认值,不允许存在两个CURRENT_TIMESTAMP
    CYQ.Data.Xml XmlHelper 助你更方便快捷的操作Xml/Html
  • 原文地址:https://www.cnblogs.com/punkrocker/p/2666307.html
Copyright © 2020-2023  润新知