第一個隨筆,使用了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
2, 查看OPC手冊,不過是英文的VB版本的,以上資料能夠在個人百度網盤裏面下載.或者私信我.異步
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); } }
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
其同時支持IP或者計算機名的方式
本地計算機第二個參數.第一個參數是服務器名稱.
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.
其餘還有一些異步寫入啊,什麼的,能夠參考手冊.