zoukankan      html  css  js  c++  java
  • C#遇上WINCC

    前言

    在工控领域中,WinCC仍然占有很大的市场份额。很多时候我们说学习C#开发上位机可以取代传统的组态软件,两者就像冤家一样,然而,即使是冤家,也会有联合的时候。比如,当我们的项目已经采用WINCC并已经落地,如果我们学会C#,能做哪些事情呢?今天跟大家分享一下如何使用C#/.NET联合西门子WinCC实现数据通信。

    环境搭建

    众所周知,WinCC作为西门子家族的一款组态软件,主要是用来和PLC(主要是西门子PLC)通信,因此我们选择的硬件就是一款西门子S7-1200 PLC。软件方面,使用的是WinCC V7.4(其他版本待测试),以及宇宙第一IDE——VS 2019。

    这里注意一下:测试时当安装好WinCC V7.4,通过添加驱动和S7-1200 PLC通信时,怎么都连接不上,最后发现应该是WINCC的S7-1200 PLC的驱动有点BUG,缺少一些组件,通过安装TIA博图之后,最终解决。

    如果想通过C#联合WINCC访问到PLC里的变量,前提是WINCC项目已经开发好,并且处于运行状态,操作步骤如下:

    1、首先创建一个S7连接,并创建4个变量分别为data1、data2、data3、data4,地址对应DB100.DBD0、DB100.DBD4、DB100.DBD8、DB100.DBD12,如下图所示:

    2、创建一个画面,拖入4个显示控件,分别绑定这4个变量,通过博图将4个变量的值分别设置为50.5、60.5、70.5、80.5,如下图所示:

     3、运行WINCC画面,如下图所示:

    访问WINCC变量

    1、首先创建一个新的Windows窗体应用,再从WINCC安装目录中找到两个dll,分别是CCHMIRuntime.dll和CCHMITags.dll,位置默认处于C:Program Files (x86)Common FilesSiemensBin,将这两个dll复制到debug根目录下并手动添加引用:

    2、Windows窗体界面设计,下图所示:

     3、编写读取变量代码,如下图所示:


            //创建通信对象
            CCHMIRUNTIME.HMIRuntime hmi = new CCHMIRUNTIME.HMIRuntime();
            //创建计时器
            Stopwatch sw = new Stopwatch();
            /// <summary>
            /// 读取变量
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btn_Read_Click(object sender, EventArgs e)
            {
                //开始计时
                sw.Restart();
                //读取变量
                object data1 = hmi.Tags["data1"].Read();
                object data2 = hmi.Tags["data2"].Read();
                object data3 = hmi.Tags["data3"].Read();
                object data4 = hmi.Tags["data4"].Read();
                //显示变量
                this.txt_data1R.Text = data1?.ToString();
                this.txt_data2R.Text = data2?.ToString();
                this.txt_data3R.Text = data3?.ToString();
                this.txt_data4R.Text = data4?.ToString();
                //显示耗时
                this.lbl_Time.Text = sw.ElapsedMilliseconds.ToString() + "ms";
            }

    4、编写写入变量代码,如下图所示:

            /// <summary>
            /// 写入变量
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btn_Write_Click(object sender, EventArgs e)
            { 
                //开始计时
                sw.Restart();
                //写入变量
                try
                {
                    hmi.Tags["data1"].Write(Convert.ToSingle(this.txt_data1W.Text));
                    hmi.Tags["data2"].Write(Convert.ToSingle(this.txt_data2W.Text));
                    hmi.Tags["data3"].Write(Convert.ToSingle(this.txt_data3W.Text));
                    hmi.Tags["data4"].Write(Convert.ToSingle(this.txt_data4W.Text));
                }
                catch (Exception)
                {
                    MessageBox.Show("写入失败");
                    return;
                }
                //显示耗时
                this.lbl_Time.Text = sw.ElapsedMilliseconds.ToString() + "ms";
            }

    5、读取测试结果如下图所示:

     6、写入测试结果如下图所示:

    访问WINCC控件

    1、重新新建一个窗体,窗体内容和布局与之前一致,如下所示:

    2、编写读取控件属性代码,如下所示:

            //创建通信对象
            CCHMIRUNTIME.HMIRuntime hmi = new CCHMIRUNTIME.HMIRuntime();
            //创建计时器
            Stopwatch sw = new Stopwatch();
            /// <summary>
            /// 读取变量
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btn_Read_Click(object sender, EventArgs e)
            {
                //开始计时
                sw.Restart();
                try
                {
                    //读取变量
                    dynamic data1 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件1"];
                    dynamic data2 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件2"];
                    dynamic data3 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件3"];
                    dynamic data4 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件4"];
                    //显示变量
                    this.txt_data1R.Text = data1.CurrentValue.ToString();
                    this.txt_data2R.Text = data2.CurrentValue.ToString();
                    this.txt_data3R.Text = data3.CurrentValue.ToString();
                    this.txt_data4R.Text = data4.CurrentValue.ToString();
                }
                catch (Exception)
                {
                    MessageBox.Show("读取失败");
                    return;
                }
                //显示耗时
                this.lbl_Time.Text = sw.ElapsedMilliseconds.ToString() + "ms";
            }

    3、编写写入控件属性代码,如下所示:


          /// <summary>
          /// 写入变量
          /// </summary>
          /// <param name="sender"></param>
          /// <param name="e"></param>
          private void btn_Write_Click(object sender, EventArgs e)
          {
              //开始计时
              sw.Restart();

              //写入变量
              try
              {
                  dynamic data1 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件1"];
                  dynamic data2 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件2"];
                  dynamic data3 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件3"];
                  dynamic data4 = hmi.Screens["NewPdl1"].ScreenItems[".NET 控件4"];
                  
                  data1.CurrentValue = Convert.ToSingle(this.txt_data1W.Text);
                  data2.CurrentValue = Convert.ToSingle(this.txt_data2W.Text);
                  data3.CurrentValue = Convert.ToSingle(this.txt_data3W.Text);
                  data4.CurrentValue = Convert.ToSingle(this.txt_data4W.Text);

              }
              catch (Exception)
              {
                  MessageBox.Show("写入失败");
                  return;
              }

              //显示耗时
              this.lbl_Time.Text = sw.ElapsedMilliseconds.ToString() + "ms";
          }

    4、读取结果如下所示:

     5、写入结果如下所示:

    这里值得注意的是,通过访问控件实现的写入并没有真正写入PLC,所以这种方式仅限于读取数据,但可以通过这种方式来设置控件的其他属性,比如样式、背景、文本等。

    整体总结

    本文主要以学习研究为主,针对C#与WINCC之间的数据通信做了较为详尽的描述,相信对于很多电气工程师,尤其是以西门子PLC为主的电气工程师来说,会有很大帮助。

  • 相关阅读:
    【数据结构】算法 Minimum Remove to Make Valid Parentheses 移除无效的括号
    【数据结构】算法 Remove Outermost Parentheses 删除最外层的括号
    【数据结构】算法 Valid Parentheses 有效的括号
    for嵌套的那些事
    i++与++i的区别
    初次接触JS 2017/11/27
    鼠标经过图片变大
    bootstrap使用
    ajax的应用原理及基本用法
    ajax实例代码及效果
  • 原文地址:https://www.cnblogs.com/xiketang/p/14955639.html
Copyright © 2011-2022 走看看