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

閱讀時間約 7 分鐘
Modbus Protocol

Modbus Protocol

上次我們聊到了在物聯網裡扮演重要 Modbus通訊協議,一個簡單開放的工業通訊協定,後來發現還有些需要補充的細節,於是決定來一下物聯網 Modbus 補完計畫。這次的內容會包含四個部分:

  1. RTU 與 ASCII 傳輸模式的差異
  2. Modbus TCP 的確認機制
  3. 協議裡 4 個 Data Model 的用途
  4. 一些常見的為什麼問題整理

不囉唆,直接上菜!

RTU 與 ASCII 傳輸模式的差異

當 Modbus 協議走在 Serial (RS232/485) 上的時候,通訊模式可以選 RTU 或 ASCII 這兩種傳輸模式,不過因為兩者的運作機制不一樣,所以通訊時只能選擇其中一種來使用且傳輸端與接收端都必須使用相同的傳輸模式,才不會發生數據解讀錯誤變成一堆亂碼、兩邊雞同鴨講的狀況。關於這兩種傳輸模式的差異之處,主要有三點:

  1. ADU 編碼的差異
  2. 訊號開始與結束的方式
  3. 資料檢查碼的類型

ADU 編碼的差異

前一篇的文章我們有提到 ADU,還記得郵局跟宅急便收送包裹的例子嗎?要寄送的物品,就得根據郵局或宅急便的規定包裝。所以 Modbus 的資料得按照 RTU 或者 ASCII 模式的要求包裝成所屬版本的 ADU 後才能進行傳輸。當我們選用 RTU 傳輸模式的時候,ADU 就會以二進位方式進行編碼,ADU 會被編成是一連串的 0101 的形式。我們先假設要傳送的裝置位址編號是數字 1,經過二進位編碼後就變成 0000 0001 。因此 RTU 傳輸模式也被稱為二進位模式。不過為了讓我們可以方便閱讀,還是會習慣把二進位的 0000 0001 轉換成十六進位的數字 0x01 來表示。

ASCII 編碼是字符編碼模式以十六進位數字表示法為基礎。一開始先把二進位的數據轉成十六進位數字表示,再把轉換出來的十六進位數字「看成」文字符號再拿出 ASCII 對照表找出字符對應的數據編碼。繼續沿用前面的通訊位置 1 為例,第一步就是先把二進位表示的 0000 0001 轉成的十六進位的數字 0x01,接著把 01 看成兩個獨立文字符號 ‘0’ 跟 ‘1’ (用單引號刮起來代表文字),經過查 ASCII 對照表得知文字符號 ‘0’ 的編碼是 0x30,’1’ 的編號是 0x31。對 ASCII 傳輸模式來說,原本要傳輸的數字 1 經過 ASCII 編碼後就變成要傳輸 0x30 0x31 了。

RTU 編碼用一個 Byte ,ASCII 就要用兩個 Bytes

你一定也發現了,一樣的資料使用 ASCII 編碼會比使用 RTU 的編碼「胖」一倍,也就是原本在 RTU 傳輸模式只要 1 個 byte (8 個 bits, 8 個 0101 的組合) 就可以處理的資料,改用 ASCII 傳輸模式就得花 2 個 byte (16bits, 16 個 0101 的組合) 來處理。ASCII 傳輸模式有比較容易閱讀的好處,考慮 Modbus Serial 每次資料傳輸封包有最大長度 256 bytes 的上限,變胖的 ASCII 傳輸模式一次能處理的資料內容自然就少了一半,數據傳輸效率自然遜於 RTU 傳輸模式了。

Modbus ADU Format (RTU)

Modbus ADU Format (RTU)

訊號開始與結束的方式

打包好的 ADU 也叫做 Frame(訊號框)是傳輸資料的基礎單位。問題就在於是接收端是如何判斷何時要開始收資料,資料何時傳送完成通訊結束?Modbus 通訊有規定前每次 Frame 傳出去前都要先打招呼,要加一個起始訊號在 ADU 前面出來給對方確認,讓接收端看到起始訊號後開始接收資料,等到所有資料都送出去後,還要在 Frame 的尾端打一個結束訊號跟接收端說再見,接收端要有收到開始跟結束訊號才算完成這次的資料傳輸作業。

RTU 傳輸的起始跟結束是用時間 >=3.5 Chars 來決定,ASCII 傳輸模式的起始跟結束是用字符 0x3A 跟 0x0D 0x0A 來決定

當我們選用 RTU 傳輸模式的時候,要打給對方確認的起始跟結束訊號都是用時間長短來決定,標準是 3.5 chars,也就是數據跑過去 3.5 bytes 所需要的時間。Serial 在待命的時候資料傳輸線路電壓都是高電位 (0),所以只要傳輸線路上出現了一個低電位訊號 (1) 且持續時間超過 3.5 chars 就會被認定通訊開始要開始接收數據,等確認出現 3.5 chars 的時間的高電位訊號的時候,就確認這次數據傳輸已經結束。至於 3.5 char(s) 是多少時間,跟我們設定的通訊參數 baudrate 有關,我們先假設 3.5 chars = 1ms ,只要偵測到有一個低電位訊號且維持了 1ms 的時候,接收端就開始收資料了直到偵測到 1ms 的結束訊號為止,關於通訊參數該怎麼設定、3.5 chars 需要多少時間是怎麼算出來的,這部分等我們後續講到 Serial 的時候再補充吧。

Modbus Frame - RTU

Modbus Frame - RTU

ASCII 模式是使用開始字符跟結束字符來表達 Frame 的頭跟尾。當 ASCII 模式要開始傳輸資料的時候,會先打出一個 0x3A 的訊號,0x3A 查 ASCII 表就是 ‘:’ 冒號,所以看到冒號後就代表後面來的是資料了,等接收端偵測到 0x0D 0x0A 的時候就表示資料已經傳送完畢了。對人來說使用 ASCII 要判斷終點跟起點是相對容易的,因為只要看到冒號就代表後面有資料,看到 0D 0A 就代表資料結束。不過 ASCII 傳輸模式的限制也很明顯,也就是你的原始資料內絕對不可以有 0D 0A,否則就會發生接收端誤以為已經傳輸完畢結果數據接收不完全的錯誤。

Modbus Frame - ASCII

Modbus Frame - ASCII

檢查碼的類型

資料傳輸的時候是走在電路上,傳輸過程中會有機會被環境電磁波干擾導致要傳給對方的資料會出錯,那麼接收方要如何確認收到的資料對不對呢?這時候就要靠 ADU 的檢查碼了。接收端會把數據需要的檢查碼計算一遍,跟傳送過來的檢查碼做比對,只要兩者檢查碼相同,就代表數據內容正確。

RTU 傳輸模式的 ADU 用的檢查碼 CRC,ASCII 傳輸模式用的演算法是 LRC

不管是哪一種算法都是為了確保收到的數據是正確的。也許你可能會好奇 CRC 或 LRC 究竟是如何計算出來的呢?關於 CRC 或 LRC 的演算法,網路上已經有一堆資料,這裡就不再贅述了。當然我也不建議你去真的去跑去查找 LRC, CRC 的細部資訊,因為根據我多年的觀察,真正有能力看懂 CRC 演算又能夠自己實作的軟體工程師真的是少之又少(也沒必要)。對應用端的軟體開發者而言,知道是什麼該怎麼去呼叫對應的 CRC 或 LRC 的函數絕對都比自己鑽研大半天搞一個自己的算法來得有效率。

能自己寫出 CRC 或 LRC 演算法的人出來固然厲害,但是能正確理解知識且應用好的人才是真正的專業!

小結論

以上就是這次 Modbus 補完計畫第一趴的內容,先把 Modbus RTU 跟 ASCII 兩種傳輸模式的三個主要的差異點分享給大家。了解跟應用才是最重要的部分,通訊本來就跟我們講話一樣,都是為了達到溝通的目的,不用特別去糾結文法或艱澀字的問題,用最簡單、最有效率方式把自己的意思清楚表達給對方就好了。這次先補到這裡,我們就下一篇再見了。

