六大通信庫,圍攻西門子
自動化行業(yè),正在慢慢往軟件行業(yè)靠近。
西門子PLC通信一直都是很多人感興趣的話題。
本文主要以C#作為編程語言,結(jié)合目前市場上常用的6種通信庫,分別與西門子S7-1200PLC進行通信測試,并對測試結(jié)果進行分享。
通信庫簡介
一、S7.NET
簡介:S7.NET是一款開源的S7協(xié)議通信庫,支持西門子S7通信。
二、Sharp7
簡介:Sharp7與S7.NET一樣,是一款.NET版本的S7通信庫。
三、Snap7
簡介:Snap7是一個開源的C++通信庫,支持西門子S7通信。
四、Prodave
簡介:Prodave是官方提供的通信庫,支持西門子PLC各種方式通信。
五、HslCommunication
簡介:HslCommunication是一個商業(yè)通信庫,涵蓋各種不同設備的通信。
六、xktComm
簡介:xktComm是一個工業(yè)通信庫,涵蓋西門子、歐姆龍、三菱、基恩士等PLC,也支持Modbus及OPC通信。
測試編寫
1、首先創(chuàng)建了幾個變量,便于隨時修改,實現(xiàn)不同功能測試。

2、針對各個通信庫編寫通信代碼
一、S7.NET
?Console.WriteLine("S7.NET通信測試開始");
????????????objS7net?=?new?Plc(CpuType.S71200,?IpAddress,?0,?0);
????????????try
????????????{
????????????????objS7net.Open();
????????????????Console.WriteLine("S7.NET連接成功");
????????????????sw.Restart();
????????????????Count?=?0;
????????????????for?(int?i?=?0;?i?<?Times;?i++)
????????????????{
????????????????????byte[]?res?=?objS7net.ReadBytes(DataType.Memory,?0,?0,?ReadLength);
????????????????????if?(res?!=?null?&&?res.Length?==?ReadLength)
????????????????????{
????????????????????????Count++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????Console.WriteLine("S7.NET通信測試讀取失敗");
????????????????????}
????????????????}
????????????????Console.WriteLine("S7.NET通信測試結(jié)束,耗時:"?+?(sw.ElapsedMilliseconds?/?Convert.ToSingle(Times)).ToString());
????????????}
????????????catch?(Exception)
????????????{
????????????????Console.WriteLine("S7.NET連接失敗");
????????????}
二、Sharp7
Console.WriteLine("Sharp7通信測試開始");
????????????int?result?=?objSharp7.ConnectTo(IpAddress,?0,?0);
????????????if?(result?==?0)
????????????{
????????????????Console.WriteLine("Sharp7連接成功");
????????????????sw.Restart();
????????????????for?(int?i?=?0;?i?<?Times;?i++)
????????????????{
????????????????????byte[]?buffer?=?new?byte[65535];
????????????????????result?=?objSharp7.MBRead(0,?ReadLength,?buffer);
????????????????????if?(result?>?0)
????????????????????{
????????????????????????Console.WriteLine("Sharp7通信測試讀取失敗");
????????????????????}
????????????????????else
????????????????????{
????????????????????????Count++;
????????????????????}
????????????????}
????????????????Console.WriteLine("Sharp7通信測試結(jié)束,耗時:"?+?(sw.ElapsedMilliseconds?/?Convert.ToSingle(Times)).ToString());
????????????}
????????????else
????????????{
????????????????Console.WriteLine("Sharp7連接失敗");
????????????}
三、Snap7
?Console.WriteLine("Snap7通信測試開始");
????????????int?operateResult?=?objSnap7.ConnectTo(IpAddress,?0,?0);
????????????if?(result?==?0)
????????????{
????????????????Console.WriteLine("Snap7連接成功");
????????????????sw.Restart();
????????????????for?(int?i?=?0;?i?<?Times;?i++)
????????????????{
????????????????????byte[]?buffer?=?new?byte[65535];
????????????????????result?=?objSnap7.MBRead(0,?ReadLength,?buffer);
????????????????????if?(result?>?0)
????????????????????{
????????????????????????Console.WriteLine("Snap7通信測試讀取失敗");
????????????????????}
????????????????????else
????????????????????{
????????????????????????Count++;
????????????????????}
????????????????}
????????????????Console.WriteLine("Snap7通信測試結(jié)束,耗時:"?+?(sw.ElapsedMilliseconds?/?Convert.ToSingle(Times)).ToString());
????????????}
????????????else
????????????{
????????????????Console.WriteLine("Snap7連接失敗");
????????????}
四、Prodave
?Console.WriteLine("Prodave通信測試開始");
????????????short?ConNr?=?63;?
????????????string?AccessPoint?=?"S7ONLINE";??????????????????
????????????Prodave6.CON_TABLE_TYPE?ConTable;
????????????int?ConTableLen?=?System.Runtime.InteropServices.Marshal.SizeOf(typeof(Prodave6.CON_TABLE_TYPE));
????????????int?RetValue;
????????????List<byte>?list?=?new?List<byte>();
????????????foreach?(var?item?in?IpAddress.Split('.'))
????????????{
????????????????list.Add(Convert.ToByte(?item));
????????????}
????????????list.Add(0);
????????????list.Add(0);
????????????ConTable.Adr?=?list.ToArray();
????????????//?Type?of?address:?MPI/PB?(1),?IP?(2),?MAC?(3)
????????????ConTable.AdrType?=?2;?
????????????ConTable.SlotNr?=?0;?
????????????ConTable.RackNr?=?0;???
????????????RetValue?=?Prodave6.LoadConnection_ex6(ConNr,?AccessPoint,?ConTableLen,?ref?ConTable);
????????????if?(RetValue?==?0)
????????????{
????????????????Console.WriteLine("Prodave連接成功");
????????????????sw.Restart();
????????????????for?(int?i?=?0;?i?<?Times;?i++)
????????????????{
????????????????????byte[]?pReadBufferM2?=?new?byte[(uint)ReadLength];
????????????????????uint?pDatLen?=?0;
????????????????????RetValue?=?Prodave6.field_read_ex6(Prodave6.FieldType.M,?0,?0,?(uint)ReadLength,?(uint)ReadLength,?pReadBufferM2,?ref?pDatLen);
????????????????????if?(RetValue?>?0)
????????????????????{
????????????????????????Console.WriteLine("Prodave通信測試讀取失敗");
????????????????????}
????????????????????else
????????????????????{
????????????????????????Count++;
????????????????????}
????????????????}
????????????????Console.WriteLine("Prodave通信測試結(jié)束,耗時:"?+?(sw.ElapsedMilliseconds?/?Convert.ToSingle(Times)).ToString());
????????????}
????????????else
????????????{
????????????????Console.WriteLine("Prodave連接失敗");
????????????}
五、HslCommunication
??Console.WriteLine("HslCommunication通信測試開始");
????????????objHsl?=?new?SiemensS7Net(SiemensPLCS.S1200,?IpAddress);
????????????var?operate?=?objHsl.ConnectServer();
????????????if?(operate.IsSuccess)
????????????{
????????????????Console.WriteLine("HslCommunication連接成功");
????????????????sw.Restart();
????????????????for?(int?i?=?0;?i?<?Times;?i++)
????????????????{
????????????????????operate?=?objHsl.Read("M0",?(ushort)ReadLength);
????????????????????if?(operate.IsSuccess)
????????????????????{
????????????????????????Count++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????Console.WriteLine("HslCommunication通信測試讀取失敗");
????????????????????}
????????????????}
????????????????Console.WriteLine("HslCommunication通信測試結(jié)束,耗時:"?+?(sw.ElapsedMilliseconds?/?Convert.ToSingle(Times)).ToString());
????????????}
????????????else
????????????{
????????????????Console.WriteLine("HslCommunication連接失敗");
????????????}
六、xktComm
Console.WriteLine("xktComm通信測試開始");
????????????if?(objxktComm.Connect(IpAddress,?CPU_Type.S71200,?0,?0))
????????????{
????????????????Console.WriteLine("xktComm連接成功");
????????????????sw.Restart();
????????????????Count?=?0;
????????????????for?(int?i?=?0;?i?<?Times;?i++)
????????????????{
????????????????????byte[]?res?=?objxktComm.ReadBytes(StoreType.Marker,?0,?0,?ReadLength);
????????????????????if?(res?!=?null?&&?res.Length?==?ReadLength)
????????????????????{
????????????????????????Count++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????Console.WriteLine("xktComm通信測試讀取失敗");
????????????????????}
????????????????}
????????????????Console.WriteLine("xktComm通信測試結(jié)束,耗時:"?+?(sw.ElapsedMilliseconds?/?Convert.ToSingle(Times)).ToString());
????????????}
????????????else
????????????{
????????????????Console.WriteLine("xktComm連接失敗");
????????????}
測試環(huán)境
測試選擇的PLC為S7-1200,型號為CPU 1214C DC/DC/DC,為排除PLC邏輯對通信測試造成影響,PLC程序幾乎為空。
循環(huán)測試
將ReadLength設置為200,Timers設置為100,即表示單次讀取長度為200個字節(jié),循環(huán)讀取100次,取平均值作為通信測試周期,結(jié)果如下所示:

