Search code examples
c#plcopcopc-da

How to read values from OPC


I am trying to read values from OPC server using Interop.OPCAutomation.dll

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");
        }
        }
    }
}

This code is not returning the values from OPC server. It is giving error on this line

temp += ItemValues.GetValue(count).ToString();

Error

Object reference not set to an instance of an object

Solution

  • First, check whether ItemValues is not null. It probably isn't, and the problem is likely to be in the null-ness of ItemValues.GetValue(count), but it is worth checking anyway. You never know what a server will return...

    Now, to the actual answer: You should check the corresponding element in Qualities first, i.e. Qualities.GetValue(count) in your approach. It is likely that the quality is Bad, and therefore the value is not valid (and can thus be a null reference). You need to decode the quality bit field according to its meaning, as per the OPC specs, but in simplified (and slightly incorrect, but generally working) sense, qualities below 64 are not good, and there are no data values associated with them.