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

閱讀時間約 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 通訊的技能喔。

avatar-img
14會員
61內容數
WarrenLo's 軟體設計武功祕笈
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Warren Lo的沙龍 的其他內容
物聯網裝置跟電腦一樣處理資料過程仰賴記憶體,不同類型的資料必須放在不同的記憶體空間。RD 會按照功能需求去規劃這些數據儲存空間,就像設計師規劃客廳、廚房、衛浴與臥室等居住空間一樣。各個空間的規劃原則上不會允許重疊,如此才能確保不同資料間不會發生互相覆蓋導致記憶體錯誤發生。
Modbus 是比 Ethernet 更簡單的通訊架構,走的是 Master-Slave 模式。協議規定 Slave 裝置們都不可以主動回應,所以 Slave 們在通訊過程中遇到看不懂的、壞掉的資料封包,能做的處理方式就是直接丟掉,從外面看 Slave 裝置的行為就跟「已讀不回」一樣毫無反應
當 Modbus 通訊模式可以選 RTU 或 ASCII 這兩種傳輸模式,不過因為兩者的運作機制不一樣,所以通訊時只能選擇其中一種來使用且傳輸端與接收端都必須使用相同的傳輸模式,才不會發生數據解讀錯誤變成一堆亂碼、兩邊雞同鴨講的狀況。關於這兩種傳輸模式的差異之處,主要有三點
我們在上一篇文章聊到了測試左移所需的 8 大能力中的前面 4 個,包含學習研究、反應回饋、作戰計畫、追溯管理的能力,這四個能力也是我們平常工作與生活上遇到困難時的解決問題的核心能力,建議還沒看過第一篇的朋友,可以先回第一篇了解一下。那麼接下來我們要就繼續聊聊測試左移的另外四個能力。
當我們有往左邊看並且嘗試為每一個開發階段設置一個檢查站來把關的想法時,就有了思考方向。原則上所有設計階段的驗證都要通過才能進入量產,因此只要中間有卡關,就不能放行進入下一個階段。
Modbus TCP 可視為一種 Modbus 分支,是跑在實體通訊介面 TCP/IP 上的 Modbus 通訊協議,TCP/IP 就是我們熟悉的網路。現代的網路讓我們的電腦、手機與其他可以上網等裝置連上互聯網,每一個網路上的裝置都被分配一個不同的 IP 位址,這是網路上用來識別每一台裝置的機制
物聯網裝置跟電腦一樣處理資料過程仰賴記憶體,不同類型的資料必須放在不同的記憶體空間。RD 會按照功能需求去規劃這些數據儲存空間,就像設計師規劃客廳、廚房、衛浴與臥室等居住空間一樣。各個空間的規劃原則上不會允許重疊,如此才能確保不同資料間不會發生互相覆蓋導致記憶體錯誤發生。
Modbus 是比 Ethernet 更簡單的通訊架構,走的是 Master-Slave 模式。協議規定 Slave 裝置們都不可以主動回應,所以 Slave 們在通訊過程中遇到看不懂的、壞掉的資料封包,能做的處理方式就是直接丟掉,從外面看 Slave 裝置的行為就跟「已讀不回」一樣毫無反應
當 Modbus 通訊模式可以選 RTU 或 ASCII 這兩種傳輸模式,不過因為兩者的運作機制不一樣,所以通訊時只能選擇其中一種來使用且傳輸端與接收端都必須使用相同的傳輸模式,才不會發生數據解讀錯誤變成一堆亂碼、兩邊雞同鴨講的狀況。關於這兩種傳輸模式的差異之處,主要有三點
我們在上一篇文章聊到了測試左移所需的 8 大能力中的前面 4 個,包含學習研究、反應回饋、作戰計畫、追溯管理的能力,這四個能力也是我們平常工作與生活上遇到困難時的解決問題的核心能力,建議還沒看過第一篇的朋友,可以先回第一篇了解一下。那麼接下來我們要就繼續聊聊測試左移的另外四個能力。
當我們有往左邊看並且嘗試為每一個開發階段設置一個檢查站來把關的想法時,就有了思考方向。原則上所有設計階段的驗證都要通過才能進入量產,因此只要中間有卡關,就不能放行進入下一個階段。
Modbus TCP 可視為一種 Modbus 分支,是跑在實體通訊介面 TCP/IP 上的 Modbus 通訊協議,TCP/IP 就是我們熟悉的網路。現代的網路讓我們的電腦、手機與其他可以上網等裝置連上互聯網,每一個網路上的裝置都被分配一個不同的 IP 位址,這是網路上用來識別每一台裝置的機制
你可能也想看
Google News 追蹤
Thumbnail
題目要求計算兩個二進位字串的相加,並以字串的形式輸出。 字串內容只包含'0'或'1'字元。 複雜度分析 時間複雜度為O(m+n),空間複雜度為O(m+n)。
Thumbnail
我們在「【🎓 Python的深度問答集】torchaudio 對部分段落進行音訊解碼」有分享到如何對一包包的封包進行音訊解碼, 但隨著音檔越大, 最終解碼的速度會越來越慢, 而這並非串流的本意, 串流應該就像水管一樣, 收到多少資料就運算多少量, 並不會隨著累積的容量越大而導致效能下降。 但實際
※ 介面是什麼: 介面:人跟電腦互相溝通的管道。 使用者與電腦互相溝通的方式稱為使用者的介面。 ※ 使用者的介面類型: 文字使用者介面:CUI。使用純鍵盤來下指令溝通,對象是伺服器(SERVER)。 圖型使用者介面:GUI。使用圖像去做點擊或拖拉的方式。 ※ 命令列(Command li
Thumbnail
MIT與MIC的差異,其實並非新聞,但只是最近又遇到相同的情況,因此在寫一篇文章說明一下,畢竟筆者覺得無人機規格這件事,應該會無限重複,未來方便解釋;而追根究柢仍然是KV值惹得禍。 事情是這樣的,客戶跟馬達廠訂了一顆KV值900的無人機馬達,實際裝機測試後,發現台製的無人機馬達轉速過高,要求降轉速
Thumbnail
上回說明的手動下指令,傳出訊息。為了節省手動輸入之動作,將欲執行的curl指令內容,事先作成執行檔。當需要傳送訊息時,只要按兩下執行檔,便可立刻傳出訊息至LINE群組內之全員 2. 說明 2.1 因每次要傳送內容不同,將這些會變動的訊息資料,輸入後保存 於bat執行檔內
Thumbnail
我們在 【Python 軍火庫🧨 - websockets】傳送/接收音檔並轉換成numpy(基礎篇) 有聊到要如何透過Websocket來傳送音檔,但上一篇的作法是在Client端就進行音訊的解碼動作,這樣會有一個缺點,假設Client的機器運算效能較差,那麼運算的結果勢必會較慢出現,對於使用者
Boot0 與 Boot1 是搭配使用。兩者都是MCU上的腳位,視情況輸入HIGH or LOW,會有不同功能 Boot0 = LOW 時,直接進入主程式,也就是會直接運行燒入MCU的程式碼。(boot1= 0 or 1都一樣)。 Boot0 = HIGH且Boot1=1,會進入bootload
Thumbnail
仍舊是紀錄一下自己的過程,避免真的又找半天 1.準備 Console線 ( RS-232 公母接頭 ) 2.準備 USB-RS232 轉接線 ( 驅動程式 ) 3.putty ( 下載位置 ) 4.Zyxel ES3500 的帳號密碼 ( 我的預設是admin/1234 )
Thumbnail
ServeMux ServeMux是一個包含映射的結構,映射會將URL映射到對應的伺服器。 DefaultServeMux DefaultServeMux是net/HTTP中預設的多工器,是ServeMux的實例。多工器要根據URL的請求導向到不同的伺服器。DefaultServeMux是
Thumbnail
題目要求計算兩個二進位字串的相加,並以字串的形式輸出。 字串內容只包含'0'或'1'字元。 複雜度分析 時間複雜度為O(m+n),空間複雜度為O(m+n)。
Thumbnail
我們在「【🎓 Python的深度問答集】torchaudio 對部分段落進行音訊解碼」有分享到如何對一包包的封包進行音訊解碼, 但隨著音檔越大, 最終解碼的速度會越來越慢, 而這並非串流的本意, 串流應該就像水管一樣, 收到多少資料就運算多少量, 並不會隨著累積的容量越大而導致效能下降。 但實際
※ 介面是什麼: 介面:人跟電腦互相溝通的管道。 使用者與電腦互相溝通的方式稱為使用者的介面。 ※ 使用者的介面類型: 文字使用者介面:CUI。使用純鍵盤來下指令溝通,對象是伺服器(SERVER)。 圖型使用者介面:GUI。使用圖像去做點擊或拖拉的方式。 ※ 命令列(Command li
Thumbnail
MIT與MIC的差異,其實並非新聞,但只是最近又遇到相同的情況,因此在寫一篇文章說明一下,畢竟筆者覺得無人機規格這件事,應該會無限重複,未來方便解釋;而追根究柢仍然是KV值惹得禍。 事情是這樣的,客戶跟馬達廠訂了一顆KV值900的無人機馬達,實際裝機測試後,發現台製的無人機馬達轉速過高,要求降轉速
Thumbnail
上回說明的手動下指令,傳出訊息。為了節省手動輸入之動作,將欲執行的curl指令內容,事先作成執行檔。當需要傳送訊息時,只要按兩下執行檔,便可立刻傳出訊息至LINE群組內之全員 2. 說明 2.1 因每次要傳送內容不同,將這些會變動的訊息資料,輸入後保存 於bat執行檔內
Thumbnail
我們在 【Python 軍火庫🧨 - websockets】傳送/接收音檔並轉換成numpy(基礎篇) 有聊到要如何透過Websocket來傳送音檔,但上一篇的作法是在Client端就進行音訊的解碼動作,這樣會有一個缺點,假設Client的機器運算效能較差,那麼運算的結果勢必會較慢出現,對於使用者
Boot0 與 Boot1 是搭配使用。兩者都是MCU上的腳位,視情況輸入HIGH or LOW,會有不同功能 Boot0 = LOW 時,直接進入主程式,也就是會直接運行燒入MCU的程式碼。(boot1= 0 or 1都一樣)。 Boot0 = HIGH且Boot1=1,會進入bootload
Thumbnail
仍舊是紀錄一下自己的過程,避免真的又找半天 1.準備 Console線 ( RS-232 公母接頭 ) 2.準備 USB-RS232 轉接線 ( 驅動程式 ) 3.putty ( 下載位置 ) 4.Zyxel ES3500 的帳號密碼 ( 我的預設是admin/1234 )
Thumbnail
ServeMux ServeMux是一個包含映射的結構,映射會將URL映射到對應的伺服器。 DefaultServeMux DefaultServeMux是net/HTTP中預設的多工器,是ServeMux的實例。多工器要根據URL的請求導向到不同的伺服器。DefaultServeMux是