帶你認識物聯網 Modbus 通訊協議 -- 補完計畫(四)

2023/10/10閱讀時間約 7 分鐘
Modbus Protocol

Modbus Protocol

經過了前三次的努力,我們終於來到這次物聯網 Modbus 補完計畫的最後一節了,這次內容是問答的形式,輕鬆聊一下、總結學習過程中幾個有趣的問題吧。

為什麼 Master 廣播給所有 slave ,slave 們卻無人回應?

我想這問題的答案是,Slave 們對於 Master 的廣播不回應可謂是心有餘力不足。主要有兩個原因,一方面受限於協議規定 Master-Slave 架構,Slave 只要不是 Master 單獨問話就得「惦惦無聲」,所以 Master 廣播時或 Slave 們收到別人的封包(或是錯誤的)只能選擇忽視。

那麼 Master 想確認 Slave 們有沒有照指令做事怎麼辦?此時確認的工作就又回到 Master 身上,Master 必須再下新的指令給 Slave 進行確認,每個 Slave 都要問一次,這種方式叫做輪詢( Polling by poll);另一方面也是受限於 Serial Modbus 通訊的物理架構,因為所有的裝置都是串接在同一個通訊迴路上(同一條 Bus),單一時間內只能有一組 Master-Slave 互相通訊,更精準的說,只能有 Master 提出 request 或是 Slave 回覆 response,這也是為什麼 RS232/RS485 都被叫做半雙工通訊(全雙工需要兩條 Bus)的原因。

問題來了,如果在一組 Master-Slave 在通訊過程中出現其他的裝置「插嘴」的狀況會怎麼樣?因為迴路只有一條,所以只要在同一個通訊迴路上同時有兩台裝置發出訊號,結果就是兩個資料封包互相對撞雙雙損毀。如果通訊過程中碰撞資料損毀的情況持續發生,導致每個裝置都沒辦法收到正確的訊號,基本上這個通訊迴路也就癱瘓了。

為什麼功能碼(Function code) 長度有 1 個 byte,編號卻只到 127 呢?

Modbus 通訊時需要指定功能碼(Function Code)並且跟資料一起組成 PDU(Protocol Data Unit),功能碼規定的資料長度是 1 個 byte,1 個 byte 可以表示的最大整數是 255。可是官方文件規定的功能碼最大值只有到 127,加上 0 總共是 128 個數,是 2 的 7 次方個,1 個 byte 的長度只用了 7 個 bits!那麼還有 1 個 bit 為什麼不用? 128-255 到哪裡去了呢?其實並不是不用,而是被「挪作他用」了。

你應該還得除了正常的功能碼還有一種特殊的功能碼叫做例外功能碼 (Exception Function Code) 對吧?正常情況下 Master 送出的 request 跟 Slave 回覆的 Response 所帶的功能碼會是一樣的,但是 Slave 也會遇到例外狀況(Exception) 的時候,此時 Slave 就必須把要原本回傳的功能碼升級成例外功能碼再傳給 Master,升級的方式就是把原本的功能碼加上 0x80 變成例外功能碼 。

例外功能碼 = 0x80 + 正常功能碼

舉例來說如果某一次的通訊 Master 送出 0x04 (Read Input Registers),Slave 會回應的例外功能碼就是 0x80 + 0x04 = 0x84,翻譯成十進位就是 132,剛好落在 128-255 之間。我們再換個角度看,0x80 跟 0x04 改用二進位表示法分別是 1000 0000 跟 0000 0100,0x84 就是 1000 0100,注意到了嗎?所謂的例外功能碼就是把長度 1 個 byte 的功能碼的最高位的那個 bit 直接從 0 變成 1 。

為什麼 RTU 傳輸模式效率會比 ASCII 傳輸模式好?

關於 RTU 與 ASCII 兩者的傳輸模式,我們在前面的物聯網 Modbus 補完計畫(一) 的時候有聊到很多細節,如果忘記了可以再回去看看喔。

基本上造成兩者傳輸效率差異的主要原因是底層通訊編碼方式。因為如果資料在 RTU 傳輸模式只要一個 byte 處理,換成 ASCII 傳輸模式就要變成兩個 bytes 來表示。而實體訊號在傳遞的時候是一個 bit 接著一個 bit 往實體線路送,不妨先把資料封包 ADU(Application Data Unit) 想像成多車廂的資料列車,ASCII 傳輸模式會讓原本只需要五個資料貨櫃變十個,資料長度加倍的代表每次的傳輸與處理的時間都變久了。

而 Modbus 協議本身也有限定 ADU 封包大小上限 256 bytes,結果變成原本用 RTU 傳輸模式可以一次送完的資料改用 ASCII 就得分兩次或更多次來傳輸。雖然對最上層應用程式的角度來看,只要最後有把資料封包有收齊就好,仔細想想,數據交換的過程中資料被拆得越多,就需要更多額外的資料包裝與更多時間來處理,速度就變慢效率變差;加上你也已經知道通訊本身很不可靠對吧,所以資料封包拆得越多中間遇到干擾、掉包導致最後組不起來機率會增加,所以對 Modbus 來說,想要有更好的通訊效率還是會盡量選用 RTU 模式才對。

為什麼通訊要有 Timeout 跟 Retry 的機制?

其實物聯網裝置間的通訊行為彷彿跟我們人之間的對話一樣,當我們說話的時候聲音必須透過空氣傳播並且要等待一段時間才能到對方耳朵裡,等對方做出反應後,我們就知道這次的「通訊」已經成功了。

等等,什麼叫做等一段時間?那到底要等多久?機器又不像人有其他方式可以確認對方的反應,例如可以用眼睛觀察對方來判斷斷方反應,難道要讓機器無限的等下去嗎?為了解決通訊要等多久的問題,發送端必須為自己設好一個計時器,資料送出後就開始倒數計時,假設等待時間 100ms 好了,意思是傳送端預期 100ms 後會收到接收端的回覆,所以只要傳送端等待的時間 100 ms 就會被判定 Timeout (等候逾時),認定接收端沒收到資料,必須重新把資料送出。這個不斷重複「傳送資料、等待逾時、傳送資料、… 」的過程就叫做 Retry 機制。

Retry 機制的目的是期望能最大的保障接收端可以正確收到資料。另外,Retry 機制設計上也不是無上限的,如果你發現每次通訊都會打到 Retry 次數上限的話,就一定得進一步做診斷,看看是不是有訊號干擾、通訊線沒接好還是已經斷線了。

小結論

回答完了上述的問題,這次的補完計畫就在這裡正式結束了,我實在感謝有一路關注這個話題到這裡的朋友。

Modbus 作為一個”古老”的通訊技術 (1979 年),不但沒有因為資訊科技的發展被淘汰,反而因為其簡單易用的特性先在局端的工控領域裡先找到了自己的一片天,隨著網路還升級成可靠版本的 Modbus TCP 達成物聯網與智慧工廠等應用目的,現在只要透過區域網路、無線網路甚至是手機通訊網路就能連接,即使裝置遠在地球另一邊的機器也能瞬間掌握設備最新狀況。說不定再過幾年,等智慧家庭技術更普及的時候,說不定咱們家裡的冰箱跟冷氣等各種家電也會點亮 Modbus TCP 通訊的技能喔。

9會員
58內容數
WarrenLo's 軟體設計武功祕笈
留言0
查看全部
發表第一個留言支持創作者!