如何从 OPC 读取值
How to read values from OPC
我正在尝试使用 Interop.OPCAutomation.dll
从 OPC 服务器读取值
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OPCAutomation;
namespace OPC
{
public partial class Form1 : Form
{
OPCServer ObjOPCServer;
OPCGroups ObjOPCGroups;
OPCGroup ObjOPCGroup;
string OPCServerName;
public Form1()
{
getData();
}
private void getData()
{
try
{
int count = 1;
opcServer.Connect("OPCTechs.SiemensNet30DA", "");
opcGroup = opcServer.OPCGroups.Add("MP");
opcGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcGroup_DataChange);
//Get First String
for (int i = 40; i <= 47; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Second String
for (int i = 80; i <= 91; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Third String
for (int i = 69; i >= 60; i--)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Fourth String
for (int i = 200; i <= 224; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Fifth String
for (int i = 300; i <= 849; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Sixth String
for (int i = 40; i >= 47; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
opcGroup.OPCItems.DefaultIsActive = true;
opcGroup.UpdateRate = 1000;
opcGroup.IsSubscribed = opcGroup.IsActive;
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Alert");
}
}
private void opcGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
try
{
string temp = "";
int count = 1;
for (; count <= 8; count++)
{
int ff = Convert.ToInt32(ClientHandles.GetValue(count));
//if (Convert.ToInt32(ClientHandles.GetValue(count)) == count)
temp += ItemValues.GetValue(count).ToString();
}
Textbox4.Text = temp.ToString();
temp = "";
for (; count <= 12; count++)
{
if (Convert.ToInt32(ClientHandles.GetValue(count)) == count)
temp += ItemValues.GetValue(count).ToString();
}
TextBox3.Text = temp.ToString();
temp = "";
for (; count <= 12; count++)
{
if (Convert.ToInt32(ClientHandles.GetValue(count)) == count)
temp += ItemValues.GetValue(count).ToString();
}
TextBox2.Text = temp.ToString();
temp = "";
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Alert");
}
}
}
}
此代码未从 OPC 服务器返回值。这条线出错
temp += ItemValues.GetValue(count).ToString();
错误
Object reference not set to an instance of an object
首先,检查ItemValues 是否不为空。它可能不是,问题很可能出在 ItemValues.GetValue(count) 的空性上,但无论如何都值得检查。你永远不知道服务器会 return...
现在,实际答案:您应该首先检查 Qualities 中的相应元素,即您的方法中的 Qualities.GetValue(count)。质量可能很差,因此该值无效(因此可能是空引用)。根据 OPC 规范,您需要根据其含义对质量位字段进行解码,但在简化(并且稍微不正确,但通常有效)的意义上,低于 64 的质量不好,并且没有与之关联的数据值。
我正在尝试使用 Interop.OPCAutomation.dll
从 OPC 服务器读取值using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OPCAutomation;
namespace OPC
{
public partial class Form1 : Form
{
OPCServer ObjOPCServer;
OPCGroups ObjOPCGroups;
OPCGroup ObjOPCGroup;
string OPCServerName;
public Form1()
{
getData();
}
private void getData()
{
try
{
int count = 1;
opcServer.Connect("OPCTechs.SiemensNet30DA", "");
opcGroup = opcServer.OPCGroups.Add("MP");
opcGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcGroup_DataChange);
//Get First String
for (int i = 40; i <= 47; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Second String
for (int i = 80; i <= 91; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Third String
for (int i = 69; i >= 60; i--)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Fourth String
for (int i = 200; i <= 224; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Fifth String
for (int i = 300; i <= 849; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Sixth String
for (int i = 40; i >= 47; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
opcGroup.OPCItems.DefaultIsActive = true;
opcGroup.UpdateRate = 1000;
opcGroup.IsSubscribed = opcGroup.IsActive;
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Alert");
}
}
private void opcGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
try
{
string temp = "";
int count = 1;
for (; count <= 8; count++)
{
int ff = Convert.ToInt32(ClientHandles.GetValue(count));
//if (Convert.ToInt32(ClientHandles.GetValue(count)) == count)
temp += ItemValues.GetValue(count).ToString();
}
Textbox4.Text = temp.ToString();
temp = "";
for (; count <= 12; count++)
{
if (Convert.ToInt32(ClientHandles.GetValue(count)) == count)
temp += ItemValues.GetValue(count).ToString();
}
TextBox3.Text = temp.ToString();
temp = "";
for (; count <= 12; count++)
{
if (Convert.ToInt32(ClientHandles.GetValue(count)) == count)
temp += ItemValues.GetValue(count).ToString();
}
TextBox2.Text = temp.ToString();
temp = "";
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Alert");
}
}
}
}
此代码未从 OPC 服务器返回值。这条线出错
temp += ItemValues.GetValue(count).ToString();
错误
Object reference not set to an instance of an object
首先,检查ItemValues 是否不为空。它可能不是,问题很可能出在 ItemValues.GetValue(count) 的空性上,但无论如何都值得检查。你永远不知道服务器会 return...
现在,实际答案:您应该首先检查 Qualities 中的相应元素,即您的方法中的 Qualities.GetValue(count)。质量可能很差,因此该值无效(因此可能是空引用)。根据 OPC 规范,您需要根据其含义对质量位字段进行解码,但在简化(并且稍微不正确,但通常有效)的意义上,低于 64 的质量不好,并且没有与之关联的数据值。