1.该教程是C#通过OPCDAAuto.dll连接Kepserver软件,可以实现与PLC和仪表等硬件通讯。该教程有两个程序,一个是测试程序,可以获取本机所有OPC服务器,连接断开指定的OPC服务器,获取服务器所有条目信息,对变量读写操作。
2.另一个程序是实际项目源码,连接西门子PLC,监控质量数据,存储数据到SQL数据库里,可以查询历史数据导出等功能。
3.该教程很适合学习,需要全套源码+V:1357448516或者+qq:584472557
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OPCAutomation;
namespace OPCTest
{
/// <summary>
/// 名称:OPC Automation DA 2.0 测试
/// 结果:本机OPC服务器测试成功
///
///
/// </summary>
public partial class OPCTest : Form
{
private OPCAutomation.OPCServer opcServer;//OPC server
private OPCAutomation.OPCGroups opcGroups;//OPC groups
private OPCAutomation.OPCGroup opcGroup;//OPC group
private OPCAutomation.OPCItems opcItems; //OPC items
private static int ClientHandle = 1;//客户端ID标识
public OPCTest()
{
InitializeComponent();
}
/// <summary>
/// 枚举本地或远程计算机上的OPC服务(由于DCOM配置问题,远程尚未成功)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
try
{
this.button3.Enabled = false;
this.comboBox1.Items.Clear();
// opcServer = new OPCServerClass();
opcServer = new OPCServer();
System.Net.IPHostEntry ipentry = new System.Net.IPHostEntry();
ipentry = System.Net.Dns.GetHostEntry(textBox1.Text);
string sname = System.Net.Dns.GetHostName();
object serverList = opcServer.GetOPCServers(ipentry.HostName);
foreach (string obj in (Array)serverList)
{
this.comboBox1.Items.Add(obj);
}
if (this.comboBox1.Items.Count > 0)
{
this.comboBox1.SelectedIndex = 0;
this.button1.Enabled = true;
this.button2.Enabled = true;
}
}
catch (Exception se)
{
MessageBox.Show(se.Message);
this.comboBox1.Items.Clear();
}
finally
{
this.button3.Enabled = true;
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.button1.Enabled = false;
this.button2.Enabled = false;
this.button4.Enabled = false;
this.dataGridView1.Rows.Clear();
}
/// <summary>
/// 连接OPC服务器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
try
{
opcServer.Connect(this.comboBox1.Text, "");
this.RecurBrowse(opcServer.CreateBrowser());
if (!this.CreateGroup())
{
return;
}
this.button4.Enabled = true;
}
catch (Exception se)
{
MessageBox.Show(se.Message);
}
}
/// <summary>
/// 创建组,并加入数据交换事件
/// </summary>
/// <returns></returns>
private bool CreateGroup()
{
try
{
this.opcGroups = opcServer.OPCGroups;
this.opcGroup = opcGroups.Add("MyGroup");
this.SetGroupProperty();//设置组属性
opcGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcGroup_DataChange);
opcGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(opcGroup_AsyncWriteComplete);
opcItems = opcGroup.OPCItems;
return true;
}
catch(Exception e)
{
MessageBox.Show(e.Message);
return false;
}
}
/// <summary>
/// 异步写数据完成时触 发的事件
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="Errors"></param>
private void opcGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
this.l_ErrorsWrite.Text = "";
for (int i = 1; i <= NumItems; i++)
{
this.l_ErrorsWrite.Text = "客户端ID:" + ClientHandles.GetValue(i).ToString() + " 错误:" + Errors.GetValue(i).ToString();
}
}
/// <summary>
/// 数据交换事件
/// </summary>
/// <param name="TransactionID">传输ID</param>
/// <param name="NumItems">传输的ITEM数</param>
/// <param name="ClientHandles">客户端标识</param>
/// <param name="ItemValues">ITEM值</param>
/// <param name="Qualities">品质</param>
/// <param name="TimeStamps">时间戳</param>
private void opcGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
try
{
textBox1.Text = NumItems.ToString();
for (int i = 1; i <= NumItems; i++)
{
//下面这种对应数据的方法是为了方便,有时候会出一些小错误。
int m = (int)ClientHandles.GetValue(i) - 1;
dataGridView1.Rows[m].Cells[1].Value = (TransactionID.ToString());
dataGridView1.Rows[m].Cells[2].Value = (ItemValues.GetValue(i).ToString());
dataGridView1.Rows[m].Cells[3].Value = (Qualities.GetValue(i).ToString());
dataGridView1.Rows[m].Cells[4].Value = (TimeStamps.GetValue(i).ToString());
dataGridView1.Rows[m].Cells[5].Value = ClientHandles.GetValue(i).ToString();
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 设置组属性
/// </summary>
/// <returns></returns>
private bool SetGroupProperty()
{
try
{
opcServer.OPCGroups.DefaultGroupIsActive = Convert.ToBoolean(this.txtDGA.Text);
opcServer.OPCGroups.DefaultGroupDeadband = (float)Convert.ToDouble(this.txtDGD.Text);
opcGroup.IsActive = Convert.ToBoolean(txtActive.Text);
opcGroup.UpdateRate = Convert.ToInt32(txtUpDate.Text);
opcGroup.IsSubscribed = Convert.ToBoolean(txtSubscrib.Text);//如设置为false,则数据不更新
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return false;
}
}
/// <summary>
/// 获取节点
/// </summary>
/// <param name="opcBrowser"></param>
private void RecurBrowse(OPCBrowser opcBrowser)
{
opcBrowser.ShowBranches();//展开分支
opcBrowser.ShowLeafs(true);//展开叶子节点
foreach (object obj in opcBrowser)
{
this.listBox1.Items.Add(obj.ToString());//将获取的所有条目在列表中列示出来
}
}
/// <summary>
/// 双击列表中的条目,将其路径
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void listBox1_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
this.txtClientPath.Text = this.listBox1.SelectedItem.ToString();
}
/// <summary>
/// 添加监视ITEM到表中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
try
{
OPCItem item1 = opcItems.AddItem(this.txtClientPath.Text, ClientHandle);
this.dataGridView1.Rows.Add(new object[] { this.txtClientPath.Text.Split('.')[this.txtClientPath.Text.Split('.').Length -1], "", "", "", "", "", item1.ServerHandle.ToString() });
this.txtClientName.Text = string.Empty;
this.txtClientPath.Text = string.Empty;
ClientHandle++;
}
catch(Exception se)
{
MessageBox.Show(se.Message);
}
}
/// <summary>
/// 断开OPC连接
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
if (null != opcGroup)
{
opcGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(opcGroup_DataChange);
opcGroup.AsyncWriteComplete -= new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(opcGroup_AsyncWriteComplete);
opcGroup = null;
}
if (null != opcServer)
{
opcServer.Disconnect();
opcServer = null;
opcItems = null;
this.comboBox1.Items.Clear();
this.comboBox1.Text = string.Empty;
this.button1.Enabled = false;
this.button2.Enabled = false;
this.listBox1.Items.Clear();
this.button4.Enabled = false;
this.dataGridView1.Rows.Clear();
ClientHandle = 1;
GC.Collect();
}
}
/// <summary>
/// 将新值写入选中的ITEM中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button5_Click(object sender, EventArgs e)
{
try
{
OPCItem item = opcItems.GetOPCItem(Convert.ToInt32(this.dataGridView1.SelectedRows[0].Cells[6].Value));//根据OPC服务端ID获取新的OPCITEM
//写多个数据时将相应的ARRAY对应即可
//MessageBox.Show(this.dataGridView1.SelectedRows[0].Cells[6].Value.ToString());
int[] ser = new int[]{0,item.ServerHandle};
//MessageBox.Show(item.ServerHandle.ToString());
Array serverHandles = (Array)ser;
Array Errors;
int TransactionID = 0;
int cancelID;
object[] value = new object[] { "", this.txtNewValue.Text }; //opc的数组是从1开始,所以这里0为空当
Array Values = (Array)value;
int ItemsNums = 1;//要写入数据的个数
opcGroup.AsyncWrite(ItemsNums, ref serverHandles, ref Values, out Errors, TransactionID, out cancelID);
this.checkBox1.Checked = false;
}
catch(Exception se)
{
MessageBox.Show(se.Message);
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (this.checkBox1.Checked)
{
if (this.dataGridView1.SelectedRows.Count > 0 && this.dataGridView1.SelectedRows[0].Cells[0].Value != null)
{
this.txtCurrentValue.Text = this.dataGridView1.SelectedRows[0].Cells[2].Value.ToString();
this.txtNewValue.Enabled = true;
this.button5.Enabled = true;
}
else
{
this.checkBox1.Checked = false;
}
}
else
{
this.txtNewValue.Enabled = false;
this.txtNewValue.Text = "";
this.txtCurrentValue.Text = "";
this.button5.Enabled = false;
}
}
private void button6_Click(object sender, EventArgs e)
{
this.SetGroupProperty();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}