備通信標(biāo)準(zhǔn)化與集成實戰(zhàn))
AF框架第十二章主要解決的是設(shè)備層通信這件事。我把這一章從頭到尾過了一遍也順手在幾個實際項目里做了驗證。先說結(jié)論這一章的內(nèi)容比前面很多章節(jié)都實用如果你正在做S7-1500和第三方設(shè)備變頻器、機器人、儀表、上位機的通信對接這一章基本能把設(shè)計思路和關(guān)鍵代碼邏輯講清楚。整章看下來核心不是教你怎么寫某一條通信指令而是告訴你如何在AF框架的架構(gòu)下把通信這件事標(biāo)準(zhǔn)化、模塊化、可復(fù)用。這一章適合三類人一是已經(jīng)在用AF框架做項目的工程師想看看官方推薦的通信層怎么搭二是被各種設(shè)備通信協(xié)議搞得頭疼的PLC程序員想知道怎么用一套統(tǒng)一思路去應(yīng)對Modbus、TCP/IP、OPC UA這些常見方式三是剛接觸AF框架、讀到這一章有點懵的新手我會把里面的概念用大白話重新捋一遍順便補充一些原文檔里不會寫的實操細(xì)節(jié)。1. 這一章在AF框架中的定位1.1 從框架全局看第十二章的承上啟下AF框架Application Framework的全稱是西門子面向SIMATIC S7-1200/1500平臺的一套應(yīng)用開發(fā)框架。它不是一套現(xiàn)成的程序而是一套約定包含數(shù)據(jù)結(jié)構(gòu)約定、功能塊劃分約定、狀態(tài)機模板和命名規(guī)范??蚣芮懊嬲鹿?jié)解決的問題分別是第一章到第五章講基礎(chǔ)數(shù)據(jù)類型和通用功能塊中間章節(jié)講報警管理、配方管理、數(shù)據(jù)記錄這些都是PLC內(nèi)部的功能組織。到了第十二章視角從內(nèi)部轉(zhuǎn)向外部。這一章講的是如何讓一個基于AF框架的PLC程序和PLC之外的設(shè)備、系統(tǒng)對話。放到整個框架里看這一章更像是一個收口章節(jié)——把前面建立的標(biāo)準(zhǔn)化數(shù)據(jù)結(jié)構(gòu)通過標(biāo)準(zhǔn)化的通信通道送到外部世界去。同時它又向下兼容了老項目的遷移需求很多用戶是從S7-300/400的老程序遷移過來的老程序里各功能塊直接調(diào)用通信指令到了新框架下必須改寫這一章就給出了改寫的標(biāo)準(zhǔn)路徑。翻譯這一章的時候我的一個明顯感受是作者對通信的定位非??酥啤H聫念^到尾沒有試圖把所有通信協(xié)議都講一遍而是盯著幾個核心場景周期性數(shù)據(jù)交換、非周期性命令傳遞、故障狀態(tài)上報。圍繞這三個場景去設(shè)計功能塊才是這章真正有價值的思路。1.2 第十二章為什么聚焦通信集成AF框架前面章節(jié)處理的數(shù)據(jù)比如報警消息、配方參數(shù)、生產(chǎn)統(tǒng)計如果只存在PLC內(nèi)部價值就少了一大半。這些數(shù)據(jù)最終要交給HMI顯示、交給MES系統(tǒng)記錄、交給變頻器去執(zhí)行、交給機器人去聯(lián)動。所以第十二章必須回答一個問題在AF框架的體系下PLC如何高效、可靠地完成這一層數(shù)據(jù)交換。這一章的翻譯難點也在這里西門子官方文檔中大量使用了英文縮寫和面向?qū)ο缶幊痰母拍畋热鏸nstance、interface、callback這類詞直接翻譯成實例接口回調(diào)很容易讓習(xí)慣了傳統(tǒng)LD梯形圖編程的工程師犯迷糊。我在翻譯時做了不少本土化處理把interface拆成功能塊的對外參數(shù)把callback解釋成通信完成后的通知機制這樣讀起來順很多。另外這一章有一個隱藏前提它假設(shè)你已經(jīng)在用AF框架的數(shù)據(jù)結(jié)構(gòu)了。比如框架里定義了統(tǒng)一的設(shè)備狀態(tài)數(shù)據(jù)類型這一章的通信功能塊就直接跟這種類型對接。如果你沒有用AF框架直接看這一章會覺得很多地方多此一舉——比如為什么通信功能塊非要帶一個請求隊列而不是直接來什么處理什么。理解了框架的全局設(shè)計才能理解這些看似多余的結(jié)構(gòu)。2. 通信架構(gòu)設(shè)計思路拆解2.1 為什么AF框架堅持集中式通信管理傳統(tǒng)的PLC通信程序最常見的寫法是每個功能塊里面各自調(diào)用通信指令。比如控制變頻器的功能塊里直接寫Modbus通信指令讀取儀表的功能塊里直接寫串口通信指令。這種方式調(diào)試前期很快但項目一復(fù)雜就出問題通信指令在同一個CPU里爭搶通信資源一個功能塊卡住其他功能塊的通信全部超時第三方設(shè)備做了更換你得把所有相關(guān)功能塊翻出來改。AF框架第十二章的設(shè)計思路是反過來的它把通信這件事從業(yè)務(wù)功能塊里抽離出來形成一層獨立的通信管理層。業(yè)務(wù)功能塊需要發(fā)送數(shù)據(jù)不是直接調(diào)用通信指令而是把數(shù)據(jù)放到一個統(tǒng)一的發(fā)送緩沖區(qū)然后由通信管理功能塊統(tǒng)一調(diào)度發(fā)送。反過來接收到的數(shù)據(jù)也由通信管理功能塊統(tǒng)一接收解析后放入接收緩沖區(qū)業(yè)務(wù)功能塊自己去取。我用做飯來打個比方傳統(tǒng)寫法是每個菜館自己雇人去進貨各買各的堵在路上誰也進不來集中式通信管理是整個園區(qū)建了一個中央采購中心各菜館把需求報上去采購中心統(tǒng)一派車。單個菜館業(yè)務(wù)功能塊不再關(guān)心菜是哪兒買來的、怎么運來的只管接貨讀接收緩沖區(qū)。這種設(shè)計的第一個好處是通信通道可以被多個業(yè)務(wù)功能塊復(fù)用。AF框架里一條通信連接比如一個TCP連接可以被多個功能塊輪流使用通過請求隊列仲裁誰優(yōu)先級高誰先發(fā)。第二個好處是通信故障的隔離。通信層單獨檢測連接狀態(tài)、重試次數(shù)、超時時間業(yè)務(wù)功能塊只需要讀取通信層的狀態(tài)字就知道當(dāng)前通信是否正常而不用自己處理底層錯誤。2.2 三種典型通信方式的選型邏輯第十二章圍繞三種通信方式展開Modbus TCP、TCP/IP自定義協(xié)議、OPC UA。章節(jié)里沒有直接說什么情況下用哪種我從它的功能塊結(jié)構(gòu)上讀出了選型邏輯這里整理一下。Modbus TCP適合標(biāo)準(zhǔn)第三方設(shè)備的場景。只要設(shè)備支持Modbus TCP不管是ABB變頻器、森蘭變頻器還是各種儀表都可以用同一個功能塊接入。選它的理由是極低的對接成本——Modbus協(xié)議是公開的、結(jié)構(gòu)簡單的、幾乎所有工業(yè)設(shè)備都支持。但Modbus的缺點是數(shù)據(jù)結(jié)構(gòu)弱只能讀寄存器、線圈沒有復(fù)雜的類型系統(tǒng)也沒有設(shè)備自動識別機制。TCP/IP自定義協(xié)議適合非標(biāo)設(shè)備或系統(tǒng)的場景比如和庫卡機器人的交互、和上位機的私有協(xié)議通信。這種情況Modbus覆蓋不了需要按對方協(xié)議文檔逐字節(jié)組幀、解析。AF框架在這一塊提供的價值是把幀的組裝和拆解標(biāo)準(zhǔn)化把協(xié)議部分留給工程師自己按需填寫。OPC UA適合信息化系統(tǒng)對接比如MES、SCADA、以及過程仿真軟件的通訊熱搜詞里提到的Process Simulate通過OPC UA與西門子PLC通訊就是典型場景。OPC UA的強項是信息建模數(shù)據(jù)帶語義不用像Modbus那樣每個地址都要查表對應(yīng)。代價是通信棧和配置都更重對PLC資源占用也更高。從章節(jié)的行文看作者對三種方式的態(tài)度不是哪個先進用哪個而是哪把鑰匙開哪把鎖。這正好也是我在實際項目中的選型原則。2.3 心跳、超時與數(shù)據(jù)一致性的處理翻譯第十二章的時候心跳這個詞反復(fù)出現(xiàn)。AF框架的通信功能塊里內(nèi)置了心跳機制PLC周期性向外發(fā)送一個遞增的計數(shù)值對方設(shè)備收到后若能正?;貜?fù)說明鏈路活著如果連續(xù)幾次收不到對方的正常回復(fù)通信層自動標(biāo)記連接異常而不是繼續(xù)悶頭等數(shù)據(jù)。這個設(shè)計對工程現(xiàn)場的意義很大。很多現(xiàn)場通信問題不是一次性完全斷掉而是間歇性丟包、超時、停頓。如果沒有心跳機制業(yè)務(wù)層接收到一半數(shù)據(jù)很可能拿著不完整的數(shù)據(jù)去執(zhí)行動作這是非常危險的。有了心跳檢測就算通信抖動PLC至少知道當(dāng)前數(shù)據(jù)不可信可以切換到安全狀態(tài)。超時處理是另一個關(guān)鍵點。AF框架把所有通信請求都拆成請求—響應(yīng)配對每個請求發(fā)出后啟動一個超時定時器。定時器到點未收到響應(yīng)該請求被標(biāo)記為失敗并進入重試隊列重試超過設(shè)定次數(shù)通信功能塊向業(yè)務(wù)功能塊上報通信失敗狀態(tài)。這個模式保證了通信問題永遠不會無限期地阻塞業(yè)務(wù)邏輯——任何一次數(shù)據(jù)請求都必須在有限時間內(nèi)給出結(jié)論哪怕結(jié)論是失敗了。數(shù)據(jù)一致性這一塊章節(jié)里強調(diào)了一個容易被人忽略的點PLC和外部設(shè)備之間的數(shù)據(jù)交換不要直接把原始數(shù)據(jù)暴露給業(yè)務(wù)邏輯。AF框架的做法是設(shè)置一套鏡像區(qū)通信層把收到的數(shù)據(jù)先寫入鏡像區(qū)校驗完整后再整體更新到業(yè)務(wù)可見的數(shù)據(jù)區(qū)。這樣做的好處是業(yè)務(wù)邏輯任何時候讀取到的數(shù)據(jù)都是完整的一幀數(shù)據(jù)不會出現(xiàn)前一半是新的后一半是舊的這類錯位問題。3. 核心功能塊詳解與實操要點3.1 通信功能塊的標(biāo)準(zhǔn)結(jié)構(gòu)第十二章給出的通信功能塊對外接口并不復(fù)雜大致分四類參數(shù)控制參數(shù)、狀態(tài)參數(shù)、數(shù)據(jù)區(qū)指針、協(xié)議相關(guān)參數(shù)??刂茀?shù)管什么時候通信和和誰通信狀態(tài)參數(shù)管當(dāng)前通信狀態(tài)和最近一次錯誤碼數(shù)據(jù)區(qū)指針指向?qū)嶋H要發(fā)送或接收的數(shù)據(jù)緩沖協(xié)議相關(guān)參數(shù)是地址、端口、從站號這類信息。我在翻譯這一章時對照過其他框架的通信功能塊設(shè)計AF的處理有一個明顯特征它不允許功能塊直接持有數(shù)據(jù)存儲區(qū)而是用指針引用外部數(shù)據(jù)區(qū)。很多新手第一次讀到這個設(shè)計會不理解覺得直接把數(shù)據(jù)放在功能塊內(nèi)部多省事。但從工程角度想指針引用的方式讓一個功能塊可以服務(wù)于多組數(shù)據(jù)。比如你和十個變頻器通信不需要建十個通信功能塊實例只要建一個通信功能塊實例然后在不同的時間點讓它分別指向不同變頻器的數(shù)據(jù)區(qū)。這個設(shè)計的另外一個好處是狀態(tài)機可以獨立運行。AF框架的通信功能塊內(nèi)部是一個典型的狀態(tài)機空閑→建立連接→發(fā)送請求→等待響應(yīng)→解析數(shù)據(jù)→回到空閑。每一個狀態(tài)之間的切換條件都寫在表中現(xiàn)場出問題的時候通過狀態(tài)字就能定位到卡在哪里排查效率高很多。注意使用指針引用數(shù)據(jù)區(qū)時務(wù)必保證數(shù)據(jù)區(qū)在PLC的保持性存儲區(qū)中并避免在功能塊退出后仍然操作已失效的數(shù)據(jù)區(qū)引用。AF框架對此有專門的數(shù)據(jù)區(qū)有效性檢查功能塊翻譯時我發(fā)現(xiàn)很多項目沒用上其實是個大隱患。3.2 參數(shù)傳遞與數(shù)據(jù)類型映射這一章有大量篇幅在講數(shù)據(jù)類型映射我一開始覺得有點枯燥后來仔細(xì)看才發(fā)現(xiàn)這是實操中最容易出錯的部分。AF框架的統(tǒng)一通信數(shù)據(jù)載體是字節(jié)數(shù)組。也就是說不管外部設(shè)備是Modbus寄存器還是自定義協(xié)議最終進入PLC后都被拆成字節(jié)放進一個數(shù)組里??蚣茉偬峁┮惶子成湟?guī)則把這些字節(jié)按照項目定義的數(shù)據(jù)結(jié)構(gòu)解釋回來。比如一個雙字實數(shù)REAL在Modbus TCP上占了兩個寄存器映射進字節(jié)數(shù)組后高字節(jié)在前還是低字節(jié)在前是靠字節(jié)順序參數(shù)控制的。我看到很多工程師在這里踩坑明明通信通了數(shù)據(jù)也能收到但數(shù)值不對或者小數(shù)點位置不對原因往往就是字節(jié)順序和數(shù)據(jù)類型的長度沒配對。AF框架在功能塊里明確暴露了這兩個參數(shù)不允許開發(fā)者猜。翻譯時我把這部分單獨拎出來做了注釋一定要先確認(rèn)對方設(shè)備的字節(jié)序西門子和大部分歐洲設(shè)備默認(rèn)高字節(jié)在前但有些儀表和第三方控制器默認(rèn)低字節(jié)在前這個不對齊后面全是糊涂賬。數(shù)據(jù)類型的長度映射也值得注意。同樣是整數(shù)有BYTE8位、WORD16位、DWORD32位三種長度。外部設(shè)備和PLC之間交換數(shù)據(jù)最穩(wěn)妥的做法是統(tǒng)一約定為WORD或DWORD長度避免因?qū)Ψ桨l(fā)了16位PLC按32位解釋導(dǎo)致的高位填充垃圾數(shù)據(jù)。數(shù)據(jù)類型在字節(jié)數(shù)組中的占用常見來源易錯點BOOL1 bit按位打包設(shè)備狀態(tài)位位偏移計算和文檔不一致BYTE1 字節(jié)小數(shù)值、命令碼無符號與有符號混亂WORD2 字節(jié)整數(shù)寄存器字節(jié)序顛倒REAL4 字節(jié)模擬量、溫度等數(shù)據(jù)來自兩個寄存器時高低字順序STRING變長設(shè)備名稱、報警文本長度前綴和終止符的差異3.3 與第三方設(shè)備對接的典型案例第十二章給了幾個對接案例我挑兩個和當(dāng)前項目最貼近的展開講。第一個是西門子S7-1500與變頻器的Modbus TCP通信。AF框架的通信功能塊面向Modbus時把功能碼FC03讀保持寄存器、FC06寫單個寄存器、FC16寫多個寄存器作為顯式參數(shù)開放。實際調(diào)試中遇到ABB變頻器時最典型的坑是AB變頻器的Modbus寄存器地址文檔里寫的是40xxx這是PLC習(xí)慣的地址表示法報文里實際地址要減一40001對應(yīng)地址0。S7-1500配合AF框架在組態(tài)時直接把地址做減一處理就能避免運行時一次又一次的地址錯誤提示。而森蘭變頻器SB200系列的Modbus地址是純16進制寄存器地址不用減一兩者混用時特別容易搞混。AF框架的功能塊里把地址偏移量單獨做成了一個參數(shù)這一個參數(shù)解決了我在現(xiàn)場最頭疼的兼容問題。第二個是西門子S7-1500與庫卡機器人的交互。這種場景一般走TCP/IP或ProfinetAF框架的處理方式是定義一套標(biāo)準(zhǔn)的命令—應(yīng)答數(shù)據(jù)包結(jié)構(gòu)。PLC發(fā)送命令數(shù)據(jù)包例如請求機器人移動到位置A機器人執(zhí)行后回傳應(yīng)答數(shù)據(jù)包例如已到達位置A。章節(jié)里強調(diào)了指令去重的問題——網(wǎng)絡(luò)通信會重發(fā)機器人可能收到兩條相同的移動指令如果沒做去重機器人會重復(fù)執(zhí)行。AF框架里在數(shù)據(jù)包里加入命令序號字段PLC發(fā)出的第N條命令序號為N機器人只需記下最后一次執(zhí)行的序號序號重復(fù)則忽略。4. 移植到實際項目的完整過程4.1 從章節(jié)示例到項目代碼的翻譯路徑我拿自己最近做的一個實例說明這一章怎么落地。項目要求一臺S7-1500作為主站和兩臺ABB變頻器Modbus TCP通信、一臺庫卡機器人TCP/IP通信、一套上位機系統(tǒng)OPC UA通信同時對接。第一步先按AF框架的結(jié)構(gòu)梳理誰和誰說話。列一張通信矩陣圖每一條通信連接、對應(yīng)的設(shè)備類型、通信協(xié)議、數(shù)據(jù)交換周期、數(shù)據(jù)量大小、優(yōu)先級。這一步做完我心里就有底了——這相當(dāng)于第十二章里說的通信需求分析是整個設(shè)計的地基。第二步確定通信功能塊的實例化數(shù)量。AF框架的官方建議是一條物理連接對應(yīng)一個通信功能塊實例。我的項目里兩臺ABB變頻器可以共用一條Modbus TCP連接所以用一個通信實例庫卡機器人單獨一條TCP連接單開一個實例OPC UA走的是PLC內(nèi)置的OPC UA服務(wù)器功能AF框架主要配合做服務(wù)器側(cè)的地址空間映射不需要傳統(tǒng)意義上的通信實例。第三步配置數(shù)據(jù)區(qū)。把每一臺設(shè)備的發(fā)送數(shù)據(jù)區(qū)和接收數(shù)據(jù)區(qū)在PLC的數(shù)據(jù)塊里聲明好。數(shù)據(jù)區(qū)的大小要留足余量比如變頻器的運行參數(shù)我預(yù)計只用到10個寄存器但我會配置20個寄存器的數(shù)據(jù)區(qū)多出來的部分是給以后擴展用的。翻譯章節(jié)時看到一個觀點很認(rèn)可數(shù)據(jù)區(qū)一旦定好盡量在一個項目周期內(nèi)保持不變換地址的代價遠大于多占幾個字節(jié)的存儲。第四步逐條填寫協(xié)議參數(shù)。Modbus TCP這邊填從站地址、寄存器起始地址、寄存器數(shù)量、字節(jié)順序TCP/IP這邊填機器人的IP和端口號、幀格式定義OPC UA這邊主要是建立服務(wù)器配置把需要開放給上位機的變量掛到地址空間。第五步寫業(yè)務(wù)側(cè)的調(diào)用邏輯。業(yè)務(wù)功能塊在需要通信的時刻把數(shù)據(jù)寫入發(fā)送數(shù)據(jù)區(qū)然后把發(fā)送請求標(biāo)志置位。通信功能塊檢測到請求標(biāo)志從發(fā)送數(shù)據(jù)區(qū)取數(shù)發(fā)出報文收到應(yīng)答后把數(shù)據(jù)寫入接收數(shù)據(jù)區(qū)并清除請求標(biāo)志。整個過程業(yè)務(wù)代碼完全不用關(guān)心底層協(xié)議這和第二章說的接口與實現(xiàn)分離一脈相承。4.2 與熱搜場景的交叉驗證看那些經(jīng)典問題怎么解熱搜詞里有一類高頻問題我今天翻譯完第十二章突然感覺它們其實都是同一個答案的不同變體。這類問題是西門子PLC與三菱變頻器RS485通訊S7-200 SMART與森蘭變頻器通信Modscan能讀串口數(shù)據(jù)但西門子組態(tài)軟件不能讀。先說S7-200 SMART與三菱變頻器RS485通信。三菱變頻器的RS485協(xié)議和標(biāo)準(zhǔn)的Modbus RTU不完全一致特別是命令幀的CRC校驗和站號定義都有廠商的特殊處理。AF框架雖然以S7-1500為主但它對通信功能塊的抽象思路是通用的把協(xié)議差異封裝進功能塊內(nèi)部對外暴露的永遠是請求數(shù)據(jù)、響應(yīng)數(shù)據(jù)、錯誤碼這三樣。你要是用這個思路去看S7-200 SMART的通信就會很自然地想到把三菱特有的協(xié)議寫成一個獨立的協(xié)議轉(zhuǎn)換子程序和主通信邏輯分開。這個思路比試圖在梯形圖里一行行調(diào)CRC要省心太多。另外一類問題是第三方上位機讀不到PLC數(shù)據(jù)。比如KepServer連接S7-1500時讀不到數(shù)據(jù)或者Process Simulate通過OPC UA與西門子PLC無法交互。這類問題十有八九不是通信層斷了而是數(shù)據(jù)模型沒有對上。AF框架在第十二章前面幾節(jié)強推的統(tǒng)一數(shù)據(jù)塊結(jié)構(gòu)恰好能幫你把給上位機看的數(shù)據(jù)單獨整理出來結(jié)構(gòu)清晰、變量名規(guī)范KepServer或OPC UA客戶端在瀏覽時一目了然。很多人不用框架的套路直接裸奔用DB塊地址亂七八糟上位機工程師連變量都找不到自然讀不到數(shù)據(jù)。我遇到過一次類似情況最后發(fā)現(xiàn)是DB塊沒有做非優(yōu)化訪問外部OPC UA無法識別優(yōu)化訪問的DB塊。這個細(xì)節(jié)AF框架相關(guān)的章節(jié)里反復(fù)提到過屬于典型的框架避免的坑。關(guān)于Modscan能讀串口數(shù)據(jù)但西門子組態(tài)軟件不能讀這一類問題則是另一個維度。Modscan是通用的Modbus調(diào)試工具它讀數(shù)據(jù)不分地址區(qū)只要鏈路通就一定能讀到。但西門子組態(tài)軟件有明確的地址區(qū)劃分I區(qū)、Q區(qū)、M區(qū)、DB區(qū)如果你把儀表數(shù)據(jù)放到了一個和組態(tài)配置不一致的地址區(qū)Modscan照常能讀組態(tài)軟件卻找不到。解決思路還是那一套先建標(biāo)準(zhǔn)的數(shù)據(jù)映射表再配置組態(tài)軟件而不是配錯了之后到處發(fā)帖問。4.3 從S7-1200/1500延伸到S7-200 SMART的遷移技巧AF框架雖然主要針對S7-1200/1500但我發(fā)現(xiàn)很多人想把其中思路用到S7-200 SMART上因為200 SMART做小型設(shè)備項目量很大。第十二章里的通信架構(gòu)思想可以用但具體實現(xiàn)要降級。S7-200 SMART的分區(qū)存儲和指令集都比1500簡單沒法完全照搬AF的通信管理層鏡像數(shù)據(jù)區(qū)指針引用。我在幾個小項目里是這么做的把AF框架的集中式思路簡化成兩個全局?jǐn)?shù)據(jù)塊一個通信子程序。全局?jǐn)?shù)據(jù)塊A存所有發(fā)送數(shù)據(jù)全局?jǐn)?shù)據(jù)塊B存所有接收數(shù)據(jù)通信子程序統(tǒng)一處理RS485或TCP外部設(shè)備的數(shù)據(jù)分發(fā)靠子程序里的索引表完成。這個簡化版雖然少了AF的完整狀態(tài)機和自動重試但在資源有限的CPU上跑得很穩(wěn)定而且保留了最核心的收益——業(yè)務(wù)代碼和通信代碼分離。翻譯章節(jié)時發(fā)現(xiàn)AF框架作者在開篇其實說過一句話大意是框架是為了讓代碼更清晰、更可維護而不是為了框架而框架。這句話放在S7-200 SMART的簡化方案上非常合適我們借鑒的是思想不必糾結(jié)形似。5. 常見問題與排查實錄5.1 通信失敗的三類典型原因這一章最后一部分結(jié)合我自己的調(diào)試經(jīng)歷把通信失敗的常見原因歸成三類。第一類是參數(shù)配置錯誤。IP地址、端口、從站號、寄存器地址這一類看似簡單的錯誤反而最難查因為報錯不明顯。我的習(xí)慣是任何通信功能塊接入新設(shè)備第一件事不是看功能塊是否通信成功而是用一個通用調(diào)試工具比如Modscan直接對設(shè)備發(fā)報文先確認(rèn)設(shè)備本身沒問題再回過來查PLC側(cè)的配置。這樣可以快速把問題范圍縮小一半。第二類是通信資源沖突。PLC的通信資源是有限的S7-1500同時建立的TCP連接、Modbus連接、OPC UA會話數(shù)都有上限。項目里多個設(shè)備同時對接時如果連接數(shù)超過了CPU的許可范圍新連接會建立失敗但舊連接的異常未必會立刻暴露。這里要用第十二章通信狀態(tài)里的連接計數(shù)實時監(jiān)控已用連接數(shù)。第三類是PLC程序掃描周期與通信周期不匹配。如果CPU掃描周期遠大于通信超時時間功能塊還沒來得及處理收到的數(shù)據(jù)超時標(biāo)志就先置位了。這種情況下通信本身是通的但邏輯處理不過來。AF框架提供的解決辦法是調(diào)整通信功能塊的調(diào)用位置——把它放到一個高優(yōu)先級的中斷OB里保證通信數(shù)據(jù)的處理不被普通的IO刷新延誤。癥狀可能原因快速驗證方法解決動作通信完全不通物理鏈路斷開或參數(shù)配置錯誤檢查網(wǎng)線指示燈、用調(diào)試工具直連設(shè)備排除物理問題后逐項核對IP/端口/站號時通時斷通信資源沖突或電磁干擾查看通信狀態(tài)里的連接計數(shù)和錯誤碼減少并發(fā)連接或加裝網(wǎng)絡(luò)隔離器數(shù)據(jù)能通但數(shù)值不對字節(jié)序或數(shù)據(jù)類型映射錯誤用固定值回環(huán)測試發(fā)已知數(shù)看收到什么修正字節(jié)順序或調(diào)整數(shù)據(jù)類型長度偶發(fā)超時掃描周期與通信周期不匹配比較CPU掃描周期和通信超時時間將通信功能塊移到中斷OB中執(zhí)行上位機讀不到數(shù)據(jù)數(shù)據(jù)塊優(yōu)化訪問或地址區(qū)不匹配在上位機地址空間直接瀏覽PLC數(shù)據(jù)關(guān)閉優(yōu)化訪問按模塊標(biāo)準(zhǔn)地址區(qū)重新映射5.2 通信數(shù)據(jù)錯亂的深坑不是你錯了是它自帶偏移這是我翻譯第十二章時最有共鳴的部分也是很多現(xiàn)場排查到深夜才發(fā)現(xiàn)的問題。Modbus協(xié)議本身的寄存器地址是零基的但不同廠商的文檔習(xí)慣于用一基甚至四萬系列的表示法。比如變頻器參數(shù)P100文檔里標(biāo)注Modbus地址為40100實際報文中的地址卻是99。這種偏移量問題一個項目里有三四種變頻器每一種的偏移規(guī)則都略有不同光靠人工配對必然出錯。AF框架的方案是在通信功能塊里內(nèi)置一個地址解碼規(guī)則從設(shè)備型號到實際地址的映射全部自動化。換句話說你以后在這個框架下接新設(shè)備只需要添加一條地址映射記錄剩下的計算全部由代碼完成。話雖如此我要提醒一句這類映射規(guī)則一定要在項目文檔里留痕否則過幾個月回來看代碼你會想不通為什么當(dāng)初40001被減了一。團隊項目里這類魔法數(shù)字最容易引起交接時的互相傷害。5.3 功能塊實例化的內(nèi)存分配問題第十二章末段討論了多個通信實例時的內(nèi)存規(guī)劃。這里有一個反直覺的點通信功能塊實例的數(shù)量不是越多越好因為每一個實例都會占用獨立的背景數(shù)據(jù)塊背景DB這塊內(nèi)存在CPU里是固定占用的哪怕該實例沒有建立通信。我在一個早期項目里就吃過虧S7-1500的CPU看著內(nèi)存很大覺得多開幾個通信實例沒問題結(jié)果程序做到后段發(fā)現(xiàn)MEM存儲區(qū)不夠用了還得回頭刪減實例數(shù)量重構(gòu)通信邏輯。后來學(xué)聰明了按AF框架文檔的建議一個通信實例覆蓋多條邏輯鏈路靠路由表區(qū)分不同設(shè)備而不是簡單粗暴地一臺設(shè)備一個實例。這個操作在第十一章的后半段也提過第十二章算是把應(yīng)用細(xì)節(jié)補齊了。注意通信功能塊的實例化除了內(nèi)存開銷還有掃描時間開銷。每一個實例在每次掃描中都要執(zhí)行狀態(tài)機處理實例過多會拉長程序掃描周期。評估實例數(shù)量時既要看內(nèi)存也要看CPU的循環(huán)時間預(yù)算。6. 翻譯筆記之外的實戰(zhàn)心得6.1 這一章最值得反復(fù)讀的三處如果把這一章壓縮成必須記住的三句話我的選擇是第一通信層必須和業(yè)務(wù)層解耦。哪怕你不是用AF框架也建議把通信的收發(fā)邏輯封裝成獨立的功能塊不要散落到各個業(yè)務(wù)塊里。我在后續(xù)項目中改變最大的地方就是這一條——程序結(jié)構(gòu)清晰了排查問題的難度會降一個量級。第二通信狀態(tài)必須暴露給HMI。AF框架的通信功能塊帶有完整的狀態(tài)字未初始化、建立中、運行正常、重試中、通信失敗這些狀態(tài)不要只在程序里用把它傳到HMI畫面上操作工能第一時間看到通信閃斷而不是等到數(shù)據(jù)異常了才發(fā)現(xiàn)。我自己被操作工問過無數(shù)次為什么數(shù)據(jù)不動了后來加上通信狀態(tài)顯示這類問題幾乎絕跡。第三統(tǒng)一的數(shù)據(jù)區(qū)勝過散亂的通信指令。哪怕你只是做一個很小的設(shè)備只有一臺變頻器一條通信也建議單獨建一個數(shù)據(jù)塊存放通信數(shù)據(jù)而不是隨手放在某幾個M位和M字里。數(shù)據(jù)區(qū)統(tǒng)一調(diào)試時能少花一半時間交接時也能少挨一半罵。6.2 用AF框架第十二章避免改了上位機又忘了PLC的尷尬做通信項目的過程中最容易出現(xiàn)的問題是上位機側(cè)改了地址但PLC側(cè)忘了同步。熱搜詞里反復(fù)出現(xiàn)KepServer、OPC UA、組態(tài)軟件連不上PLC等問題大多和這種兩側(cè)不同步有關(guān)。AF框架在第十二章給出的解法是把PLC對外通信的數(shù)據(jù)全部集中到一個通信映射區(qū)上位機和PLC約定只通過這個映射區(qū)交換數(shù)據(jù)PLC側(cè)其他任何變量都不直接對上位機開放。這樣改地址時只需要改映射區(qū)里的一條記錄PLC程序和上位機配置同步修改即可大大減少只改了一頭的概率。我在實際項目中用這個方法做得比較徹底映射區(qū)里連注釋都寫上此地址與上位機綁定修改必須通知上位機工程師。這樣做看起來有點機械但在多人協(xié)作的項目里這是最不依賴個人記憶的可靠方案。6.3 翻譯視角的補充英德原始文檔里那些翻譯不出來的坑這一章的英文原版和中文習(xí)慣很大的一個差異是英文里的configuration和parameter在原文里經(jīng)?;煊谩7g到中文時如果都翻成參數(shù)會掩蓋兩者的區(qū)別。我在處理時做了區(qū)分configuration翻成組態(tài)指設(shè)備級的參數(shù)集合如通信初始化配置parameter翻成參數(shù)指運行過程中可以動態(tài)調(diào)整的量。這個區(qū)分很重要因為AF框架里通信功能塊的組態(tài)是在下載程序前定好的而參數(shù)可以在HMI上運行時修改。如果概念混在一起新手很容易在運行時盲目修改組態(tài)項導(dǎo)致功能塊重新初始化通信閃斷。另外德軍原版里很多動詞的語義比英文復(fù)雜一層翻譯成英文本身就已經(jīng)丟信息。比如überwachen這個詞英文翻成monitor中文再翻成監(jiān)視三重翻譯下來原文里帶有主動干預(yù)含義的監(jiān)視這個信息就丟了。AF框架里的很多監(jiān)視功能塊其實不只是監(jiān)視還包含超限自動修正的含義。我在翻譯時會在這類詞后面加括號備注原文提醒自己也是提醒讀者不要小看這些詞義差異它直接決定你理解功能塊的行為邊界。6.4 關(guān)于深入學(xué)習(xí)這一章的建議如果你決定啃下AF框架第十二章并實際用起來我給三條學(xué)習(xí)路徑的建議。第一先搭硬件環(huán)境再讀文檔。沒有實際PLC和第三方設(shè)備或者仿真軟件讀這一章很容易覺得抽象。哪怕你只有一臺S7-1500本機也可以先建兩個通信功能塊做回環(huán)測試PLC自己發(fā)自己收把整個通信流程跑通再去看書本里的擴展內(nèi)容?;丨h(huán)通了后面的事情都順理成章。第二帶著什么時候用得上去讀。這一章每一節(jié)解決一類問題。你在做上位機對接就重點看OPC UA那幾節(jié)你在做變頻器通信就重點看Modbus那幾節(jié)在做機器人聯(lián)動重點看TCP/IP那幾節(jié)。工作驅(qū)動型的閱讀比從頭到尾通讀效率高很多。第三把這一章和AF框架里的報警管理、配方管理章節(jié)聯(lián)動起來看。你會慢慢發(fā)現(xiàn)通信只是手段標(biāo)準(zhǔn)化的數(shù)據(jù)在系統(tǒng)里流動才是目的。第十二章在整本書里不孤立它和前后章節(jié)一起構(gòu)成了西門子這套框架的完整閉環(huán)。這就是從會用一個功能塊到會搭一個可維護系統(tǒng)的關(guān)鍵一步。