赞
踩
KepServer可以将任何工业设备的通信协议转换为opc协议,然后用OPCAutomation进行上位机数据读写。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OPCAutomation; namespace KepTest1 { public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); this.Load += FrmMain_Load; } private void FrmMain_Load(object sender, EventArgs e) { this.btnRefresh_Click(btnRefresh, null); this.dataGridViewValue.AutoGenerateColumns = false; } OPCServer opcServer; OPCGroups opcGroups; OPCGroup opcGroup; OPCItems opcItems; OPCItem opcItem; //项 Dictionary<string, OPCItem> dicOpcItem = new Dictionary<string, OPCItem>(); List<OPCItem> opcItemList = new List<OPCItem>(); //项的集合 OPCBrowser opcBrowser; string strHostName = null; object opcServerList; List<OpcValue> opcValueList = new List<OpcValue>(); int clientHandle; //change句柄 int count; //异步写入相关 Array writeErrors; int cancelId; private void btnConn_Click(object sender, EventArgs e) { //连接服务器 if (opcServer != null) { opcServer = new OPCServer(); } try { opcServer.Connect(this.cmb_ServerName.Text, this.cmb_ServerNode.Text); } catch (Exception ex) { MessageBox.Show("连接失败:" + ex.Message); return; } opcBrowser = this.opcServer.CreateBrowser(); //由OPC 节点创建浏览器 opcBrowser.ShowBranches();//展示浏览器属性 opcBrowser.ShowLeafs(true); //叶节点展示 //绑定 其实是浏览器browers this.listBoxServer.Items.Clear(); foreach (var item in opcBrowser) { if (!this.listBoxServer.Items.Contains(item)) { this.listBoxServer.Items.Add(item.ToString()); } } //通信组集合 opcGroups = this.opcServer.OPCGroups; opcGroups.DefaultGroupDeadband = 0; //只要有变化,就显示出来 opcGroups.DefaultGroupIsActive = true; //opcGroups.DefaultGroupUpdateRate = 200; //200毫秒刷新一次 //通信组实例化 opcGroup = opcGroups.Add("S71500Test"); opcGroup.IsActive = true; opcGroup.IsSubscribed = true; //是否开启异步回调 opcGroup.UpdateRate = 200; opcItems = opcGroup.OPCItems; opcGroup.DataChange += OpcGroup_DataChange; } //订阅模式 private void OpcGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps) { for (int i = 0; i < NumItems; i++) { //clientHandle = Convert.ToInt32(ClientHandles.GetValue(i + 1)); //opcValueList[clientHandle - 1].Value = ItemValues.GetValue(i + 1).ToString(); //opcValueList[clientHandle - 1].InsertTime = Convert.ToDateTime(TimeStamps.GetValue(i + 1)); //this.dataGridViewValue.DataSource = null; //this.dataGridViewValue.DataSource = opcValueList; clientHandle = Convert.ToInt32(ClientHandles.GetValue(i + 1)); opcValueList[clientHandle - 1].Value = ItemValues.GetValue(i + 1).ToString(); opcValueList[clientHandle - 1].InsertTime = Convert.ToDateTime(TimeStamps.GetValue(i + 1)); opcValueList[clientHandle - 1].OPCDataType = ItemValues.GetValue(i + 1).GetType().ToString(); opcValueList[clientHandle - 1].OPCQuality = Qualities.GetValue(i + 1).ToString(); } xktTextShowBasic1.VarValue = opcValueList[0].Value; } private void btnRefresh_Click(object sender, EventArgs e) { //清空 this.cmb_ServerNode.Items.Clear(); this.cmb_ServerName.Items.Clear(); Task.Run(async () => { IPHostEntry IPhost = Dns.GetHostEntry(Environment.MachineName); if (IPhost.AddressList.Length > 0) { for (int i = 0; i < IPhost.AddressList.Length; i++) { await Task.Delay(500); string host = Dns.GetHostEntry(IPhost.AddressList[i]).HostName;//计算机名称 if (!this.cmb_ServerNode.Items.Contains(host)) { this.cmb_ServerNode.Invoke(new Action(() => { this.cmb_ServerNode.Items.Add(host); })); } } } }); } //如果改变 private void cmb_ServerNode_SelectedIndexChanged(object sender, EventArgs e) { if (opcServer == null) { opcServer = new OPCServer(); } this.cmb_ServerName.Items.Clear(); strHostName = this.cmb_ServerNode.Text.Trim(); //获取主机名 try { opcServerList = opcServer.GetOPCServers(strHostName); //object serviceList = KepServer.GetOPCServers(this.cmb_ServerNode.Text); Task.Run(async () => { foreach (var item in (Array)opcServerList) { await Task.Delay(500); if (!this.cmb_ServerName.Items.Contains(item)) { this.cmb_ServerName.Invoke(new Action(() => { this.cmb_ServerName.Items.Add(item); })); } } }); } catch (Exception) { } } private void listBoxServer_MouseDoubleClick(object sender, MouseEventArgs e) { opcValueList.Add(new OpcValue()); opcValueList[count].Name = this.listBoxServer.Text.Trim(); opcItem = opcItems.AddItem(this.listBoxServer.Text.Trim(), count + 1); opcItemList.Add(opcItem); count += 1; } //读取 private void button1_Click(object sender, EventArgs e) { opcValueList.Add(new OpcValue() { Name = "MD200",ItemId = "Siemens1500.siemens1513.MD200" }); opcValueList.Add(new OpcValue() { Name = "DB24DBW8", ItemId = "Siemens1500.siemens1513.DB24DBW8" }); opcValueList.Add(new OpcValue() { Name = "DB24DBD34",ItemId = "Siemens1500.siemens1513.DB24DBD34" }); //opcServer通过Ip 端口号得到: opcServer.Connect(this.cmb_ServerName.Text, this.cmb_ServerNode.Text); //opcGroups 由Opc服务器得到:opcGroups = this.opcServer.OPCGroups; //opcGroup 由 opcGroups 实例化得到:opcGroup = opcGroups.Add("S71500Test"); //opcItems由opcGroup中得到: opcItems = opcGroup.OPCItems; 而来 实例化opcItems 得到 opcItem //做集合opcItem 方便取出opcItem,方便写变量 for (int i = 0; i < opcValueList.Count; i++) { opcItem = opcItems.AddItem(opcValueList[i].ItemId, i + 1); opcItemList.Add(opcItem); dicOpcItem.Add(opcValueList[i].Name, opcItem); } } private void btnWrite_Click(object sender, EventArgs e) { string value = txtWrite.Text.Trim(); //同步写入 //dicOpcItem["MD200"].Write(value); //异步写入 int[] reServerHandle = new int[2] { 0, dicOpcItem["MD200"].ServerHandle }; Array arrayReServerHandle = reServerHandle.ToArray(); object[] reValue = new object[2] { "", value}; Array values = reValue.ToArray(); opcGroup.AsyncWrite(1, ref arrayReServerHandle, ref values, out writeErrors, 2022, out cancelId); } private void btnDisc_Click(object sender, EventArgs e) { opcServer.Disconnect(); Environment.Exit(0); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace KepTest1 { public class OpcValue { public int Id { get; set; } public string ItemId { get; set; } public string Name { get; set; } public string Value { get; set; } //通信质量 public string OPCQuality { get; set; } //ClientHandle public int ClientHandle { get; set; } public string OPCDataType { get; set; } public DateTime InsertTime { get; set; } } }
KepServer配置:
西门子PLC配置:
#T1(IN := #start, PT := t#1S); #C1(CU := #T1.Q, R := #reset, PV := 30000); IF #T1.Q THEN RESET_TIMER(#T1); ; END_IF; IF #start THEN "OpcDb".ushort[1] := #C1.CV; "OpcDb".ushort[2] := "OpcDb".ushort[1] + 1; "OpcDb".ushort[3] := "OpcDb".ushort[2] + 1; "OpcDb".ushort[4] := "OpcDb".ushort[3] + 1; "OpcDb".ushort[5] := "OpcDb".ushort[4] + 1; "OpcDb".ushort[6] := "OpcDb".ushort[5] + 1; "MD204" := "OpcDb".ushort[6] + 1.1; "MD208" := "OpcDb".ushort[6] + 1.2; "MD200" := "OpcDb".ushort[6] + 5.5; "OpcDb".float[0] := "OpcDb".ushort[6] + 6.6; "OpcDb".float[1] := "OpcDb".ushort[6] + 7.1; "OpcDb".float[2] := "OpcDb".ushort[6] + 8.1; "OpcDb".float[3] := "OpcDb".ushort[6] + 9.9; END_IF;
//opcServer通过Ip 端口号得到: opcServer.Connect(this.cmb_ServerName.Text, this.cmb_ServerNode.Text);
//opcGroups 由Opc服务器得到:opcGroups = this.opcServer.OPCGroups;
//opcGroup 由 opcGroups 实例化得到:opcGroup = opcGroups.Add("S71500Test");
//opcItems由opcGroup中得到: opcItems = opcGroup.OPCItems; 而来 实例化opcItems 得到 opcItem
//做集合opcItem 方便取出opcItem,方便写变量
需要先注册OPCDA,在System32 和syswow64中有OPCDAAuto.dll。注册后就可以引入dll了,引入之后就有了using OPCAutomation
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。