avatar-img
14會員
61內容數
WarrenLo's 軟體設計武功祕笈
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Warren Lo的沙龍 的其他內容
我們在上一篇文章聊到了測試左移所需的 8 大能力中的前面 4 個,包含學習研究、反應回饋、作戰計畫、追溯管理的能力,這四個能力也是我們平常工作與生活上遇到困難時的解決問題的核心能力,建議還沒看過第一篇的朋友,可以先回第一篇了解一下。那麼接下來我們要就繼續聊聊測試左移的另外四個能力。
當我們有往左邊看並且嘗試為每一個開發階段設置一個檢查站來把關的想法時,就有了思考方向。原則上所有設計階段的驗證都要通過才能進入量產,因此只要中間有卡關,就不能放行進入下一個階段。
Modbus TCP 可視為一種 Modbus 分支,是跑在實體通訊介面 TCP/IP 上的 Modbus 通訊協議,TCP/IP 就是我們熟悉的網路。現代的網路讓我們的電腦、手機與其他可以上網等裝置連上互聯網,每一個網路上的裝置都被分配一個不同的 IP 位址,這是網路上用來識別每一台裝置的機制
以前當 RD 在開發系統產品的時候需要控制很多硬體設備,韌體工程師有說硬體控制可以走自定義的通訊格式,需要搭配一張指令對照表,按表組成命令下給終端設備,設備們接收到正確的指令後才會做出正確的回應(對於不認識的指令,設備會只會已讀不回!)
Modbus 是一種定義在通訊應用層的協議,會根據資料跑在不同的實體介面上而有不同的「版本」,例如:應用在 RS232/RS485 串列埠介面的就是 Modbus RTU/ASCII,應用在 TCP/IP 的就是 Modbus TCP 也 SCADA 的主要應用協議。
每個人都在心裡有了自己對智慧工廠的想像(陰影?),不少人也開始結合自己的經驗得出自己的見解,直接把智慧工廠直接跟某個特定主題直接劃上等號,這種化繁為簡的總結能力對人類學習很有用處,人類是不斷的學習總結來擴展知識能力。但是使用不當或過度簡化也會走歪掉形成「偏見」,而強烈固執的偏見就會升級為「迷思」
我們在上一篇文章聊到了測試左移所需的 8 大能力中的前面 4 個,包含學習研究、反應回饋、作戰計畫、追溯管理的能力,這四個能力也是我們平常工作與生活上遇到困難時的解決問題的核心能力,建議還沒看過第一篇的朋友,可以先回第一篇了解一下。那麼接下來我們要就繼續聊聊測試左移的另外四個能力。
當我們有往左邊看並且嘗試為每一個開發階段設置一個檢查站來把關的想法時,就有了思考方向。原則上所有設計階段的驗證都要通過才能進入量產,因此只要中間有卡關,就不能放行進入下一個階段。
Modbus TCP 可視為一種 Modbus 分支,是跑在實體通訊介面 TCP/IP 上的 Modbus 通訊協議,TCP/IP 就是我們熟悉的網路。現代的網路讓我們的電腦、手機與其他可以上網等裝置連上互聯網,每一個網路上的裝置都被分配一個不同的 IP 位址,這是網路上用來識別每一台裝置的機制
以前當 RD 在開發系統產品的時候需要控制很多硬體設備,韌體工程師有說硬體控制可以走自定義的通訊格式,需要搭配一張指令對照表,按表組成命令下給終端設備,設備們接收到正確的指令後才會做出正確的回應(對於不認識的指令,設備會只會已讀不回!)
Modbus 是一種定義在通訊應用層的協議,會根據資料跑在不同的實體介面上而有不同的「版本」,例如:應用在 RS232/RS485 串列埠介面的就是 Modbus RTU/ASCII,應用在 TCP/IP 的就是 Modbus TCP 也 SCADA 的主要應用協議。
每個人都在心裡有了自己對智慧工廠的想像(陰影?),不少人也開始結合自己的經驗得出自己的見解,直接把智慧工廠直接跟某個特定主題直接劃上等號,這種化繁為簡的總結能力對人類學習很有用處,人類是不斷的學習總結來擴展知識能力。但是使用不當或過度簡化也會走歪掉形成「偏見」,而強烈固執的偏見就會升級為「迷思」
你可能也想看
Google News 追蹤
Thumbnail
這篇文章分享如何操作檯達CTA計時器,使用MODBUS RTU通訊模式進行讀取與寫入資料的完整過程。從硬體連接、通訊設定到ISPSoft的軟體配置,詳細介紹每一步驟,並提供實際的程式碼範例。適合希望瞭解CTA通訊設定以及MODBUS應用的技術人員或工程師。
Thumbnail
今天要來介紹的是Python中資料型別的函數, 這幾天學習的素材是Youtube上“程式柴大大的Python 6 小時初學者課程”,一步一步帶著大家操作並解,學習中也別忘了要多多練習,練習的部分我是把我學到的東西請Chatgpt幫我出類似的題型並讓我練習。 以下我先寫出一個簡單的code,再加以
Thumbnail
題目要求計算兩個二進位字串的相加,並以字串的形式輸出。 字串內容只包含'0'或'1'字元。 複雜度分析 時間複雜度為O(m+n),空間複雜度為O(m+n)。
Thumbnail
數位IC裡我們關注的都是0或1, 大家都知道電腦是0101在做二進位的運算, 在晶片裡又是怎麼做到的? 實際上我們在設計晶片時,會給他一個VDD跟GND, VDD-GND給的是預期的Driving volatge, 像是5V或9V 以5V為例 0或1物理上就是目前的電壓靠近0V或5
Thumbnail
本篇文章講解了字符編碼的基礎知識,包括ASCII, Unicode 和 UTF-8的誕生背景、解決的問題以及轉換方式。瞭解這些知識有助於解決在讀檔案時用錯誤的編碼方式轉換就會出現亂碼等問題。文章內容涉及電腦技術中的字符編碼相關歷史緣由,可幫助讀者解決相關疑問。
Thumbnail
** 3C機構設計爸版權所有 ** USB 是我們每天生活上所使用的device中最常有的I/O port,舉凡TV、cash machine、PC、Server、phone、……等等,數不完的device都有USB 接口,當然也存在著不同種類的USB接口,在下次的分享中,3C機構設計爸會做一個U
Thumbnail
在實務上,條碼槍傳送的資訊可能包含不可見字符或控制字符。這可能是因為條碼槍在傳送條碼數據時使用了一些特殊字符,這些字符在可見字符集合之外,例如 \x06 就是 ASCII 中的 "ACK" 控制字符。 本文將探討,如何查詢及處理這些特殊字符。
使用ADC時必須注意 MCU上會有Vref腳位,這兩個腳位必須接上VDD及GND。 這兩個腳位是專門給ADC使用的,ADC在轉換時會需要參考電壓來轉換成digital。公式如下 ​digital = (Vin / Vref) * 2^12 digital:是電腦讀取到的數值。 Vin:輸
Boot0 與 Boot1 是搭配使用。兩者都是MCU上的腳位,視情況輸入HIGH or LOW,會有不同功能 Boot0 = LOW 時,直接進入主程式,也就是會直接運行燒入MCU的程式碼。(boot1= 0 or 1都一樣)。 Boot0 = HIGH且Boot1=1,會進入bootload
Thumbnail
這篇文章分享如何操作檯達CTA計時器,使用MODBUS RTU通訊模式進行讀取與寫入資料的完整過程。從硬體連接、通訊設定到ISPSoft的軟體配置,詳細介紹每一步驟,並提供實際的程式碼範例。適合希望瞭解CTA通訊設定以及MODBUS應用的技術人員或工程師。
Thumbnail
今天要來介紹的是Python中資料型別的函數, 這幾天學習的素材是Youtube上“程式柴大大的Python 6 小時初學者課程”,一步一步帶著大家操作並解,學習中也別忘了要多多練習,練習的部分我是把我學到的東西請Chatgpt幫我出類似的題型並讓我練習。 以下我先寫出一個簡單的code,再加以
Thumbnail
題目要求計算兩個二進位字串的相加,並以字串的形式輸出。 字串內容只包含'0'或'1'字元。 複雜度分析 時間複雜度為O(m+n),空間複雜度為O(m+n)。
Thumbnail
數位IC裡我們關注的都是0或1, 大家都知道電腦是0101在做二進位的運算, 在晶片裡又是怎麼做到的? 實際上我們在設計晶片時,會給他一個VDD跟GND, VDD-GND給的是預期的Driving volatge, 像是5V或9V 以5V為例 0或1物理上就是目前的電壓靠近0V或5
Thumbnail
本篇文章講解了字符編碼的基礎知識,包括ASCII, Unicode 和 UTF-8的誕生背景、解決的問題以及轉換方式。瞭解這些知識有助於解決在讀檔案時用錯誤的編碼方式轉換就會出現亂碼等問題。文章內容涉及電腦技術中的字符編碼相關歷史緣由,可幫助讀者解決相關疑問。
Thumbnail
** 3C機構設計爸版權所有 ** USB 是我們每天生活上所使用的device中最常有的I/O port,舉凡TV、cash machine、PC、Server、phone、……等等,數不完的device都有USB 接口,當然也存在著不同種類的USB接口,在下次的分享中,3C機構設計爸會做一個U
Thumbnail
在實務上,條碼槍傳送的資訊可能包含不可見字符或控制字符。這可能是因為條碼槍在傳送條碼數據時使用了一些特殊字符,這些字符在可見字符集合之外,例如 \x06 就是 ASCII 中的 "ACK" 控制字符。 本文將探討,如何查詢及處理這些特殊字符。
使用ADC時必須注意 MCU上會有Vref腳位,這兩個腳位必須接上VDD及GND。 這兩個腳位是專門給ADC使用的,ADC在轉換時會需要參考電壓來轉換成digital。公式如下 ​digital = (Vin / Vref) * 2^12 digital:是電腦讀取到的數值。 Vin:輸
Boot0 與 Boot1 是搭配使用。兩者都是MCU上的腳位,視情況輸入HIGH or LOW,會有不同功能 Boot0 = LOW 時,直接進入主程式,也就是會直接運行燒入MCU的程式碼。(boot1= 0 or 1都一樣)。 Boot0 = HIGH且Boot1=1,會進入bootload