C#遇上WINCC

摘要:
前言在工业控制领域,WinCC仍然占有很大的市场份额。例如,当我们的项目采用了WINCC并已经实现时,如果我们学习了C#,我们能做什么?今天,我想和大家分享一下如何使用C#/。NET实现与西门子WinCC的数据通信。这里有一个注意事项:当测试期间安装WinCCV7.4时,当添加驱动程序以与S7-1200 PLC通信时,无法连接。最后,发现WINCC的S7-1200 PLC的驱动程序有点bug,并且缺少一些组件。安装TIA博客后,问题终于得到解决。

C#遇上WINCC第1张

前言

在工控领域中,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,如下图所示:

C#遇上WINCC第2张

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

C#遇上WINCC第3张

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

C#遇上WINCC第4张

访问WINCC变量

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

C#遇上WINCC第5张

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

C#遇上WINCC第6张

 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、读取测试结果如下图所示:

C#遇上WINCC第7张

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

C#遇上WINCC第8张

访问WINCC控件

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

C#遇上WINCC第9张

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、读取结果如下所示:

C#遇上WINCC第10张

 5、写入结果如下所示:

C#遇上WINCC第11张

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

整体总结

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

免责声明:文章转载自《C#遇上WINCC》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇前端框架Vue自学之Vue router(六)从Hadoop框架与MapReduce模式中谈海量数据处理(含淘宝技术架构)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#中out的用法

out的用法out关键字会导致参数通过引用来传递。这与ref关键字类似,不同之处在于ref要求变量必须在传递之前进行初始化。若要使用out参数,方法定义和调用方法都必须显式使用out关键字。例如: classOutExample { static void Method(out inti) { i = 44; }...

Oracle视图和PL SQL编程.

Oracle中的视图 在Oracle数据库中视图是数据库中特有的对象。视图主要用于数据查询,它不会存储数据(物化视图除外)。这是视图和数据表的重要区别。 视图的数据来源于一个或等多个表中的数据,可以利用视图进行查询、插入、更新和删除数据,操作视图就是间接操作数据库表。 通常情况下,视图主要用于查询,不提倡通过视图而更新与视图相关的表,因为视图中的数据只是一...

SV中的OOP

OOP:Object-Oriented Programming,有两点个人认为适合验证环境的搭建:1)Property(变量)和Method(function/task)的封装,其实是BFM模型更方便的应          用。2)继承(Inheritance)与合成(Composition)非常适合一个架构的搭建。 在SV中,类可以定义在program,...

php性能调优

第一章  针对系统调用过多的优化 我这次的优化针对syscall调用过多的问题,所以使用strace跟踪apache进行分析。 1.  apache2ctl -X & 使用-X(debug)参数启动httpd进程,这个时候只启动1个httpd进程 2. ps -ef | grep httpd 找到需要strace的pid 3. strace -p...

SPSS统计分析(第5版)

SPSS统计分析(第5版) 《SPSS统计分析(第5版)》编委会 1 SPSS概述 1.1 软件安装与运行 1.1.1 SPSS软件安装方法 1.1.2 SPSS的启动与退出 1.1.3 SPSS运行管理方式 1.2 窗口及其功能概述 1.2.1 数据编辑窗口 1.2.2 输出窗口 1.2.3 语句窗口 1.2.4 【窗口】菜单 1.2.5 对话框及其使用...

UiPath Level 1-Lesson 3. Data Manipulation

学习大纲 如何拆分字符串 如何改变部分字符串的格式 如何在表格中根据条件选中特定的行 1. 标量型变量,集合,表格 活动的属性都有预定义的数据类型。鼠标悬停在属性面板的某个属性上,就会出现相应的提示。 使用右键菜单或Ctrl+K在属性栏创建的变量,会直接设置为属性预定义的类型。 标量型变量 (Scalar Variables):一个单独的固定类...