C#连接Kepserver与PLC进行OPC通信上位机程序源码

该程序是我通过一个星期的测试,终于搞明白C#如何调用OPCDAAuto.dll链接KEPserver与PLC通讯,通过OPC方式可以连接市面上主流PLC,具体代码如下,如果想要测试程序源码或者项目程序的朋友可以联系我+V:1357448516。

using System;

using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OPCAutomation;
using System.Diagnostics;
using System.Threading; 


namespace OPC_Client
{
    public partial class Form1 : Form
    {
        OPCServer objServer;
        OPCGroups objGroups;
        OPCGroup objGroup;
        OPCItems objItems;
        OPCItem[] objChangeItem;
        Array strItemIDs;
        Array lClientHandles;
        Array lserverhandles;
        Array lErrors;
        string State;
       //  int ltransID_Rd = 1;
       // int lCancelID_Rd;
       object RequestedDataTypes = null;
        object AccessPaths = null;
      // Array lerrors_Rd;
        Array lErrors_Wt;
        int lTransID_Wt = 2;
        int lCancelID_Wt;
        int opcQualityState;//OPC与PLC链接状态
       //状态显示枚举
        private delegate void OPCtimer(string text);
        //OPC与PLC链接状态
        private delegate void OPCtoPlcState(int PLCstate);


        //定时器
        System.Windows.Forms.Timer tim;
        //OPC链接定时器
        System.Windows.Forms.Timer OPCconnectTimer;  
 
        public Form1()
        {
            InitializeComponent();
        }






        private void Form1_Load(object sender, EventArgs e)
        {
            //OPC链接定时器初始化
            OPCconnectTimer = new System.Windows.Forms.Timer();
            OPCconnectTimer.Interval =1000;
            OPCconnectTimer.Tick += new EventHandler(OPCconnectTimer_Tick);
            OPCconnectTimer.Enabled = true;




            //初始化链接状态定时器
            tim = new System.Windows.Forms.Timer();//定义一个1S的定时器;
            tim.Interval = 1500;
            tim.Tick += new EventHandler(theout);//定时时间到后执行theout事件;
            tim.Enabled = true; ;//是否执行System.Timers.Timer.Elapsed事件;
            //(1)创建opc server对象
            objServer = new OPCServer();
            objChangeItem = new OPCItem[4];


          
           
        }




        /// <summary>
        /// 状态显示定时器触发事件
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void theout(object sender, EventArgs e)
        {
            tim.Interval = 1500;
            //OPC链接状态
            State = objServer.ServerState.ToString();
            SetOPCstate(State);
            //OPC与PLC链接状态
            opcQualityState = opcQualityJudge();
            changeLightStatus(opcQualityState);
        }






        #region OPC链接状态显示
        private void SetOPCstate(string text)
        {
            if (label3.InvokeRequired)
            {
                OPCtimer opcdelateTimer = new OPCtimer(InvokeMessage);
                this.Invoke(opcdelateTimer, text);
            }
            else
            {
                this.label3.Text = text;
            }
        
        }
        private void InvokeMessage(string text)
        {
            this.label3.Text = text;
        }


        #endregion






        #region OPC与PLC链接状态指示灯显示
        private void changeLightStatus(int PLCstate)
        {
            if (label13.InvokeRequired)
            {
                OPCtoPlcState sl = new OPCtoPlcState(InvokeLight);
                this.Invoke(sl, PLCstate);
            }
            else
            {
                switch (PLCstate)
                {
                    case 1:
                        this.label13.BackColor = Color.Green;
                        this.label13.Text = "已连接";
                        break;
                    case 0:
                        this.label13.BackColor = Color.Red;
                        this.label13.Text = "未连接";
                        this.Data1.Text = "0";
                        this.Data2.Text = "0";
                        break;
                }
            }
        }
        private void InvokeLight(int light)
        {
            switch (light)
            {
                case 1:
                    this.label13.BackColor = Color.Green;
                    this.label13.Text = "已连接";
                    break;
                case 0:
                    this.label13.BackColor = Color.Red;
                    this.label13.Text = "未连接";
                    this.Data1.Text = "0";
                    this.Data2.Text = "0";
                    break;
            }


        }




        /// <summary>
        /// 判断OPC与PLC链接状态,返回值1时表示链接,返回值0表示断开。
        /// 依次判断各个OPC项的质量信息,有一个变量质量为0时认为断开。
        /// </summary>
        /// <returns></returns>
        private int opcQualityJudge()
        {
            int[] opcQuality = new int[4];
            for (int i = 1; i < 4; i++)
            {
                opcQuality[i] = objChangeItem[i].Quality;
                if (opcQuality[i] != 192)
                {
                    return 0;
                }
            }
            return 1;
        }
        #endregion






      


        //结束并断开opc server
        private void button4_Click(object sender, EventArgs e)
        {
            //释放所有组资源
         
           
            if (null != objGroup)
            {
                objGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
                objGroup.AsyncWriteComplete -= new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(AsyncWriteComplete);
                objGroup = null;
                objServer.OPCGroups.RemoveAll();


            }
            if (null != objServer)
            {
                objServer.Disconnect();
                objServer = null;
                objItems = null;
                this.Data1.Text ="0";
                this.Data2.Text = "0";
                this.label3.Text = State.ToString();
                GC.Collect();
            }
            //关闭kepserver进程,这个跟OPC操作无关
            /*
            foreach ( Process oneProcess in Process.GetProcesses())
            {
            if (oneProcess.ProcessName == "ServerMain")
            oneProcess.Kill();
            }
            */
        }


        //每当项数据有变化时执行的事件,采用订阅方式




        void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            //为了测试,所以加了控制台的输出,来查看事物ID号
            //Console.WriteLine("********"+TransactionID.ToString()+"*********");


            for (int i = 0; i < NumItems; i++)
            {


               
                    if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 1)
                    {
                        if (ItemValues.GetValue(i + 1) != null)
                        {
                            this.Data1.Text = ItemValues.GetValue(i + 1).ToString();
                            
                            
                        }
                    }
              
                if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 2)
                {
                    if (ItemValues.GetValue(i + 1) != null)
                    {
                        this.Data2.Text = ItemValues.GetValue(i + 1).ToString();
                        //this.label5.Text = Qualities.GetValue(i + 1).ToString();
                        //int quality;
                        //quality = objChangeItem[2].Quality;
                        //label5.Text = quality.ToString();
                    }
                }
                if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 3)
                {
                    if (ItemValues.GetValue(i + 1) != null)
                    {
                        this.Data3.Text = ItemValues.GetValue(i + 1).ToString();
                    }
                }
                if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 4)
                {
                    if (ItemValues.GetValue(i + 1) != null)
                    {
                        this.Data4.Text = ItemValues.GetValue(i + 1).ToString();
                    }
                }
                if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 5)
                {
                    if (ItemValues.GetValue(i + 1) != null)
                    {
                        this.Data5.Text = ItemValues.GetValue(i + 1).ToString();
                    }
                }
                if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 6)
                {
                    if (ItemValues.GetValue(i + 1) != null)
                    {
                        this.Data6.Text = ItemValues.GetValue(i + 1).ToString();
                    }
                }
            }




        }


        void AsyncReadComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps, ref Array Errors)
        {


            MessageBox.Show("读取完成");
            label11.Text = "连上";
        }
           
         
        //发送异步写数据指令
        private void button3_Click(object sender, EventArgs e)
        {
            Array AsyncValue_Wt;
            Array SerHandles;
            object[] tmpWtData = new object[3];//写入的数据必须是object型的,否则会报错
            int[] tmpSerHdles = new int[3];
            //将输入数据赋给数组,然后再转成Array型送给AsyncValue_Wt
            tmpWtData[1] = (object)textBox1.Text;
            tmpWtData[2] = (object)textBox2.Text;
            AsyncValue_Wt = (Array)tmpWtData;
            //将输入数据送给的Item对应服务器句柄赋给数组,然后再转成Array型送给SerHandles
            tmpSerHdles[1] = Convert.ToInt32(lserverhandles.GetValue(1));
            tmpSerHdles[2] = Convert.ToInt32(lserverhandles.GetValue(2));
            SerHandles = (Array)tmpSerHdles;
            objGroup.AsyncWrite(2, ref SerHandles, ref AsyncValue_Wt, out lErrors_Wt, lTransID_Wt, out lCancelID_Wt);


            //用objChangeItem[1].Write用这句可也以写入数据,但并不触发写入事件。
            objChangeItem[1] = objItems.GetOPCItem(Convert.ToInt32(lserverhandles.GetValue (1)));
            //objChangeItem[1].Write(102);
           
        }
       
        
        //异步写入成功
        private void AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
        {
            MessageBox.Show("数据写入成功!");
        }




        /// <summary>
        /// OPC初始化
        /// 当定时时间到触发下面事件
        /// 开机后延迟1秒开始初始化OPC,以后10秒检查与OPC链接转态,如果断开链接就重新链接并初始化OPC
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OPCconnectTimer_Tick(object sender, EventArgs e)
        {
            try
            {   
                
                OPCconnectTimer.Interval = 10000;
                if (objServer.ServerState != 1)
                {
                   
                    连接opc server
                    objServer.Connect("KEPware.KEPServerEx.V4", "");
                    //(2)建立一个opc组集合
                    objGroups = objServer.OPCGroups;
                    //(3)建立一个opc组
                    objGroup = objGroups.Add(null); //Group组名字可有可无
                    //(4)添加opc标签
                    objGroup.IsActive = true; //设置该组为活动状态,连接PLC时,设置为非活动状态也一样
                    objGroup.IsSubscribed =true; //设置异步通知
                    objGroup.UpdateRate = 250;
                    objServer.OPCGroups.DefaultGroupDeadband = 0;
                    objGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
                    objGroup.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(AsyncReadComplete);
                    objGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(AsyncWriteComplete);
                    objItems = objGroup.OPCItems; //建立opc标签集合
                    string[] tmpIDs = new string[7];
                    int[] tmpCHandles = new int[7];
                    for (int i = 1; i < 7; i++)
                    {
                        tmpCHandles[i] = i;
                    }
                    tmpIDs[1] = "Channel1.Device1.m0";
                    tmpIDs[2] = "Channel1.Device1.m03";
                    tmpIDs[3] = "Channel1.Device1.m1";
                    strItemIDs = (Array)tmpIDs;//必须转成Array型,否则不能调用AddItems方法
                    lClientHandles = (Array)tmpCHandles;
                    // 添加opc标签
                    objItems.AddItems(3, ref strItemIDs, ref lClientHandles, out lserverhandles, out lErrors, RequestedDataTypes, AccessPaths);
                    for (int i = 1; i < 4; i++)
                    {
                        objChangeItem[i] = objItems.GetOPCItem(Convert.ToInt32(lserverhandles.GetValue(i)));
                    }
                }
            }
            catch (Exception ce)
            {
                objServer.Disconnect();


                //ShowMessage sm = new ShowMessage(InsertAlarmMessage);
                //this.Invoke(sm, ce.Message);
            }
        
    


        }


       
    }

}

猜你喜欢

转载自blog.csdn.net/u014780302/article/details/52796187