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時無此問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM