C# 联合KepServer对PLC进行数据读写

KepServer可以将任何工业设备的通信协议转换为opc协议,然后用OPCAutomation进行上位机数据读写。

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

namespace KepTest1
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
            this.Load += FrmMain_Load;
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.btnRefresh_Click(btnRefresh, null);
            this.dataGridViewValue.AutoGenerateColumns = false;
        }

        OPCServer opcServer;
        OPCGroups opcGroups;
        OPCGroup opcGroup;

        OPCItems opcItems;
        OPCItem opcItem; //项
        Dictionary<string, OPCItem> dicOpcItem = new Dictionary<string, OPCItem>();
        List<OPCItem> opcItemList = new List<OPCItem>(); //项的集合

        OPCBrowser opcBrowser;
        string strHostName = null;
        object opcServerList;

        List<OpcValue> opcValueList = new List<OpcValue>();

        int clientHandle; //change句柄

        int count;

        //异步写入相关
        Array writeErrors;
        int cancelId;

        private void btnConn_Click(object sender, EventArgs e)
        {
            //连接服务器
            if (opcServer != null)
            {
                opcServer = new OPCServer();
            }
            try
            {
                opcServer.Connect(this.cmb_ServerName.Text, this.cmb_ServerNode.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("连接失败:" + ex.Message);
                return;
            }

            opcBrowser = this.opcServer.CreateBrowser(); //由OPC 节点创建浏览器
            opcBrowser.ShowBranches();//展示浏览器属性
            opcBrowser.ShowLeafs(true); //叶节点展示

            //绑定 其实是浏览器browers
            this.listBoxServer.Items.Clear();

            foreach (var item in opcBrowser)
            {
                if (!this.listBoxServer.Items.Contains(item))
                {
                    this.listBoxServer.Items.Add(item.ToString());
                }
            }

            //通信组集合
            opcGroups = this.opcServer.OPCGroups;
            opcGroups.DefaultGroupDeadband = 0; //只要有变化,就显示出来
            opcGroups.DefaultGroupIsActive = true;
            //opcGroups.DefaultGroupUpdateRate = 200; //200毫秒刷新一次

            //通信组实例化
            opcGroup = opcGroups.Add("S71500Test");
            opcGroup.IsActive = true;
            opcGroup.IsSubscribed = true; //是否开启异步回调
            opcGroup.UpdateRate = 200;

            opcItems = opcGroup.OPCItems;
            opcGroup.DataChange += OpcGroup_DataChange;

        }

        //订阅模式
        private void OpcGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            for (int i = 0; i < NumItems; i++)
            {
                //clientHandle = Convert.ToInt32(ClientHandles.GetValue(i + 1));
                //opcValueList[clientHandle - 1].Value = ItemValues.GetValue(i + 1).ToString();
                //opcValueList[clientHandle - 1].InsertTime = Convert.ToDateTime(TimeStamps.GetValue(i + 1));

                //this.dataGridViewValue.DataSource = null;
                //this.dataGridViewValue.DataSource = opcValueList;

                clientHandle = Convert.ToInt32(ClientHandles.GetValue(i + 1));
                opcValueList[clientHandle - 1].Value = ItemValues.GetValue(i + 1).ToString();
                opcValueList[clientHandle - 1].InsertTime = Convert.ToDateTime(TimeStamps.GetValue(i + 1));
                opcValueList[clientHandle - 1].OPCDataType = ItemValues.GetValue(i + 1).GetType().ToString();
                opcValueList[clientHandle - 1].OPCQuality = Qualities.GetValue(i + 1).ToString();
            }
            xktTextShowBasic1.VarValue = opcValueList[0].Value;
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            //清空
            this.cmb_ServerNode.Items.Clear();
            this.cmb_ServerName.Items.Clear();
            Task.Run(async () =>
            {
                IPHostEntry IPhost = Dns.GetHostEntry(Environment.MachineName);
                if (IPhost.AddressList.Length > 0)
                {
                    
                    for (int i = 0; i < IPhost.AddressList.Length; i++)
                    {
                        await Task.Delay(500);
                        string host = Dns.GetHostEntry(IPhost.AddressList[i]).HostName;//计算机名称

                        if (!this.cmb_ServerNode.Items.Contains(host))
                        {
                            this.cmb_ServerNode.Invoke(new Action(() =>
                            {
                                this.cmb_ServerNode.Items.Add(host);
                            }));
                        }
                    }
                }
            });

        }

        //如果改变
        private void cmb_ServerNode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (opcServer == null)
            {
                opcServer = new OPCServer();
            }

            this.cmb_ServerName.Items.Clear();

            strHostName = this.cmb_ServerNode.Text.Trim(); //获取主机名

            try
            {
                opcServerList = opcServer.GetOPCServers(strHostName);

                //object serviceList = KepServer.GetOPCServers(this.cmb_ServerNode.Text);

                Task.Run(async () => 
                {
                    foreach (var item in (Array)opcServerList)
                    {
                        await Task.Delay(500);
                        if (!this.cmb_ServerName.Items.Contains(item))
                        {
                            this.cmb_ServerName.Invoke(new Action(() =>
                            {
                                this.cmb_ServerName.Items.Add(item);
                            }));
                            
                        }
                    }
                });

            }
            catch (Exception)
            {

            }


        }


        private void listBoxServer_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            opcValueList.Add(new OpcValue());
            opcValueList[count].Name = this.listBoxServer.Text.Trim();
            opcItem = opcItems.AddItem(this.listBoxServer.Text.Trim(), count + 1);
            opcItemList.Add(opcItem);
            count += 1;
        }

        //读取
        private void button1_Click(object sender, EventArgs e)
        {
            opcValueList.Add(new OpcValue() { Name = "MD200",ItemId = "Siemens1500.siemens1513.MD200" });
            opcValueList.Add(new OpcValue() { Name = "DB24DBW8", ItemId = "Siemens1500.siemens1513.DB24DBW8" });
            opcValueList.Add(new OpcValue() { Name = "DB24DBD34",ItemId = "Siemens1500.siemens1513.DB24DBD34" });


                //opcServer通过Ip 端口号得到: opcServer.Connect(this.cmb_ServerName.Text, this.cmb_ServerNode.Text);
                //opcGroups 由Opc服务器得到:opcGroups = this.opcServer.OPCGroups;
                //opcGroup 由 opcGroups 实例化得到:opcGroup = opcGroups.Add("S71500Test");
                //opcItems由opcGroup中得到: opcItems = opcGroup.OPCItems; 而来 实例化opcItems 得到 opcItem
                //做集合opcItem 方便取出opcItem,方便写变量
            
            for (int i = 0; i < opcValueList.Count; i++)
            {
                opcItem = opcItems.AddItem(opcValueList[i].ItemId, i + 1);
                opcItemList.Add(opcItem);
                dicOpcItem.Add(opcValueList[i].Name, opcItem);
            }
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            string value = txtWrite.Text.Trim();

            //同步写入
            //dicOpcItem["MD200"].Write(value);

            //异步写入
            int[] reServerHandle = new int[2] { 0, dicOpcItem["MD200"].ServerHandle };
            Array arrayReServerHandle = reServerHandle.ToArray();
            object[] reValue = new object[2] { "", value};

            Array values = reValue.ToArray();
            opcGroup.AsyncWrite(1, ref arrayReServerHandle, ref values, out writeErrors, 2022, out cancelId);
        }

        private void btnDisc_Click(object sender, EventArgs e)
        {
            opcServer.Disconnect();
            Environment.Exit(0);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KepTest1
{
    public class OpcValue
    {
        public int Id { get; set; }
        public string ItemId { get; set; }
        public string Name { get; set; }
        public string Value { get; set; }
        //通信质量
        public string OPCQuality { get; set; }
        //ClientHandle
        public int ClientHandle { get; set; }
        public string OPCDataType { get; set; }
        public DateTime InsertTime { get; set; }
    }
}

在这里插入图片描述
在这里插入图片描述

KepServer配置:
在这里插入图片描述
西门子PLC配置:

#T1(IN := #start,
    PT := t#1S);
#C1(CU := #T1.Q,
    R := #reset,
    PV := 30000);

IF #T1.Q THEN
    RESET_TIMER(#T1);
    
    ;
END_IF;

IF #start THEN
    "OpcDb".ushort[1] := #C1.CV;
    "OpcDb".ushort[2] := "OpcDb".ushort[1] + 1;
    "OpcDb".ushort[3] := "OpcDb".ushort[2] + 1;
    "OpcDb".ushort[4] := "OpcDb".ushort[3] + 1;
    "OpcDb".ushort[5] := "OpcDb".ushort[4] + 1;
    "OpcDb".ushort[6] := "OpcDb".ushort[5] + 1;
    
    "MD204" := "OpcDb".ushort[6] + 1.1;
    "MD208" := "OpcDb".ushort[6] + 1.2;
    "MD200" := "OpcDb".ushort[6] + 5.5;
    "OpcDb".float[0] := "OpcDb".ushort[6] + 6.6;
    "OpcDb".float[1] := "OpcDb".ushort[6] + 7.1;
    "OpcDb".float[2] := "OpcDb".ushort[6] + 8.1;
    "OpcDb".float[3] := "OpcDb".ushort[6] + 9.9;

END_IF;


在这里插入图片描述

            //opcServer通过Ip 端口号得到: opcServer.Connect(this.cmb_ServerName.Text, this.cmb_ServerNode.Text);
            //opcGroups 由Opc服务器得到:opcGroups = this.opcServer.OPCGroups;
            //opcGroup 由 opcGroups 实例化得到:opcGroup = opcGroups.Add("S71500Test");
            //opcItems由opcGroup中得到: opcItems = opcGroup.OPCItems; 而来 实例化opcItems 得到 opcItem
            //做集合opcItem 方便取出opcItem,方便写变量

需要先注册OPCDA,在System32 和syswow64中有OPCDAAuto.dll。注册后就可以引入dll了,引入之后就有了using OPCAutomation

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值