C

解決科技看今朝 2024-03-08 17:32:13
背景介紹

早前我們推出了一款C#上位機項目實例教程。它源自于我們爲客戶定制開發的一個上位機項目。但因爲開發時間比較久,加上當時開發時間比較緊張,在代碼規範和項目框架結構上還是有一些優化空間。因此在2023下半年我們對該項目進行了重構,在代碼的規範性、項目框架和界面上進行了全面提升。

這套C#上位機項目實例有別于一些上位機Demo,它的最主要不同點是工程級別的應用。作爲工程級項目,它尤其注重穩定性和開發效率。工業領域的應用,穩定性高于一切,無需多言。其次是開發效率,因爲開發效率的高低直接影響項目成本,所以高效率的開發對降低項目成本尤爲重要。

重構後的項目實例在框架結構上做了優化,我們完全可以把它作爲一個上位機模板來使用。基于這套上位機項目模板,修修改改就可以完成一個上位機項目。最近手頭正好有一個這樣的上位機項目,想著可以測試一下重構後的這套項目模板的實戰能力,所以我們准備基于它來開發。

項目介紹

本項目是一個物料輸送系統。控制系統核心是兩台S7-1200系列PLC。人機界面是一台觸摸式的工控一體機。點數大概有2000點左右。

本項目我們將以重構後的C#上位機項目實例作爲模板進行修改,以一個實際的上位機項目開發過程來檢驗它的開發效率。

開發過程-驅動部分

作爲一個上位機,最基礎也是最重要的部分就是通信驅動了。在我們的C#上位機項目模板中,設備通信是作爲後台獨立運行的。前端頁面通過變量名稱和PLC進行數據交互。通信過程是封裝好的,且開放的。我們在開發時不需要關注通信細節,只需要根據物理PLC數據進行實例化,然後創建變量即可。

具體修改過程非常簡單,首先我們根據實際的物理PLC數量進行聲明和初始化。

//根據物理PLC數量聲明變量,該項目一共2台PLCstatic S7PLC PLC1 = null;static S7PLC PLC2 = null;///<summary>///初始化PLC///</summary>public static void Initial(){ //往變量池中添加變量 AddTagsPLC1(); AddTagsPLC2(); //初始化1#PLC PLC1 = newS7PLC("192.168.0.11",0,1); //訂閱事件 PLC1.StatusChanged += PLC1_StatusChanged; PLC1.DataUpdate += PLC1_DataUpdate; //讀寫信息 ByteList1(PLC1); PLC1.WriteTagsList = TagsPLC1; //通信啓動 PLC1.Start(); //初始化2#PLC PLC2 = newS7PLC("192.168.0.12", 0, 1); //訂閱事件 PLC2.StatusChanged += PLC2_StatusChanged; PLC2.DataUpdate += PLC2_DataUpdate; //讀寫信息 ByteList2(PLC2); PLC2.WriteTagsList = TagsPLC2; //通信啓動 PLC2.Start();}

然後我們根據每台PLC需要訪問的數據往PLC實例裏面添加變量。

/// <summary>/// 添加變量/1#PLC/// </summary>private static void AddTagsPLC1(){ TagsPLC1.Add("A區注塑機料位1", new TagModel() { Address = "D1.0.0" }); TagsPLC1.Add("A區注塑機料位2", new TagModel() { Address = "D1.0.1" }); TagsPLC1.Add("A區注塑機料位3", new TagModel() { Address = "D1.0.2" }); TagsPLC1.Add("A區注塑機料位4", new TagModel() { Address = "D1.0.3" }); TagsPLC1.Add("A區注塑機料位5", new TagModel() { Address = "D1.0.4" }); TagsPLC1.Add("A區注塑機料位6", new TagModel() { Address = "D1.0.5" }); TagsPLC1.Add("A區注塑機料位7", new TagModel() { Address = "D1.0.6" }); TagsPLC1.Add("A區注塑機料位8", new TagModel() { Address = "D1.0.7" }); //…… //變量比較多,這裏就不全面貼出來了。}

同樣的方法爲2#PLC添加變量。再根據變量情況設置需要請求的報文信息。

private static void ByteList2(S7PLC mdb) { ReadMsg msg = new ReadMsg(); msg.Id = "1"; msg.RgstArea = 0x84; msg.DBNumber = 1; msg.StartAddress = 0; msg.Count = 9000; mdb.ReadMsgList.Add(msg); }

最後一步是更新數據,我們需要將驅動返回的報文解析並綁定到相應的變量。數據更新方法由PLC驅動的數據更新事件進行觸發。

///<summary>///解析數據///</summary>///<param name="Data"></param>private static void AnalyzeDataPLC1(Dictionary<string, int[]> Data){ Byte[] DataArray = Array.ConvertAll(Data["1"], val => checked((Byte)val)); TagsPLC1["A區注塑機料位1"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 0); TagsPLC1["A區注塑機料位2"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 1); TagsPLC1["A區注塑機料位3"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 2); TagsPLC1["A區注塑機料位4"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 3); TagsPLC1["A區注塑機料位5"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 4); TagsPLC1["A區注塑機料位6"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 5); TagsPLC1["A區注塑機料位7"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 6); TagsPLC1["A區注塑機料位7"].Value1 = Sharp7.S7.GetBitAt(DataArray, 0, 7); //…… //變量比較多,這裏就不全面貼出來了。 }

只需要上述簡單的幾步即可完成上位機軟件和設備的數據交互。根據實測時間,一天不到的時間就完成了兩台PLC共約2000點的變量配置。除了支持批量導入PLC變量的WinCC外,對于一些不支持變量導入的組態軟件,在配置這麽多變量的時間花費上估計也是相差無幾。如果采用我們的支持變量自動解析的AdvScadaFramework高級上位機框架軟件則可以在更短的時間內完成。

變量添加完成後,我們在需要展示的窗體定時刷新就可以了。這種方式比較簡單方便。當然也可以采用基于變量名的綁定方式。這兩種方式的工作量其實差不多。

開發過程-周期歸檔

周期歸檔的數據一般用于曲線或者生成報表。該上位機項目模板對于歸檔的處理也很簡單。首先我們新建一個實體類。該實體類包含了需要歸檔的所有成員。

public ArchiveModel{ [SugarColumn(IsPrimaryKey = true)] public DateTime DT { get; set; } public double TotalWeight1 { get; set; } public double TotalWeight2 { get; set; } public double TotalWeight3 { get; set; } public double TotalWeight4 { get; set; } public double TotalWeight5 { get; set; } public double TotalWeight6 { get; set; } public double TotalWeight7 { get; set; } public double TotalWeight8 { get; set; } public double TotalWeight9 { get; set; } public double TotalWeight10 { get; set; }}

歸檔是由一個單獨的後台任務負責的。我們把裏面的代碼稍微調整下就可以了。

public static void PowerArchive(){ while (true) { //控制歸檔周期 Thread.Sleep(2000); try { ArchiveModel am = new ArchiveModel(); am.DT = DateTime.Now; am.TotalWeight1 = PLC.TagsPLC2["總量1"].Value1 is null ? 0 : Convert.ToDouble(PLC.TagsPLC2["總量1"].Value1.ToString()); am.TotalWeight2 = PLC.TagsPLC2["總量2"].Value1 is null ? 0 : Convert.ToDouble(PLC.TagsPLC2["總量2"].Value1.ToString()); am.TotalWeight3 = PLC.TagsPLC2["總量3"].Value1 is null ? 0 : Convert.ToDouble(PLC.TagsPLC2["總量3"].Value1.ToString()); am.TotalWeight4 = PLC.TagsPLC2["總量4"].Value1 is null ? 0 : Convert.ToDouble(PLC.TagsPLC2["總量4"].Value1.ToString()); am.TotalWeight5 = PLC.TagsPLC2["總量5"].Value1 is null ? 0 : Convert.ToDouble(PLC.TagsPLC2["總量5"].Value1.ToString()); am.TotalWeight6 = PLC.TagsPLC2["總量6"].Value1 is null ? 0 : Convert.ToDouble(PLC.TagsPLC2["總量6"].Value1.ToString()); DAL.DBOperation.AddOperation(am); } catch (Exception) { //throw; } } }

這樣啓動程序後,它就會自動生成數據表並定時保存數據。也是非常的方便快捷。

關于C#上位機項目框架

CSharpSCADA上位機項目實例軟件(CSharpSCADA)源自一個定制化的上位機項目。經過重構後,在框架結構上更加合理。它也可以作爲上位機項目模板使用,簡單的修改調整即可實現一個上位機項目。

AdvScadaFramework高級上位機框架軟件(AdvScadaFramework)是集成度更高的一款上位機框架軟件,除了工藝畫面外,其它功能均可以通過配置實現。

0 阅读:0

解決科技看今朝

簡介:感謝大家的關注