C#開發OPC客戶端

第一個隨筆,使用了OPEN Live Write,做爲客戶端.最近使用c#開發一個小軟件,主要功能是OPC客戶端.之後會開發各種別的協議,做爲,協議的轉發棧.node

由於我本人是搞自動化的,因此搞自動化小夥伴像我這樣喜歡編程的可能有,可是通常是邏輯思惟強,可是底子相對仍是弱的.編程

1,C# 開發OPC的準備工做c#

            軟件:VS2019;數組

            DLL:C:\Program Files (x86)\Common Files\MatrikonOPC\Common\OPCDAAuto.dll服務器

            而且將其拷貝到C:\Windows\SysWOW64中,而且使用DLL註冊.(記得註冊必須在這個文件夾中)網絡

            而後在,VS2019的引用添加引用dom

image

2, 查看OPC手冊,不過是英文的VB版本的,以上資料能夠在個人百度網盤裏面下載.或者私信我.異步

image

3, 如何查詢 opc服務器數量和鏈接服務器函數

 private void BtGetList_Click(object sender, EventArgs e)
        {
            KepServer = new OPCServer();

            MessageBox.Show(Environment.MachineName);

            object serverList = KepServer.GetOPCServers();



            //枚舉網絡全部OPC服務器並寫入ComboBox控件



            foreach (string turn in (Array)serverList)



            {



                cmbServerName.Items.Add(turn);



            }
        }

4,鏈接服務器(能夠去下載一個MatrikonOPCSimulation)
 private void Form1_Load(object sender, EventArgs e)
        {
            KepServer = new OPCServer();
            KepServer.Connect("Matrikon.OPC.Simulation.1");
            if (KepServer.ServerState == (int)OPCServerState.OPCRunning)



            {


                tsslServerState.Text = "已鏈接到-" + KepServer.ServerName + "   ";
                opcBrowser = KepServer.CreateBrowser();

            }
            TreeNode Root = treeView1.Nodes.Add(KepServer.ServerName);
            Root.Tag = KepServer;
            opcBrowser.MoveToRoot();
            ShowInTreeView(opcBrowser,Root);
        }

其中主要函數說明:spa

image

其同時支持IP或者計算機名的方式

image

本地計算機第二個參數.第一個參數是服務器名稱.

5,對於OPCBrower 對象.

          從上面能夠看到OPCBrowser 來自 OpcServer.CreateBrower(),其主要用來查看服務器相關信息.

         其自己是一個集合(collection),可是,這個時候,其items=0;

        ShowBranchs():該函數用於將當前節點的名稱集合寫入到Collection中.

        ShowLeafs():該函數用於將當前節點的Tags 寫入到Collection中.

        ShowLeafs(True):將顯示該節點下面全部的itemsID--------------很重要,在添加ITEM時能夠用到.

private void ShowInTreeView(OPCBrowser brower,TreeNode node)
        {
            TreeNode childNode = null;
            brower.ShowBranches();
            int BranchCount = brower.Count;
            List<string> lst = null;
            if (brower.Count>0)
                //回溯的添加branch
            {
                lst = new List<string>();
                foreach (string t in brower)
                    lst.Add(t);

                foreach (string branch in lst)
                {
                     childNode = new TreeNode(branch);
                     childNode.Tag = brower.GetItemID(branch);
                     node.Nodes.Add(childNode);
                     brower.MoveDown(branch);
                     ShowInTreeView(brower, childNode);
                     brower.MoveUp();

                 }
            }

            brower.ShowLeafs();
            int LeafsCount = brower.Count;
            foreach (string leaf in brower)
            {
                childNode = new TreeNode(brower.GetItemID(leaf));
                childNode.Tag = brower.GetItemID(leaf);
                node.Nodes.Add(childNode);


            }


        }

這樣就能夠把服務器的信息讀取到樹裏面了.

brower對象主要做用就是能夠知道服務器裏面的信息了.

6,Group對象及Item對象.

首先:須要建立Group對象:

 private void Button3_Click(object sender, EventArgs e)
        {
            KepGroups = KepServer.OPCGroups;
            KepGroups.DefaultGroupIsActive = true;
            KepGroups.DefaultGroupUpdateRate = 200;
            KepGroups.DefaultGroupDeadband = 0;
            KepGroup = KepGroups.Add("mxb");
            KepGroup.IsSubscribed = true;
            KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler( DataChangeHandlerFunc);
            KepItems = KepGroup.OPCItems;
            //
            KepItem = KepItems.AddItem("Random.ArrayOfReal8", 1);
            textBox1.Text = KepItem.ServerHandle + ":" + KepItem.RequestedDataType;





        }

說明:

若是該參數是IsSubscribed=True;則其支持訂閱功能:也就是當改組中的參數有改變的時候,其會觸發DataChange事件.

其中:ItemID是一個關鍵的參數,能夠經過 OpcBrower.ShowLeafs(true)查看.

AddItem(string ItemID,int ClientHandle):其中Client Handle是客戶端自行填寫的.

一個Item 有一個ServerHandle,由服務器提供,ItemID:由服務器提供;ClientHandle:由客戶端提供.

事件處理函數

 private void DataChangeHandlerFunc(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            //
                for(int i = 1;i<=NumItems;i++)
            {
                if((int)ClientHandles.GetValue(i) == KepItem.ClientHandle)
                {

                    dynamic t = ItemValues.GetValue(i);
                    object[] ary;
                    ary = Array.ConvertAll<double, object>(t, new Converter<double, object>((x) =>x));
                    listBox1.Items.Clear();
                    listBox1.Items.AddRange(ary);


                                    }
            }

         }

使用該函數能夠快速定位數據變動的Item.注意:全部的Array都是1開頭的,因此不能直接轉換成int[]或者double[];須要編寫一個轉換

的函數,轉換成object[].另外,須要注意到 ClientHandles雖然是一個int數組,可是是沒法直接轉換到int[]的,由於首先,其起始index=1.

其餘還有一些異步寫入啊,什麼的,能夠參考手冊.

相關文章
相關標籤/搜索