陳雪嬌,繆文南
(華南理工大學 廣州學院, 廣州 510800)
西門子 S7-1200 定位于“低端的離散自動化系統和獨立自動化系統中使用的小型控制器模塊”,充分滿足于中小型自動化的系統需求。此系列產品的設計充分考慮了系統、控制器、人機界面和軟件的無縫整合和高效協調的需求[1-4]。特別是面向小規模裝置的可編程控制器,具有符合不同用途的通信功能,如:與控制柜內的顯示器及變頻器的連接、遠程監控等。
目前,由于西門子公司沒有公開通信協議,上位機程序設計主要有兩種方式:采用專門的組態軟件(如 WinCC、組態王等)開發或是通過編程語言自行開發。第1 種方法操作簡單、效率高,對開發人員的要求相對較低,但成本較高;第 2 種方法相對復雜,要求開發者具有較高的編程水平,開發周期長,但與第1 種方法相比具有靈活、成本低的優點[5-7]。本文采用第二種方法。
在進行通訊前需要對西門子PLC進行配置,本次采用西門子公司生產的S7-1200系列PLC,CPU型號為1212C,集成以太網通訊模塊,在使用第三方程序對PLC進行讀寫之前,需要對PLC進行權限設置,允許遠程連接PLC,以TIA PORTAL V13為例,打開設備屬性——常規選項卡——web服務器——保護——勾選允許遠程連接,如圖1所示。
Socket建立在傳輸層協議(TCP和UDP)之上,由于TCP面向連接,UDP是無連接的,因此,利用Socket進行通信,有兩種方式:面向連接的和無連接的[8-9]。在第一種方式下,兩個通信的應用程序之間必須先建立一種虛擬的連接,然后再傳輸數據。第二種方式也稱數據報文方式,在此種方式下,傳輸過程中,數據有可能丟失,先發送的數據也可能后到,各個報文的路徑也不定相同[3]。本文采用面向連接的通信方式,讀數據的流程如圖2所示。寫數據的流程和讀數據的流程是一致的,把圖1中讀數據的模塊改為寫數據模塊即可。

圖1 PLC設備的屬性設置

圖2 讀數據流程
通過安裝選裝Ethernet通信單元,加上SOCKET服務,可實現在以太網下的高速穩定的數據讀寫功能。而在C#中,System.Net.Sockets命名空間為需要嚴密控制網絡訪問的開發人員提供了Sockets接口的托管實現。System.Net命名空間中的所有其他網絡訪問類都建立在該套接字Socket實現之上,如TCPClient、TCPListener和UDPClient類封裝有關創建到Internet的TCP和UDP連接的詳細信息;NetworkStream類則提供用于網絡訪問的基礎數據流等.
定義SOCKET連接及設置:
mSocket=newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
IPEndPoint server = newIPEndPoint(IPAddress.Parse(RemoteIP), RemotePort);
連接:
mSocket.Connect(server);
一般情況下,電腦IP和PLC IP設置正確后連接都沒有問題,但這一步只表明和PLC的TCP網絡連接成功,并不代表能對PLC進行數據讀寫.
在TCP連接正常后,需要對PLC發送特定的指令才能實現讀寫功能.
try
{
……
//S7-1200系列PLC以下內容和西門子其他類型不同
mSendArray [11]=193;
mSendArray [12]=2;
mSendArray [13]=1;
mSendArray [14]=0;
mSendArray [15]=194;
mSendArray [16]=2;
mSendArray [17]=3;
mSendArray [18]=(byte)(Rack*2*16+Slot); //rack--機架號,slot--槽號,根據PLC實際配置情況設置,單CPU時rack默認為0,slot默認為1
……
mSocket.Send(bSend1, 22, SocketFlags.None);
//收到PLC正確回復后,可以進行數據讀寫
if (mSocket.Receive(bReceive, 22, SocketFlags.None) !=22)
{
thrownewException(ErrorCode.WrongNumberReceivedBytes.ToString());
}
}
catch (Exception)
{
return -1;
}
讀數據也是采用SOCKET方式進行,直接使用PLC地址即可讀取該地址內容,地址格式如:M0.0;MB0;MD0;DB1.DBX0.0;DB20.DBD200;T45等.
針對不同的變量類型,需要轉換成不同的字節長度:
privateint VarTypeToByteLength(VarType varType, int varCount=1)
{
switch (varType)
{
caseVarType.Bit:
return varCount; //TODO
caseVarType.Byte:
return (varCount < 1) ? 1 : varCount;
caseVarType.String:
return varCount;
caseVarType.Word:
caseVarType.Timer:
caseVarType.Int:
caseVarType.Counter:
return varCount * 2;
caseVarType.DWord:
caseVarType.DInt:
caseVarType.Real:
return varCount * 4;
default:
return 0;
}
}
寫數據也是采用SOCKET方式進行,直接使用PLC地址即可讀取該地址內容,地址格式和讀數據時相同,需要注意的是寫值時寫的值類型和該地址的類型必須相同,例:M0.0只能寫入bit類型,MB0只能寫入byte類型。
本文件介紹了在TCP協議下如何使用C#編程語言對西門子PLC進行數據讀寫操作,依靠C#編程語言的簡便性及socket服務的通用性,實現了對西門子PLC數據的讀寫操作,最后需要說明一點,C#編程語言自身帶有內存回收機制,在關閉軟件時,所有資源會自動釋放,但在程序未關閉時多次使用socket服務連接PLC時,在每次連接結束后需要手動釋放資源,否則可能導致無法連接。