• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#OPC使用

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

OPC客户端操作主要有4个步骤:

1.连接OPC服务器

2.创建组和项

3.读写数据

4.断开服务器连接

 

全部代码:

View Code
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using OPCAutomation;

namespace ConsoleOPC
{
    public class OPCClient
    {
        private OPCServer KepServer;
        private OPCGroups KepGroups;
        public OPCGroup KepGroup;
        private OPCItems KepItems;
        private OPCItem KepItem;
        int itmHandleClient = 0;
        int itmHandleServer = 0;

        public object readValue;

        public List<string> serverNames = new List<string>();
        public List<string> Tags = new List<string>();

        /// <summary>
        /// 枚举本地OPC SERVER
        /// </summary>
        public void GetOPCServers()
        {
            IPHostEntry IPHost = Dns.GetHostEntry(Environment.MachineName);

            Console.WriteLine("MAC Address:");
            foreach (IPAddress ip in IPHost.AddressList)
            {
                Console.WriteLine(ip.ToString());
            }
            Console.WriteLine("Please Enter IPHOST");

            string strHostIP = "localhost";//Console.ReadLine();

            IPHostEntry ipHostEntry = Dns.GetHostEntry(strHostIP);
            try
            {
                KepServer = new OPCServer();
                object serverList = KepServer.GetOPCServers(ipHostEntry.HostName.ToString());
                int i = 0;
                foreach (string serverName in (Array)serverList)
                {
                    Console.WriteLine(i.ToString() + "." + serverName);
                    serverNames.Add(serverName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Connect Error:" + ex.Message);
            }
        }

        /// <summary>
        /// 连接OPC SERVER
        /// </summary>
        /// <param name="serverName">OPC SERVER名字</param>
        public void ConnectServer(string serverName)
        {
            try
            {
                KepServer.Connect(serverName, "");
                CreateGroup("");
                CreateItems();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Connect Error:" + ex.Message);
            }
        }

        /// <summary>
        /// 创建组,组名无所谓
        /// </summary>
        private void CreateGroup(string groupName)
        {
            try
            {
                KepGroups = KepServer.OPCGroups;
                KepGroup = KepGroups.Add(groupName);
                KepServer.OPCGroups.DefaultGroupIsActive = true;
                KepServer.OPCGroups.DefaultGroupDeadband = 0;
                KepGroup.UpdateRate = 250;
                KepGroup.IsActive = true;
                KepGroup.IsSubscribed = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Create group error:" + ex.Message);
            }
        }

        private void CreateItems()
        {
            KepItems = KepGroup.OPCItems;
            KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
        }

        private void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            for (int i = 1; i <= NumItems; i++)
            {
                readValue = ItemValues.GetValue(i).ToString();
            }
        }

        private void GetTagValue(string tagName)
        {
            try
            {
                readValue = "";
                if (itmHandleClient != 0)
                {
                    Array Errors;
                    OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
                    //注:OPC中以1为数组的基数
                    int[] temp = new int[2] { 0, bItem.ServerHandle };
                    Array serverHandle = (Array)temp;
                    //移除上一次选择的项
                    KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
                }
                itmHandleClient = 12345;
                KepItem = KepItems.AddItem(tagName, itmHandleClient);
                itmHandleServer = KepItem.ServerHandle;
            }
            catch (Exception err)
            {
                //没有任何权限的项,都是OPC服务器保留的系统项,此处可不做处理。
                itmHandleClient = 0;
                Console.WriteLine("Read value error:" + err.Message);
            }
        }

        public void WriteValue(string tagName, object _value)
        {
            GetTagValue(tagName);
            OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
            int[] temp = new int[2] { 0, bItem.ServerHandle };
            Array serverHandles = (Array)temp;
            object[] valueTemp = new object[2] { "", _value };
            Array values = (Array)valueTemp;
            Array Errors;
            int cancelID;
            KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, 2009, out cancelID);
            //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件
            GC.Collect();
        }

        public object ReadValue(string tagName)
        {
            GetTagValue(tagName);
            Thread.Sleep(500);
            try
            {
                return KepItem.Value;
            }
            catch
            {
                return null;
            }
        }

        public void ReadValue(string tagName,bool wtf)
        {
            GetTagValue(tagName);
            OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
            int[] temp = new int[2] { 0, bItem.ServerHandle };
            Array serverHandles = (Array)temp;
            Array Errors;
            int cancel;
            KepGroup.AsyncRead(1, ref serverHandles, out Errors, 2009, out cancel);
            GC.Collect();
        }


    }
}

 

步骤:

1.使用GetOPCServers方法,将本地所有OPC Server上所有OPC服务器服务枚举并写入serverNames变量中

2.使用ConnectServer方法,连接服务器。此方法自动创建OPC Group,创建方法中的groupname任意写

3.使用ReadValue及WriteValue方法读写数据。

 

PS:

1.OPCItems是一个列表,每次将旧数据移除,插入新数据,即列表中永远只有一个元素;

2.读的时候有可能旧数据移除,新数据未写入,报对象为null的错误,sleep一下即可

第二条不一定对,使用模拟器的时候也有此问题,连PLC时无此问题


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++开源跨平台类库及在VC++.net中应用的配置发布时间:2022-07-14
下一篇:
销售C#版代码生成器-支持PowerDesigner设计文档发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap