解析)
車間里一臺老設備改造客戶提了個要求別加運動控制卡就用PLC上閑置的那個485口把伺服帶起來。我第一反應就是匯川伺服加Modbus-RTU——不用額外買通訊板卡不用換驅(qū)動器一條雙絞線就能讓西門子PLC和匯川伺服對上話。這篇文章就把我從Modbus-RTU幀結(jié)構(gòu)解析、匯川伺服參數(shù)設置到西門子PLC側(cè)程序配置的完整過程記錄下來算是一份能直接參考復現(xiàn)的實戰(zhàn)文檔。適合正在做設備改造、維護調(diào)試或者剛接觸伺服總線通訊的工程師。很多朋友一聽到“總線通訊”就發(fā)怵覺得協(xié)議高深莫測。實際把Modbus-RTU拆開看無非就是按固定格式發(fā)一串16進制字節(jié)伺服收到后回一串字節(jié)僅此而已。真正干活時讓人卡殼的往往是幾個細節(jié)CRC校驗怎么算、寄存器地址從哪查、PLC里那個ADDR參數(shù)怎么拼、伺服使能后為什么不動。這些我都會在下面逐個講透。1. 方案選型為什么是Modbus-RTU1.1 匯川伺服的主流通訊方式對比匯川伺服驅(qū)動器以常見的IS620N系列為例本身支持脈沖、CANopen、EtherCAT、Modbus-RTU等好幾種控制方式。選型時很多人糾結(jié)我直接給一張對比表大家按場景對號入座??刂品绞酵ㄓ?信號介質(zhì)典型周期成本適用場景脈沖脈沖方向信號實時性取決于發(fā)脈沖頻率最低無需通訊模塊簡單單軸定位PLC高速脈沖口夠用CANopenCAN總線1-10ms中多軸中小型設備PLC帶CAN口EtherCAT以太網(wǎng)0.125-1ms較高多軸高速高精度需要專用主站Modbus-RTURS48510-50ms取決于輪詢低老設備改造、少軸點位控制、PLC僅支持串口從成本角度講Modbus-RTU幾乎不增加硬件成本。PLC自帶RS485口或加一個幾十塊的通訊板伺服用標準RJ45或端子接線兩邊撥碼一撥就完事。對于老設備改造、單軸或兩三軸的點位控制這種方案性價比極高。1.2 Modbus-RTU的性能邊界Modbus-RTU不是萬能的它的性能邊界得說清楚免得大家踩坑。RS485串口通訊常見波特率9600或19200算一幀十幾字節(jié)的數(shù)據(jù)再加上幀間隔主站輪詢一個從站大約要5-10ms。如果你帶三五臺伺服完整輪詢一圈可能到30-50ms。這個響應速度做點位運動控制、速度控制、狀態(tài)監(jiān)控完全夠用但要做多軸插補、高速高精輪廓加工那就別指望它了老老實實上EtherCAT。還有一點要注意Modbus-RTU是半雙工主從協(xié)議所有通訊由主站發(fā)起從站之間不能直接通訊。這意味著你的控制邏輯必須集中在PLC側(cè)伺服側(cè)的“聯(lián)動”需要通過PLC輪詢來實現(xiàn)。好在匯川伺服大部分運動控制是“給目標位置、觸發(fā)運行”這種點位模式天然適合Modbus-RTU。1.3 硬件準備與組網(wǎng)拓撲本次實戰(zhàn)所用硬件清單如下匯川伺服驅(qū)動器IS620N一臺配套伺服電機MS1H4系列西門子S7-1200 PLC一臺外加CM1241 RS485通訊模塊訂貨號6ES7241-1CH30-1XB0USB轉(zhuǎn)RS485調(diào)試工具一個用于先單獨驗證伺服通訊屏蔽雙絞線若干米RS485通訊線組網(wǎng)拓撲很簡單PLC的CM1241模塊的RS485口作為主站用屏蔽雙絞線引出A、B兩線接到伺服驅(qū)動器的485通訊端子上。需要注意的是如果鏈路上有多臺伺服每臺的從站地址要設置成不同編號鏈路兩端設備需要啟用終端電阻。這一點我在后面的調(diào)試章節(jié)還會重點講。2. Modbus-RTU幀結(jié)構(gòu)解析先把協(xié)議啃透2.1 報文幀的基本組成Modbus-RTU一幀報文包含四個部分從站地址、功能碼、數(shù)據(jù)區(qū)、CRC校驗??雌饋砗唵蔚總€字節(jié)在總線上的時序是有嚴格要求的。字段長度說明從站地址1字節(jié)0-2471-247可用0為廣播地址功能碼1字節(jié)03讀寄存器、06寫單個寄存器、10十六進制0x10寫多個寄存器數(shù)據(jù)區(qū)N字節(jié)取決于功能碼包含寄存器起始地址、數(shù)據(jù)長度、數(shù)據(jù)內(nèi)容CRC校驗2字節(jié)CRC16-Modbus低字節(jié)在前幀與幀之間必須有至少3.5個字符時間的空閑間隔。以9600波特率為例一個字符大約1ms3.5個字符就是3.5ms左右。如果兩幀之間的間隔太短接收方可能把兩幀數(shù)據(jù)當成一幀處理導致解析錯亂。做PLC通訊程序時如果調(diào)用通訊指令的頻率過高反而可能觸發(fā)這個問題。2.2 三種核心功能碼03、06、10本次實戰(zhàn)用到三個功能碼分別是讀寄存器、寫單個寄存器、寫多個寄存器030x03讀保持寄存器用于讀取伺服的狀態(tài)字、實際位置、實際速度等。報文格式是“從站地址03起始地址高字節(jié)起始地址低字節(jié)寄存器數(shù)量高字節(jié)寄存器數(shù)量低字節(jié)CRC”。060x06寫單個寄存器用于寫控制字、模式切換等單字操作。報文格式是“從站地址06寄存器地址數(shù)據(jù)CRC”。100x10寫多個寄存器用于寫目標位置、目標速度這類32位數(shù)據(jù)。因為一個寄存器只有16位32位數(shù)據(jù)需要占用兩個連續(xù)寄存器這時候必須用0x10功能碼一次寫入兩個字。舉個例子讀取1號從站、寄存器地址0x0B01、長度為1個字報文就是01 03 0B 01 00 01 CRC_LO CRC_HI其中0B01就是要讀取的寄存器地址0001表示讀取1個寄存器。對應匯川伺服的H0B-01對象字典也就是狀態(tài)字。2.3 CRC校驗的原理與手算方法CRC校驗是Modbus-RTU最容易讓新手迷糊的地方。如果你用串口調(diào)試助手手動發(fā)幀不把CRC算對伺服絕對不搭理你。CRC16-Modbus的算法核心是初始值0xFFFF多項式0xA001逐字節(jié)處理。我習慣在電腦上用Python腳本算CRC函數(shù)就這么幾行def crc16_modbus(data: bytes) - int: crc 0xFFFF for byte in data: crc ^ byte for _ in range(8): if crc 1: crc (crc 1) ^ 0xA001 else: crc 1 return crc舉例要發(fā)送01 03 0B 01 00 01這6個字節(jié)先把這6個字節(jié)傳入函數(shù)得到CRC值然后將CRC的低字節(jié)放在幀尾倒數(shù)第二位高字節(jié)放在最后一位。也就是很多文檔里寫的“低字節(jié)在前”。當時我剛開始做串口調(diào)試時就栽在這個字節(jié)序上把高低字節(jié)寫反伺服一直無響應排查了半天才發(fā)現(xiàn)是CRC字節(jié)序問題。2.4 用串口調(diào)試工具先驗證一幀拿到驅(qū)動器后我強烈建議先用USB轉(zhuǎn)RS485工具連接伺服配合串口調(diào)試助手手動發(fā)送一幀讀取狀態(tài)字的報文確認伺服能正常回復。這一步能幫你把“伺服通訊問題”和“PLC通訊問題”分開極大縮小排查范圍。我的調(diào)試流程是這樣的打開串口調(diào)試助手設置串口號、波特率9600、數(shù)據(jù)位8、偶校驗、停止位1然后手動發(fā)送01 03 0B 01 00 01 CRC_LO CRC_HI如果一切正常會收到類似01 03 02 00 06 CRC_LO CRC_HI其中01是從站地址03是功能碼02表示后面有2個字節(jié)數(shù)據(jù)00 06就是狀態(tài)字的內(nèi)容??吹竭@個響應說明驅(qū)動器通訊通道完全正常接下來再去折騰PLC程序思路就清晰很多。3. 匯川伺服側(cè)參數(shù)設置讓驅(qū)動器開口說話3.1 通訊參數(shù)組H0C的設置匯川伺服驅(qū)動器的參數(shù)通過前面板或調(diào)試軟件InoDriverShop修改。Modbus-RTU通訊需要設置H0C組的幾個參數(shù)我用表格整理了一份常用配置。參數(shù)含義常用設置說明H0C-00從站通訊地址1范圍1-127多臺伺服必須不同H0C-01通訊波特率596000-9對應不同波特率具體查閱手冊H0C-02數(shù)據(jù)格式18E18個數(shù)據(jù)位偶校驗1個停止位H0C-03通訊協(xié)議選擇Modbus-RTU部分固件版本還需要設置協(xié)議類型H0C-05485終端電阻按需鏈路終端設備設為1中間設備設為0H0C-06通訊超時時間100ms主站超時后驅(qū)動器報警這里最需要注意的是H0C組參數(shù)修改后部分參數(shù)需要驅(qū)動器重新上電才能生效。我遇到過好幾次現(xiàn)場改完參數(shù)直接發(fā)報文驅(qū)動器不響應結(jié)果發(fā)現(xiàn)是參數(shù)沒真正加載。一般操作是修改后保存參數(shù)然后斷電報文再重新上電。3.2 控制模式與指令來源的確認要讓伺服通過Modbus-RTU接收位置指令光配好通訊參數(shù)還不夠還得把驅(qū)動器的控制模式和指令來源切到Modbus通訊。匯川IS620N中一般用H02組參數(shù)設置控制模式位置控制、速度控制還是轉(zhuǎn)矩控制。點位運動用位置控制模式也就是H02-01設為位置控制。關鍵是指令來源。默認情況下驅(qū)動器可能從脈沖端子接收指令必須把位置指令來源修改為Modbus通訊。具體是H02-03還是H0D組不同固件版本略有差異我建議直接以隨機附帶手冊的“運行指令來源”章節(jié)為準。設置完同樣要保存并重新上電。3.3 對象字典H0B組PLC眼中的伺服寄存器匯川IS620N將Servo對象字典映射到了Modbus保持寄存器區(qū)以H0B組為主。下面這張表是本次實戰(zhàn)最核心的寄存器映射建議截圖保存。Modbus寄存器地址對象字典含義讀寫屬性0x0B00H0B-00控制字讀寫0x0B01H0B-01狀態(tài)字只讀0x0B02H0B-02目標位置32位讀寫0x0B03H0B-03實際位置32位只讀0x0B04H0B-04目標速度32位讀寫0x0B05H0B-05實際速度32位只讀0x0B06H0B-06目標轉(zhuǎn)矩只讀0x0B07H0B-07實際轉(zhuǎn)矩只讀注意32位的數(shù)據(jù)比如目標位置在Modbus里占兩個字默認高位字在前、低位字在后也就是大端模式。在PLC側(cè)組裝數(shù)據(jù)時一定要先放高16位再放低16位。我見過不少同行把高低字顛倒結(jié)果伺服走的位置完全不是預想值。3.4 默認編碼器線數(shù)是262144這個數(shù)值能改嗎這是很多匯川伺服用戶都問過的問題。MS1H4系列電機配絕對值編碼器默認分辨率是262144線也就是電機轉(zhuǎn)一圈編碼器反饋262144個脈沖。那這個“262144”到底能不能改我的答案很明確編碼器本身的分辨率是硬件特性不能通過參數(shù)修改。出廠后的262144就固定在編碼器內(nèi)部改不了也不需要改。但為什么有人覺得它能改因為在伺服驅(qū)動器的參數(shù)里確實提供了編碼器分頻輸出比如H05組的脈沖輸出分頻和電子齒輪比電子齒輪分子/分母等參數(shù)。這些參數(shù)修改的是驅(qū)動器對外輸出的脈沖數(shù)或指令換算關系不會改變編碼器內(nèi)部的實際分辨率。舉個例子你可以設置電子齒輪比讓PLC每發(fā)1000個脈沖電機轉(zhuǎn)一圈但電機內(nèi)部編碼器反饋的仍是262144線分辨率精度并沒有降低。所以當你看到驅(qū)動器里顯示262144時不要去糾結(jié)怎么把它改小。你真正需要操心的是電子齒輪比的計算讓PLC發(fā)的用戶單位符合你想要的脈沖當量。3.5 電子齒輪比的計算示例電子齒輪比解決的是“PLC發(fā)的用戶單位”和“電機實際轉(zhuǎn)多少圈”之間的換算。假設現(xiàn)場要求PLC發(fā)送10000個單位電機剛好轉(zhuǎn)一圈。而伺服內(nèi)部一個單位對應多少編碼器反饋呢這就要算電子齒輪比了。以編碼器分辨率262144線為例如果一份位置指令對應1個編碼器計數(shù)那么要讓10000份指令轉(zhuǎn)一圈電子齒輪比應該設置為262144:10000簡化后約等于26.2144:1。但這樣不是整數(shù)很多驅(qū)動器的電子齒輪比要求整數(shù)設定沒法直接寫。實際工程中我們會調(diào)整用戶單位比如讓每份指令對應0.001mm絲杠導程10mm電機轉(zhuǎn)一圈走10mm那轉(zhuǎn)一圈需要10000個用戶單位此時電子齒輪比同樣是262144:10000。如果比例不是整數(shù)就換用戶單位比如改成每份指令對應0.01mm轉(zhuǎn)一圈只要1000份指令齒輪比就是262144:1000依然不是整數(shù)。所以很多時候需要配合機械傳動比一起調(diào)這就是另一個話題了??傊涀∫稽c編碼器線數(shù)是固定的你需要調(diào)的是電子齒輪比分母和分子。4. 西門子PLC側(cè)配置從零到能跑4.1 硬件接線RS485 A/B與屏蔽處理RS485接線看著簡單其實是故障高發(fā)區(qū)。CM1241 RS485模塊上的A、B端子對應匯川伺服驅(qū)動器的485通訊端子。接線時用屏蔽雙絞線A接A、B接B然后屏蔽層單端接地一般在PLC側(cè)接地。很多人圖省事不接地線等到現(xiàn)場變頻器一啟動通訊就開始亂碼那時候后悔就晚了。如果鏈路上只有PLC和伺服兩臺設備且CM1241和伺服分布在鏈路兩端那兩端的終端電阻都要啟用。CM1241模塊側(cè)面有終端電阻撥碼開關伺服側(cè)通過H0C-05參數(shù)啟用。如果鏈路中間還有其他設備中間設備的終端電阻必須關閉。4.2 TIA Portal中組態(tài)CM1241 RS485在TIA Portal博途中先添加S7-1200 CPU再添加CM1241 RS485模塊。組態(tài)時可以看到模塊的硬件標識符比如“64”之類的數(shù)字這個標識符在后面的通訊指令里要作為PORT參數(shù)使用。通訊口的波特率、校驗方式等在硬件組態(tài)里可以先隨便設真正生效的是后面程序里MB_COMM_LOAD指令設置的參數(shù)。這一點很多初次接觸的朋友會被繞暈覺得“我硬件組態(tài)里明明設了9600怎么程序里還要設一遍”。記住CM1241的串口參數(shù)最終以MB_COMM_LOAD的形參為準。4.3 初始化指令MB_COMM_LOAD在OB1里調(diào)用MB_COMM_LOAD指令負責初始化串口通訊參數(shù)。核心形參如下形參設置值說明PORTCM1241硬件標識符在PLC變量的系統(tǒng)常量中查找BAUD9600與伺服H0C-01一致PARITY2偶校驗與伺服H0C-02一致DATABITS88個數(shù)據(jù)位STOPBITS11個停止位MB_DB分配一個全局DB用于存放通訊控制數(shù)據(jù)MB_COMM_LOAD的REQ端用首次掃描脈沖觸發(fā)一次即可不需要每個掃描周期都去初始化。DONE和ERROR引腳可以接到M點或DB里方便在線監(jiān)控。4.4 主站讀寫指令MB_MASTER初始化完成后用MB_MASTER進行單次讀寫。MB_MASTER是邊沿觸發(fā)的每次REQ從0變1時發(fā)送一次請求。核心形參如下形參說明REQ上升沿觸發(fā)通訊請求RW0表示讀1表示寫ADDR從站地址功能碼起始地址組合值DATA_PTR指向存儲數(shù)據(jù)區(qū)的指針LEN數(shù)據(jù)長度讀寫字的個數(shù)重點是ADDR的拼接。S7-1200的MB_MASTER要求把從站地址、功能碼、起始地址打包成一個雙字。比如讀1號從站、功能碼03、起始地址0x0B01ADDR就等于16#01030B01其中01是從站地址03是功能碼0B01是寄存器地址。如果是寫控制字功能碼換成06ADDR就是16#01060B00寫多個寄存器時功能碼用160x10比如寫目標位置0x0B02ADDR為16#01100B02這個ADDR格式我在現(xiàn)場給不少同事講過大家最容易錯的就是把從站地址和功能碼的位置搞混。一定記住高字節(jié)是從站地址次高字節(jié)是功能碼低兩個字節(jié)是寄存器地址。4.5 點位運動控制的程序邏輯我寫一個最簡單的點位控制流程大家可以直接參考首次掃描調(diào)用MB_COMM_LOAD完成初始化。用MB_MASTER寫控制字0x0B00值為1使能伺服。延時一段時間確認狀態(tài)字0x0B01的bit0為1表示伺服已使能。用MB_MASTER功能碼0x10寫目標位置寄存器0x0B02連續(xù)寫兩個字數(shù)據(jù)先放高字再加低字。再次用MB_MASTER功能碼06寫控制字值為3觸發(fā)運行。周期讀取狀態(tài)字和實際位置判斷運動是否完成。LEN參數(shù)注意讀寫單個寄存器16位數(shù)據(jù)時LEN1讀寫32位數(shù)據(jù)比如目標位置時LEN2。DATA_PTR指向的數(shù)據(jù)區(qū)如果是32位數(shù)據(jù)需要保證兩個字連續(xù)存放。我在實際項目中會把每次MB_MASTER的ERROR引腳接到一個故障DB一旦狀態(tài)字不是0就把狀態(tài)值記錄下來。這樣即使伺服或者通訊出問題也能快速定位是哪個請求失敗。5. 常見問題與排查技巧實錄5.1 通訊超時故障速查表調(diào)試中通訊超時是最常見的問題我把這些年踩過的坑整理成一張表按出現(xiàn)頻率排序?,F(xiàn)象可能原因排查方法主站報16#8180從站無響應伺服地址、波特率、數(shù)據(jù)格式不一致用串口調(diào)試助手直接發(fā)幀測試伺服是否回復主站報16#8180從站無響應RS485 A/B接反對調(diào)A/B線主站報16#8180從站無響應伺服未上電或通訊參數(shù)修改后未重啟斷電重啟驅(qū)動器偶發(fā)超時缺終端電阻、線纜過長、屏蔽層未接地檢查鏈路終端電阻和接地偶發(fā)超時波特率過高導致抗干擾能力下降降到9600試一下通訊正常但數(shù)據(jù)錯亂校驗位、停止位設置不一致PLC和伺服統(tǒng)一為8E1或8N1伺服能通訊但不動作控制模式或指令來源未設置為Modbus檢查H02組控制模式和指令來源5.2 西門子16#8180錯誤代碼詳解16#8180這個錯誤在S7-1200 Modbus-RTU通訊里最常見。西門子官方文檔的解釋是“從站無響應”或“請求超時”。說白了MB_MASTER把請求幀發(fā)出去但在設定的超時時間內(nèi)沒收到從站回復于是報這個錯。排查思路很簡單先把PLC放在一邊用USB轉(zhuǎn)RS485和串口調(diào)試助手手動發(fā)一幀讀狀態(tài)字的報文。如果伺服也不回復問題一定出在伺服側(cè)或接線側(cè)。如果串口助手能收到回復那問題就回到PLC側(cè)——重點查MB_COMM_LOAD的參數(shù)是否和伺服一致ADDR的地址拼接是否正確以及RS485模塊接線。這里還有個容易被忽略的點MB_MASTER的LEN參數(shù)如果設錯也可能導致通訊失敗。比如寫目標位置時LEN設為1而實際需要2個字PLC只發(fā)了一個字伺服端解析就會異常導致不回復或回異常碼。5.3 數(shù)據(jù)字節(jié)序與單位換算問題數(shù)據(jù)錯亂是另一個高頻問題。Modbus協(xié)議規(guī)定多字節(jié)數(shù)據(jù)大端傳輸也就是高字節(jié)在前。但伺服驅(qū)動器的實際表現(xiàn)偶爾會和手冊有出入我的建議是寫一個固定值去驗證。比如把目標位置寄存器寫成0x0001C350十進制115536然后用伺服面板或調(diào)試軟件看實際位置值。如果顯示115536說明字序正確如果顯示的是其他值大概率是高低字顛倒調(diào)整一下PLC里數(shù)據(jù)的存放順序即可。還有個經(jīng)驗PLC的DATA_PTR如果指向的是Byte數(shù)組或Word數(shù)組要注意數(shù)據(jù)對齊。S7-1200里指針訪問的數(shù)據(jù)區(qū)最好用位存儲器M區(qū)或者DB的絕對地址避免優(yōu)化訪問帶來的麻煩。5.4 實測下來的幾條獨家心得最后分享幾條現(xiàn)場總結(jié)出來的經(jīng)驗都是常規(guī)手冊里不會寫的內(nèi)容。第一調(diào)試時先用串口助手把伺服通訊打通再動PLC程序。這樣做的好處是能把問題分成“伺服側(cè)”和“PLC側(cè)”兩段每段單獨驗證效率最高。我有一次直接上PLC折騰了兩小時沒搞定結(jié)果用串口助手十分鐘就發(fā)現(xiàn)是CM1241模塊的DB數(shù)據(jù)區(qū)地址寫錯了。第二使能之前一定要確認狀態(tài)字的反饋。很多伺服必須先看到使能位反饋有效才會響應運行指令。PLC里別省那幾個掃描周期寫完控制字加一個延時或者輪詢狀態(tài)字確認到位后再發(fā)下一幀穩(wěn)定性會好很多。第三參數(shù)修改后記得保存并斷電重啟。我見過不少現(xiàn)場參數(shù)在InoDriverShop里改了也保存了但驅(qū)動器沒重啟導致新參數(shù)沒生效。通訊類參數(shù)尤其敏感不重啟很容易出現(xiàn)“改了半天沒變化”的怪象。第四通訊超時時間不要設太短。MB_MASTER的超時設置如果太小在惡劣電磁環(huán)境下容易誤報但也不要太長否則故障響應太慢。我一般設置在100-300ms之間兼顧穩(wěn)定性和實時性。最后分享一點個人體會我做設備調(diào)試這些年越來越覺得通訊方案不是越高級越好。Modbus-RTU雖然“老”但在這種小規(guī)模點位控制場景里穩(wěn)定、直觀、好排查反而是最省心的選擇。匯川伺服加西門子PLC的組合在市場上保有量巨大兩個設備之間的Modbus-RTU通訊值得每個自動化工程師認真掌握。按照我的習慣每次新項目會先做一張通訊參數(shù)速查卡把伺服H0C組參數(shù)、H0B組關鍵寄存器地址、PLC側(cè)MB_COMM_LOAD和MB_MASTER的配置全部寫在一張紙上。現(xiàn)場調(diào)試時對照這張紙操作基本能一次通過。這篇文章就算是一個公開版的速查卡希望對大家有用。