S7協(xié)議是西門子S7系列PLC內(nèi)置的通信協(xié)議。我們使用C#、C++或者Python等高級編程語言開發(fā)的上位機如果想訪問S7系列PLC的數(shù)據(jù),那S7協(xié)議是最方便的。目前市面上也有很多開源或者閉源的基于S7的通信驅(qū)動,比如S7Net、NodeS7、Snap7等等。但是自S7-1200/1500開始,西門子將其內(nèi)置的協(xié)議升級到了S7CommPlus。該協(xié)議支持以符號名訪問PLC數(shù)據(jù),并且全面支持通信過程的認證和數(shù)據(jù)加密,使其安全性得到了很大的提高。
S7CommPlus并非開放的協(xié)議。網(wǎng)上也有一些針對該協(xié)議的研究文章。但是S7CommPlus認證過程比較復雜,沒有很扎實的網(wǎng)絡通信基礎很難分析出來,更別說基于它開發(fā)一個通信驅(qū)動了。幸運的是前一段時間無意中在網(wǎng)上發(fā)現(xiàn)了一個德國人封裝的S7CommPlus通信驅(qū)動。前幾天下載后抽空研究了下。本來沒抱太大希望,但是運行起來連接到PLCSIM Advanced后發(fā)現(xiàn)竟然可以批量獲取到PLC里面所有的標簽名。
string HostIp;
int res;
List<ItemAddress> readlist = new List<ItemAddress>();
Console.WriteLine("程序啟動......");
//設定目標PLC的IP
if (args.Length == 1)
{
HostIp = args[0];
}
else
{
HostIp = "192.168.0.10";
}
Console.WriteLine("連接至PLC: " + HostIp);
S7CommPlusConnection conn = new S7CommPlusConnection();
res = conn.Connect(HostIp);
if (res == 0)
{
Console.WriteLine("連接成功!");
Console.WriteLine("瀏覽標簽......");
// Variablenhaushalt auslesen
List<VarInfo> vars = new List<VarInfo>();
res = conn.Browse(out vars);
}
看來所言非虛,不過連續(xù)運行一段時間后,發(fā)現(xiàn)通信非常不穩(wěn)定,短則幾十秒,長則3-5分鐘就會掉一次線。
為了排除PLCSIM Advanced或者系統(tǒng)的問題,我又找了一臺S7-1200PLC來測試。發(fā)現(xiàn)可以連接到CPU,但是無法獲取標簽名。想著是不是固件版本問題。將CPU的固件版本從4.4升級到4.5后終于可以獲取到標簽名稱了。通過驅(qū)動的讀標簽值方法也可以獲取到變量的值。
Console.WriteLine("讀標簽值......");foreach (var v in vars){ readlist.Add(new ItemAddress(v.AccessSequence));} List<object> values = new List<object>(); List<UInt64> errors = new List<UInt64>(); //調(diào)用讀標簽值方法 res = conn.ReadValues(readlist, out values, out errors);
既然讀寫沒問題,那么連續(xù)運行試下穩(wěn)定性如何。一晚上沒關機,第二天起來發(fā)現(xiàn)通信依然正常。檢查應用程序的各項參數(shù)也都沒啥問題,看來穩(wěn)定性應該還行。不過經(jīng)過對比,在數(shù)據(jù)刷新速度上,S7CommPlus比之前的S7明顯慢了一些,不知道是否和中間的通信認證有關系。后面有時間再觀察看看。