前言
在工控領域中,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為主的電氣工程師來說,會有很大幫助。