我正在尝试使用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
答案 0 :(得分:1)
首先,检查ItemValues是否为空。它可能不是,问题很可能是ItemValues.GetValue(count)的无效,但无论如何都值得检查。你永远不知道服务器会返回什么......
现在,到实际答案:您应首先检查质量中的相应元素,即您的方法中的Qualities.GetValue(count)。质量很可能是坏的,因此该值无效(因此可以是空引用)。根据OPC规范,您需要根据其含义解码质量位字段,但是在简化(略微不正确但通常有效)的意义上,64以下的质量不好,并且没有与之关联的数据值。