本人學習了一下.Net,恰好,51自學網,又要用這個。而網上很多VC6,VB6,VB .Net的但,很少C#的。現在研究一下,給出例子:
測試平台,是VS2008,KEPServer,OpcNetApi.dll和OpcNetApi.Com.dll。當然我也同時安裝了,51自學網,西門子的Net2006和Step7,其中Net2006是負責OPC的,可能會在系統中創建一些dll之類的,自學,因為我的程序換到一台沒有Net2006的機子上既然有問題,不知其電腦問題還是因為沒裝Net2006。不過,理論上,OpcNetApi.dll和OpcNetApi.Com.dll足矣。還有,Net2006的安裝路徑下會有寫dll和例子。例如我的是默認安裝,C:\Program Files\Siemens\SIMATIC.NET\opc2\samples下有Automation、Custom、dotnet、xml四種應用的例子,有興趣的可以研究研究。
下面給出我的代碼,是基於控制台的,代碼不長,如果 您有C#經驗和OPC基礎應不難理解,而且還有注釋,希望您能喜歡:)
以下是Program.cs,有些測試操作我注釋掉了,大家也可以玩玩。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 using Opc; 7 using Opc.Da; 8 using OpcCom; 9 10 namespace OPCAPITest 11 { 12 class Tester 13 { 14 private Opc.Da.Server m_server = null;//定義數據存取服務器 15 private Opc.Da.Subscription subscription = null;//定義組對象(訂閱者) 16 private Opc.Da.SubscriptionState state = null;//定義組(訂閱者)狀態,相當於OPC規范中組的參數 17 private Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//定義枚舉基於COM服務器的接口,用來搜索所有的此類服務器。 18 public void Work() 19 { 20 //查詢服務器 21 Opc.Server[] servers = m_discovery.GetAvailableServers(Specification.COM_DA_20,"TX1" , null); 22 //daver表示數據存取規范版本,Specification.COMDA_20等於2.0版本。 23 //host為計算機名,null表示不需要任何網絡安全認證。 24 if (servers != null) 25 { 26 foreach (Opc.Da.Server server in servers) 27 { 28 //server即為需要連接的OPC數據存取服務器。 29 if (String.Compare(server.Name,"TX1.KEPware.KEPServerEx.V4",true) == 0)//為true忽略大小寫 30 //if (String.Compare(server.Name, "localhost.KEPware.KEPServerEx.V4", true) == 0)//不帶計算機名為本地訪問 31 { 32 m_server = server;//建立連接。 33 break; 34 } 35 } 36 } 37 38 //連接服務器 39 if (m_server != null)//非空連接服務器 40 m_server.Connect(); 41 else 42 return; 43 44 //設定組狀態 45 state = new Opc.Da.SubscriptionState();//組(訂閱者)狀態,相當於OPC規范中組的參數 46 state.Name = "測試";//組名 47 state.ServerHandle = null;//服務器給該組分配的句柄。 48 state.ClientHandle = Guid.NewGuid().ToString();//客戶端給該組分配的句柄。 49 state.Active = true;//激活該組。 50 state.UpdateRate = 100;//刷新頻率為1秒。 51 state.Deadband = 0;// 死區值,設為0時,服務器端該組內任何數據變化都通知組。 52 state.Locale = null;//不設置地區值。 53 54 //添加組 55 subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//創建組 56 //定義Item列表 57 //對應類型為:{Byte,Byte,Char,Short,String,Word,Boolean} 58 string[] itemName = { "BPJ.DB1.dbb0", "BPJ.DB1.dbb1", "BPJ.DB1.dbc2", "BPJ.DB1.dbi3", 59 "BPJ.DB1.dbs4", "BPJ.DB1.dbw5", "BPJ.DB1.dbx6" }; 60 61 //定義item列表 62 Item[] items = new Item[7];//定義數據項,即item 63 int i; 64 for (i = 0; i < items.Length; i++)//item初始化賦值 65 { 66 items[i] = new Item();//創建一個項Item對象。 67 items[i].ClientHandle = Guid.NewGuid().ToString();//客戶端給該數據項分配的句柄。 68 items[i].ItemPath = null; //該數據項在服務器中的路徑。 69 items[i].ItemName = itemName[i]; //該數據項在服務器中的名字。 70 } 71 72 //添加Item 73 subscription.AddItems(items); 74 75 //注冊回調事件 76 subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange); 77 78 //以下測試同步讀 79 //以下讀整個組 80 ItemValueResult[] values = subscription.Read(subscription.Items); 81 //以下檢驗item的quality 82 /*if (values[0].Quality .Equals(Opc.Da.Quality.Good)) 83 Console.WriteLine("檢測質量成功!");*/ 84 //以下讀部分組 85 Item[] r_items=new Item[2]; 86 for (i = 1; i < 3; i++) 87 r_items[i-1] = subscription.Items[i]; 88 ItemValueResult[] values2 = subscription.Read(r_items); 89 //以下遍歷讀到的全部值 90 /*foreach (ItemValueResult value in values2) 91 { 92 Console.WriteLine("同步讀:ITEM:{0},value:{1},quality:{2}", value.ItemName, value.Value, value.Quality); 93 }*/ 94 95 //以下測試異步讀 96 IRequest quest=null ; 97 subscription.Read(subscription.Items,1,this.OnReadComplete,out quest ) ; 98 99 //以下測試同步寫 100 //以下寫整個組 101 ItemValue[] itemvalues= new ItemValue[subscription.Items.Length]; 102 for (i = 0; i < subscription.Items.Length; i++) 103 itemvalues[i] = new ItemValue((ItemIdentifier)subscription.Items[i]); 104 itemvalues[0].Value = 255; 105 itemvalues[1].Value = 126; 106 itemvalues[2].Value = 'A'; 107 itemvalues[3].Value = -128; 108 itemvalues[4].Value = "Good Lucky!"; 109 itemvalues[5].Value = 65535; 110 itemvalues[6].Value = true; 111 subscription.Write(itemvalues); 112 Thread.Sleep(500);//暫停線程以讓DataChange反映 113 //以下寫部分組 114 ItemValue[] itemvalues2 = new ItemValue[3]; 115 itemvalues2[0] = new ItemValue((ItemIdentifier)subscription.Items[1]);//TItem類要先轉成ItemIdentifier,才能轉成ItemValue 116 itemvalues2[1] = new ItemValue((ItemIdentifier)subscription.Items[2]);//TItem類要先轉成ItemIdentifier,才能轉成ItemValue 117 itemvalues2[2] = new ItemValue((ItemIdentifier)subscription.Items[3]);//TItem類要先轉成ItemIdentifier,才能轉成ItemValue 118 itemvalues2[0].Value = 12; 119 itemvalues2[1].Value = 112; 120 itemvalues2[2].Value = 122; 121 subscription.Write(itemvalues2); 122 123 //以下測試異步寫 124 Thread.Sleep(500);//暫停線程以讓DataChange反映 125 subscription.Write(itemvalues, 1, this.OnWriteComplete, out quest); 126 127 //END 128 Console.WriteLine("************************************** hit <return> to close..."); 129 Console.ReadLine(); 130 131 //取消回調事件 132 subscription.DataChanged -= new Opc.Da.DataChangedEventHandler(this.OnDataChange); 133 //移除組內item 134 subscription.RemoveItems(subscription.Items); 135 //結束:釋放各資源 136 m_server.CancelSubscription(subscription);//m_server前文已說明,通知服務器要求刪除組。 137 subscription.Dispose();//強制.NET資源回收站回收該subscription的所有資源。 138 m_server.Disconnect();//斷開服務器連接 139 } 140 141 //DataChange回調 142 public void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values) 143 { 144 Console.WriteLine("_____________________DataChange事件"); 145 foreach (ItemValueResult item in values) 146 { 147 Console.WriteLine("發生DataChange事件"); 148 Console.WriteLine("ITEM:{0},value:{1}", item.ItemName,item.Value); 149 Console.WriteLine("ITEM:{0},value:{1}", item.Quality,item.Timestamp); 150 Console.WriteLine("事件信號句柄為{0}", requestHandle); 151 152 } 153 154 } 155 156 //ReadComplete回調 157 public void OnReadComplete(object requestHandle, Opc.Da.ItemValueResult[] values) 158 { 159 /*Console.WriteLine("發生異步讀name:{0},value:{1}", values[0].ItemName, values[0].Value); 160 if ((int)requestHandle == 1) 161 Console.WriteLine("事件信號句柄為{0}", requestHandle);*/ 162 } 163 164 //WriteComplete回調 165 public void OnWriteComplete(object requestHandle, Opc.IdentifiedResult[] values) 166 { 167 /*Console.WriteLine("發生異步寫name:{0},value:{1}", values[0].ItemName, values[0].GetType()); 168 if ((int)requestHandle == 2) 169 Console.WriteLine("事件信號句柄為{0}", requestHandle);*/ 170 } 171 172 static void Main(string[] args) 173 { 174 Tester tst = new Tester(); 175 tst.Work(); 176 } 177 } 178 }
用OpcNetApi.dll連接上opc服務器后,如何展現opc服務器上所有的數據項名。
是不是用BrowseElement[] elements = m_server.Browse(itemID, m_filters, out position)函數,如果是這個函數怎么用啊,參數是什么?有沒有例子?
http://bbs.csdn.net/topics/390777396 Opc.Da.BrowseFilters filters = new Opc.Da.BrowseFilters(); filters.BrowseFilter = Opc.Da.browseFilter.all; Opc.Da.BrowsePosition pos = null; Opc.Da.BrowseElement[] elements = m_server.Browse(null, filters,out pos);