由于項(xiàng)目需要連接PLC和PC,所以傳送幾種狀態(tài)和控制信息。 為了實(shí)現(xiàn)最快的響應(yīng)速度,采用了I/O直接連接。 但是,這需要添加I/O卡,與PLC的I/O功能有些重復(fù)。 那么,網(wǎng)絡(luò)通信可能嗎? 本文進(jìn)行一些實(shí)驗(yàn)。
西門子S7-1200
概述
使用的PLC是目前主流的西門子S7-1200。 支持PROFINET、PROFIBUS等網(wǎng)絡(luò)標(biāo)準(zhǔn)/協(xié)議,也可以間接連接到Modbus設(shè)備。 任何標(biāo)準(zhǔn)都有很多服務(wù)/協(xié)議。 詳情請(qǐng)參照Communication with SIMATIC 但是,這些標(biāo)準(zhǔn)中有些用于西門子的設(shè)備相互連接,不一定適用于PC。下圖為TIA門戶v 14的通信相關(guān)命令,也可作為線索。
PLC通信指令
與PC的通信可以使用OPC服務(wù)器,但它是基于OLE/COM的,只能在Windows上使用。 一些軟件(如LabView )支持與西門子PLC的通信。 是跨平臺(tái)開源方案,一個(gè)是Snap7。 先試試這個(gè)吧。 另外,請(qǐng)嘗試最原始的TCP協(xié)議。
Snap7
Snap7是針對(duì)西門子S7協(xié)議的。 PLC不需要S7的服務(wù)器這一配置,但只需要利用Snap7 lib,就可以將PC作為S7客戶端讀取/寫入服務(wù)器端的數(shù)據(jù)塊。
數(shù)據(jù)塊映射
塊分為輸入?yún)^(qū)域(DI、AI )、輸出區(qū)域) DQ、AQ )、程序塊) DB )等。 在下圖中,DB3是測(cè)試程序的數(shù)據(jù)塊。
數(shù)據(jù)塊和監(jiān)視值
可以使用Snap7包附帶的(編譯的)測(cè)試程序查看/更改值。
Snap7測(cè)試程序
訪問設(shè)置
讀寫前需要進(jìn)行配置和權(quán)限設(shè)置。 禁用塊優(yōu)化,并授予完全權(quán)限。 有關(guān)詳細(xì)信息,請(qǐng)參閱Snap7文檔。另外,有些設(shè)置未在文檔中列出,即允許從遠(yuǎn)程對(duì)象進(jìn)行PUT/GET通信訪問。 否則就會(huì)出現(xiàn)“函數(shù)不可用”,
錯(cuò)誤,如“基于函數(shù)的處理器”。
Snap7通信的訪問設(shè)定
Python版的Snap7
使用腳本語言有時(shí)會(huì)很方便。 Python-snap7是Snap7 lib的python軟件包。 因?yàn)橹皇墙涌趯拥姆庋b,所以對(duì)速度的影響很小。安裝時(shí),需要安裝Snap7庫,然后使用pip安裝python-snap7。 有些平臺(tái)沒有現(xiàn)成的Snap7庫,需要自己編譯。 總之是草莓派,我自己編譯的。 實(shí)測(cè)Python2和Python3都工作。
核心代碼如下: I/O只有2字節(jié),所以直接讀取/寫入2字節(jié)。
導(dǎo)入快照7
從快照7 .快照7類型導(dǎo)入S7區(qū)域數(shù)據(jù)庫,S7區(qū)域PA,S7區(qū)域應(yīng)用
第7類客戶端:類
def _ init _ (自,ip,槽=1,軌跡=0) :
self.client=snap7. client.client (
self.client.connect(IP,機(jī)架,插槽)。
延遲(自) :
區(qū)域=S7區(qū)域應(yīng)用
db=0
開始=0
amount=2
ba=self.client.read _ area (區(qū)域、數(shù)據(jù)庫、開始、停止) )。
d=巴西
d=8
d|=壩0
返回d
efwritedq (自,數(shù)據(jù)) :
區(qū)域=S7區(qū)域帕
db=0
開始=0
amount=2
ba=字節(jié)數(shù)組(amount )
BA0=數(shù)據(jù)0x FF
BA [1]=數(shù)據(jù)8
sel
f.client.write_area(area, db, start, ba)速度測(cè)試
循環(huán)讀/寫DQ,看看總耗時(shí)。示意代碼如下:
def testWriteLoop(self, count): d = 0 self.log.info("Write DQ from: %04x", d) t1 = time.time() while d < count: self.plc.writeDQ(d) d += 1 t2 = time.time() self.log.info("Write DQ till: %04x. Average: %.2fms", (d - 1), (t2 - t1) * 1000 / d)可以看到單次讀/寫的平均時(shí)間略高于9ms.
下圖是最低位的波形。10個(gè)周期對(duì)應(yīng)于20次寫,耗時(shí)約182ms。高低電平不對(duì)稱的問題后面再說。
反向通信
如果PC做Snap7的服務(wù)器,則PLC需要使用GET/PUT指令讀/寫PC端的數(shù)據(jù)。既然都是S7協(xié)議,我們假設(shè)它的速度和正向是相當(dāng)?shù)?,暫且跳過,先試試另一類型的通信。
原始的TCP通信
S7-1200支持開放式用戶通信,即基于TCP,但不屬于任何標(biāo)準(zhǔn)應(yīng)用層協(xié)議的,完全由用戶自己定義的協(xié)議。
實(shí)驗(yàn)設(shè)計(jì)
PC端作為服務(wù)器:實(shí)際測(cè)試使用樹莓派充當(dāng)PC的角色。PLC端發(fā)送數(shù)據(jù):由一個(gè)DI來觸發(fā)數(shù)據(jù)發(fā)送。樹莓派開啟數(shù)據(jù)發(fā)送:通過控制一個(gè)GPIO來開關(guān)繼電器,進(jìn)而改變PLC端的DI(信號(hào)1);樹莓派在收到數(shù)據(jù)后,改變另一個(gè)GPIO的狀態(tài)(信號(hào)2)作為標(biāo)志;比較信號(hào)2和信號(hào)1的時(shí)間差。PC端
PC端作為服務(wù)器,監(jiān)聽某一端口。在Linux上,可以用命令行工具netcat進(jìn)行調(diào)試。
開兩個(gè)窗口:
netcat -l 2000: 監(jiān)聽端口2000netcat localhost 2000: 與本機(jī)2000端口連接一個(gè)窗口輸入字符,另一個(gè)窗口就會(huì)顯示出來。
然后,用Python socket寫一個(gè)類似的服務(wù)器端程序,核心代碼如下:
import socket self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind(('', self.args.port)) self.sock.listen(1) self.conn, addr = self.sock.accept() data = self.conn.recv(32) self.log.info("Received: %02X %02X", data[0], data[1])可以用 netcat 測(cè)試這個(gè)服務(wù)器程序。
PLC端
PLC端使用TSEND_C發(fā)送數(shù)據(jù)。
由trigger觸發(fā)數(shù)據(jù)發(fā)送,trigger對(duì)應(yīng)于數(shù)字輸入,比如DI0.1.trigger同時(shí)觸發(fā)一個(gè)計(jì)數(shù)器。TSEND發(fā)送這個(gè)計(jì)數(shù)器的值,這樣PC每次收到的數(shù)據(jù)是遞增的。CONT設(shè)為TRUE,保持連接,這樣速度最快。在網(wǎng)絡(luò)連接設(shè)置中指定PC端的IP地址和端口號(hào),端口號(hào)要和服務(wù)器監(jiān)聽的端口號(hào)一致。由PLC主動(dòng)發(fā)起連接。
初步的結(jié)果
下圖中,黃色為PLC端的輸入(信號(hào)1),綠色為樹莓派上收到數(shù)據(jù)后的輸出(信號(hào)2)。
都以上升沿作為標(biāo)志。兩者的時(shí)間差不到9ms。
可以更快嗎?
通信負(fù)載
由通信引起的循環(huán)負(fù)荷:默認(rèn)是20%,取值可以從15%到50%。改變這個(gè)值,發(fā)現(xiàn)對(duì)通信時(shí)間并沒有影響。
輸入濾波器
這個(gè)值默認(rèn)是6.4ms,它是用來過濾按鍵抖動(dòng)的。但對(duì)于電路觸發(fā)(非人工/機(jī)械按鍵)的情況,這個(gè)抖動(dòng)可以設(shè)得很小。
將它調(diào)小至0.1ms,整個(gè)耗時(shí)降低了約6ms. 通信耗時(shí)不到3ms了。
循環(huán)時(shí)間
PLC的運(yùn)行方式是不斷循環(huán)去讀取輸入,執(zhí)行程序塊,更新輸出的模式。循環(huán)周期過長,是否會(huì)影響網(wǎng)絡(luò)通信呢?
通過在線診斷,可以看到循環(huán)時(shí)間最長為4ms,通常都在1~2ms。
這說明循環(huán)時(shí)間并不是瓶頸。而且反過來,循環(huán)時(shí)間比通信時(shí)間還短(即使輸入濾波器為6.4ms,通信時(shí)間9ms時(shí),循環(huán)時(shí)間依然是1~2ms),這說明通信和循環(huán)似乎是分頭執(zhí)行的。
其它
本來還想試一下中斷執(zhí)行方式的,但把通信程序塊放到中斷響應(yīng)里執(zhí)行并沒有成功。考慮到對(duì)于PLC的百兆網(wǎng)口,3ms已經(jīng)夠快了,就沒再折騰了。
還試驗(yàn)了一下,在PLC上單純地增加一個(gè)計(jì)數(shù)器或反復(fù)翻轉(zhuǎn)輸出電平,每次操作耗時(shí)大約也是3ms。
順便說一句,在PLC的數(shù)字輸出上,卻看不到電平的翻轉(zhuǎn)(看到的總是高電平)。前面有一張“遞增寫DQ時(shí)DQ0.0的波形”圖,18ms的周期,基本上已看不到電平下降到0了。感覺PLC的輸出頻率并不高,甚至可能有高頻濾波。
結(jié)語
從PLC的眾多網(wǎng)絡(luò)通信方式中,本文試驗(yàn)了簡單易行并且跨平臺(tái)的兩種方式,用來和PC通信。
使用基于S7協(xié)議的Snap7庫,在讀寫PLC時(shí)大約耗時(shí)9ms.使用開放式的TCP協(xié)議,PLC向PC發(fā)送數(shù)據(jù)最快不到3ms.考慮到S7-1200只是百兆網(wǎng)絡(luò),這個(gè)速度應(yīng)該是不錯(cuò)的,可以滿足大部分需要。