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 Files\Siemens\Bin,將這兩個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為主的電氣工程師來說,會有很大幫助。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM