夏富平







摘要:上位PC機利用從PLC控制器實時采集的各項實時數據,自動監控現場各種機械設備和傳感器設備的運行狀態,并根據設備的實時狀態進行有效合理的統計分析,從而實現工業控制系統的自動化和信息化管理,這已成為工業控制領域的一個重量的發展方向。本文以西門子的Prodave 組件為基礎,設計并實現了一種上位機與PLC控制器通訊的通用接口,項目實踐證明,該通訊接口穩定性好、擴展性強且實際操作靈活方便,便于用戶將此通訊接口集成至各類工業控制系統中。
關鍵詞: simatic;prodave;PLC;C#;設計模式
1 ?概述
自動化工業控制領域中PLC作為一種高效、靈活、穩定的控制器,有著廣泛的應用。以PLC控制器為核心,上位PC機為實時監控體的控制系統已經成為工業自動化PLC控制系統的一個重要發展方向。實現PLC與PC的通信可以實現向上一級提供諸如工藝流程圖、動態數據畫面、報表顯示等多種窗口技術,使PLC控制系統具有良好的人機交互界面,通過上位機對PLC數據的讀寫監控實現現場數據的采集、傳送以及生產過程調度的自動化和信息化,其應用前景十分廣闊。
自動化生產線控制系統中通常會采用工業組態軟件開發上位機系統,PLC作為下層控制設備,目前市場上通信組態系統結構復雜,價格昂貴,應用繁瑣,且不具備一定的通用性。隨著工業以太網的深入發展,相較于品種繁多的組態軟件來說,高級編程語言更加適合開發具有實時響應、功能豐富、擴展方便、高靈活性和易于移植等技術需求的上位機系統。為此,需要設計一種與PLC通信的通用接口,用戶采用高級編程語言開發的上位機系統能夠運用此通訊接口與PLC進行數據通信。
本文以造紙行業中紙卷輸送控制系統的設計方法為基礎,對西門子S7系列中的PLC與上位機通訊的原理作深入細致的研究,依據Visual Studio 2005作為開發平臺用C#語言實現了PLC與上位PC機的通用通訊接口,該接口具有穩定性好、易于擴展維護且操作方便的特點,對于需要用上位機與PLC通訊的工程設計人員來說,具有一定的借鑒作用。
2 ?西門子Prodave組件介紹
Prodave是“Process Data Traffic”(過程數據交換)的縮寫形式,可以用于西門子S7-200、S7-300/400、M7和C7等S7系列PLC的通訊,通過MPI通信處理器、PC/MPI適配器和以太網絡可以方便地在PLC與PC之間建立數據鏈接。Prodave的動態鏈接庫(Dynamic Link Library,DLL)提供了大量的基于Windows系統的DLL函數,為用戶提供了解決上位機與PLC之間的數據交換與數據處理的詳細方案。
表1為項目中涉及到的Prodave組件的簡單介紹。
現階段項目中使用的Prodave組件版本主要有Prodave5.x系列和Prodave6.2系列。其中,Prodave6.2可用于Window 64位操作系統,且可以采用MPI-Profibus或者以太網通信,而其他版本的組件只能安裝于Windows 32位操作系統的上位機中,一般采用MPI-Profibus通信方式。
Prodave組件的函數分為基本函數、數據處理函數和電話服務函數,基本函數主要包含建立連接、關閉連接、激活連接、讀取PLC地址數據以及寫入PLC地址數據的函數。
3 ?通用接口的詳細設計方案
3.1 現有設計問題
由于上位機與PLC通信需要用到的Prodave組件版本過多,導致上位機與PLC通信時接口不盡相同,代碼復用能力差。當上位機硬件設備升級或者更換Prodave通訊組件時,需要修改上位機控制系統中與PLC通信的模塊代碼。在紙卷輸送控制系統的設計過程中,由于每個項目的工藝設計和功能要求不同,工程設計人員在做項目方案設計和設備選型時,選用西門子的CPU型號也不盡相同,因此網絡設計人員需要根據不同的工藝需求采用不同版本的Prodave組件來編寫與PLC通信的代碼。圖1為上位機與PLC控制器現有通訊結構。
3.2 通信接口設計要求
由于與PLC通信的Prodave組件版本多,對應的接口函數也不盡相同,因此對上位機來說,新的通用接口需要滿足以下設計要求:
①通用性能強。能夠滿足現階段項目中使用的不同Prodave組件的要求,當通信組件發生改變時,原有通信模塊不用發生變化;
②有較強的靈活性和擴展性能。如果未來出現新的Prodave組件的升級,現有系統中涉及的PLC通信模塊代碼不用發生變化,僅需要按接口要求增加新的Prodave組件對象即可;
③封裝性好,利于模塊移植。通用接口對應的PLC通信模塊可以非常方便的遷移至其他項目中,盡可能少的修改原有模塊代碼。
3.3 通信接口設計方案
通過深入分析可以得知:不論是哪一種Prodave組件,上位機控制系統均希望此組件能完成對PLC控制器的建立連接、讀取數據、寫入數據和關閉連接的功能,而各種版本的Prodave組件均能滿足此種功能,不同的是接口函數名稱以及輸入參數各不相同。因此,可以按照軟件設計模式中的工廠設計方法,將涉及到與PLC操作的各個對象中操作函數按一定的規則抽象出來,形成一個通用的接口對象。圖2是改進后上位機系統與PLC的通訊結構。
3.4 通用接口的設計實現
在實現通用接口對象前,首先需要分析現有各版本Prodave 組件對應的接口函數,然后再根據各接口函數再抽象成對應的接口對象。
①Prodave5.x組件。
主要包含有加載與激活連接、讀取與寫入PLC數據以及卸載連接的接口函數。
protected extern static int load_tool(byte nr, string device, byte[,] adr_table)
protected extern static int new_ss(byte no)
protected extern static int unload_tool()
protected extern static int d_field_read(int dbno, int dwno, int amount, byte[] buffer)
protected extern static int d_field_write(int dbno, int dwno, int amount, byte[] buffer)
②Prodave6.x組件。
主要包含有加載與激活連接、讀取與寫入PLC數據以及卸載連接的接口函數。
protected extern static int LoadConnection_ex6(int ConNr, string pAccessPoint, int ConTableLen, ref CON_TABLE_TYPE pConTable)
protected extern static int SetActiveConnection_ex6(UInt16 ConNr)
protected extern static int UnloadConnection_ex6(UInt16 ConNr)
protected extern static int field_read_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen, byte[] pBuffer, ref UInt32 pDatLen)
protected extern static int field_write_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen, byte[] pBuffer)
從上述各版本Prodave組件對應的接口函數可知,Prodave5.x系列對應的主要接口函數的函數名稱與對應參數數量與類型與Prodave6.x系列對應的主要接口函數函數名稱與對應參數數量與類型基本不相同。因此需要在各個引用Prodave組件對應的接口對象之上還需要抽象一個適配對象,目的在于將原始接口函數與加工后的接口函數分離開,將各組件使用的接口函數的函數名稱與函數參數數量盡量保持一致。
圖3為對應組件的類設計示意圖,從圖中可以看出,每一種Prodave組件的接口函數均有一個適配對象與之對應,如Prodave5.0的接口對象PLCProdave5D0與適配對象PLCOperation5D0對應,同理Prodave5.6的接口對象PLCProdave5D6與適配對象PLCOperation5D6對應, PLCProdave6D0與適配對象PLCOperation6D0對應。從圖3中還可以看出,每一類適配對象對應的連接函數(ConnectPLC)、重新連接函數(ReConnectPLC)、讀取PLC數據函數(ReadData)、寫入PLC數據函數(WriteData)以及關閉連接函數(CloseConnectPLC)對應的函數名稱、函數對應參數數量和類型均相同,每個適配類使用的屬性名稱和數量以及定義的事件名稱和返回的參數也相同。因此,可以在對應的適配器對象之上編寫統一的通用接口對象IPLCOperation。適配對象PLCOperation5D0、PLCOperation5D6和PLCOperation6D0除了繼承各自對應的接口對象外,還需要實現IPLCOperation和IDisposible接口,其中實現IDisposible接中主要用于在關閉對象時要求系統顯示釋放對應內存等重要資源。
從圖3Prodave組件類設計圖中,將各適配器對象相同的部分抽象出來可以非常容易得到通用的PLC接口對象如圖4所示。
通用接口中用到的其他相關對象如圖5所示
以下代碼為通用接口類的具體實現方式:
public interface IPLCOperation
{
event PLCMessageEventHandler OnPLCMessageChanged;
bool Connected ?{get;}
PLCType CurrPLCType { get; }
bool ConnectPLC();
bool CloseConnectPLC();
bool ReConnectPLC();
bool ReadData(int dbno, string strAddr, ref string retBoolValue);
bool ReadData(int dbno, int dwno, int amount, ref byte[] buffer);
bool WriteData(int dbno, string strAddr);
bool WriteData(int dbno, string strAddr, bool blnValue);
bool WriteData(int dbno, int dwno, int amount, ulong data);
bool WriteData(int dbno, int dwno, int amount, byte[] buffer);
}
最后建立了一個PLC操作工廠類,完全將各種具體的PLC接口實現對象封裝起來,主要是根據外部參數的不同創建不同的具體的PLC操作對象實例,以下代碼為工廠類的具體實現代碼:
public class PLCFactory
{
public static IPLCOperation CreatePLC(PLCType plcType, PLCConnItem plcConnParams)
{
IPLCOperation currPLCOperation;
switch (plcType)
{
case PLCType.PLC_5D0:
currPLCOperation = new PLCOperation5D0(plcConnParams);
break;
case PLCType.PLC_5D6:
currPLCOperation= new PLCOperation5D6(plcConnParams);
break;
case PLCType.PLC_6D0:
currPLCOperation = new PLCOperation6D0(plcConnParams);
break;
default:
currPLCOperation = new PLCOperation6D0(plcConnParams);
break;
}
return currPLCOperation;
}
}
上述代碼將PLC組件類型和PLC連接參數對象傳入PLC工廠對象中,由工廠對象根據PLC組件類型來實例化不同的PLC操作類。當然上述實現實例化不同PLC操作類還可以使用反射的方法,在此不再贅述。
4 ?通用接口的具體操作實現
上位機控制系統只需要關注PLC通信通用接口的實現方式,因此在項目實際使用過程中,系統設計人員可以按以下方式使用。
4.1 PLC模塊初始化
在實際項目設計過程中,如某臺上位機控制系統需要與一個以上的PLC通信,此處可以在PLC通信模塊中,可以建立一個以PLC通用接口對象為元素的PLC接口集合,將控制系統需要使用的PLC通信接口封裝在此集合體中,方便程序遍歷PLC通用接口和存儲連接PLC需要的各種參數值,圖6為多個PLC通信接口對應多個PLC的應用場景:
private void InitialPLCModule()
{
CGlobal.PLCHelpers.Clear();
foreach (DataRow currRow in m_dtPLCConnParams.Rows)
{
//PLC連接參數初始化
PLCConnItem plcItem = new PLCConnItem();
plcItem.GongweiType = m_GongweiType;
plcItem.MobanNO = m_MobanNO;
plcItem.ByteBuffer = new byte[m_MaxBytesCount];
plcItem.DBUnit = m_DBUnit;
plcItem.Address=m_Address;
//建立一個PLC通用接口類,并將其放至集合中
IPLCOperation plcHelper = PLCFactory.CreatePLC(m_plcType, plcItem);
plcHelper.OnPLCMessageChanged += new
PLCMessageEventHandler(PLCHelper_OnPLCMessageChanged);
plcHelper.ConnectPLC();
plcItem.PLCHelper = plcHelper;
CGlobal.PLCHelpers.AddPLCConnItem(plcItem);
}
}
4.2 PLC數據讀取操作
當PLC接口集合不為空時,可以循環遍歷PLC接口集合中的通用接口類,并讀取對應的PLC對應地址塊中數據放置在指定的字節數組中。
private void ReadPLCData()
{
if (CGlobal.PLCHelpers == null || CGlobal.PLCHelpers.Count == 0) return;
byte[] bytBuffer;
foreach (PLCConnItem plcItem in CGlobal.PLCHelpers)
{
if (plcItem == null || plcItem.PLCHelper == null)
{ continue; }
if (plcItem.PLCHelper.Connected)
{
bytBuffer = new byte[plcItem.ByteBuffer.Length];
bool blnSucc=plcItem.PLCHelper.ReadData(plcItem.DBUnit, 0, plcItem.ByteBuffer.Length, ref bytBuffer);
if (blnSucc) plcItem.ByteBuffer = bytBuffer;
}
else{
CGlobal.DelayTime(1000);
plcItem.PLCHelper.ReConnectPLC();
}
}
}
4.3 PLC數據寫入操作
PLC數據寫入的方法比較簡單,首先按工位類型和模板類型參數遍歷PLC接口集合中找到指定接口,然后調用對應的接口函數WriteData即可。
CGlobal.PLCHelpers[m_GongweiType,m_MobanNO].PLCHelper.WriteData
(dbunit,dwno,amount,value);
4.4 釋放PLC模塊資源
當需要釋放PLC接品資源時,需要遍歷PLC接口集合,先關閉當前連接,然后再銷毀對象即可。
if (CGlobal.PLCHelpers != null) CGlobal.PLCHelpers.Clear();
5 ?結論
以西門子的Prodave 組件為具體研究對象,結合軟件工程中的軟件設計模式思想,設計并實現了一種上位機與PLC通訊的通用接口,該通訊接口已成功應用于福建聯盛紙業PM5&6,PM7,PM8、山東太陽紙業PM19&20,24、安徽山鷹PM5&6等多套紙卷輸送控制系統中。實踐證明,該通訊接口可以使通訊模塊的代碼結構清晰,穩定性好、擴展性和集成性強且實際操作靈活方便,可適應復雜的項目工藝需求變化,具有一定的參考價值和應用價值。
參考文獻:
[1]程宏.福建聯盛紙業PM8輸送控制系統源碼,2012.
[2]程宏.山東太陽紙業PM24輸送控制系統源碼,2014.
[3]王翔.設計模式-基于C#的工程化實現及擴展[M].電子工業出版社,2012.
[4]葛新鋒,晉景濤.基于VB的上位機與PLC通信系統實現,2009.
[5]趙曉明,徐立,邵威,夏春林.基于VC++的上位機與西門子系列PLC通信的研究[J].機電工程,2007.