從結(jié)果可以得出以下結(jié)論:
基于C#與西門子PLC通信,單次通信時間間隔為10ms左右。
從結(jié)果來看,除了Prodave之外,其余五種通信時間幾乎一樣,Prodave稍長。
博圖影響測試
開啟TIA博圖軟件,并將其轉(zhuǎn)至在線,如下所示:

再次執(zhí)行結(jié)果如下:

通過大量測試發(fā)現(xiàn),通信時間稍有增加,大約為0.4ms。
監(jiān)控影響測試
創(chuàng)建一個監(jiān)控表,打開并監(jiān)控變量MD0,如下所示:

再次執(zhí)行結(jié)果如下:

通過大量測試發(fā)現(xiàn),通信時間增幅較大,大約為4ms。
多字節(jié)測試
將ReadLength設置為2000,Timers設置為10,即表示單次讀取長度為2000個字節(jié),循環(huán)讀取10次,取平均值作為通信測試周期,結(jié)果如下所示:

從結(jié)果可以得出以下結(jié)論:
由于S7-1200的PDU為240,因此讀取2000個字節(jié)耗時大約在100ms左右。
從結(jié)果來看,Prodave內(nèi)部沒有做分包處理,如果使用,需要二次封裝。
寫在最后
越來越多的電氣工程師意識到掌握一門高級語言的重要性,然而,很多人都苦于無法入門,為此,我們特意準備了一次上位機小白職場練造營,專門針對想要學習上位機的初學者,旨于幫助更多的電氣工程師突破技術瓶頸,在自動化的道路上走得更遠。

由于添加人數(shù)較多,可能導致無法添加,如果添加不上,可以添加備用號:xiketang777