iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
Modern Web

你渴望連結嗎?將 Web 與硬體連上線吧!系列 第 5

D04 - 從零開始的 Firmata 通訊

電子助教:「(大包小包)窩準備好了 (≖‿ゝ≖)✧」

鱈魚:「東西放下,我們沒有要轉生。」

電子助教:「說好的香香妹子們呢?(́⊙◞౪◟⊙‵)」

鱈魚:「別瞎掰好嗎」

電子助教:(每天眼前只有一隻肥宅魚,我的電生怎麼這麼歹命 ( ´•̥̥̥ ω •̥̥̥` ))

鱈魚:「你心裡是不是在想甚麼很失禮的事情... (´ー`)」


接下來我們將慢慢研讀 Firmata Protocol,並自行設計 Firmata 收發套件。

首先打開 Firmata Protocol 的 Github,並點擊「protocol.md」文件。

D04 - Firmata Github.png

此文件便是 Firmata 的基礎內容,詳細說明 Firmata 之 MIDI 格式、數位類比資料響應等等。

Untitled

我們不要從頭開始啃(以免大家都跑光 ...(ˊДˋ;)),循序漸進地一步一步來。

讓我們回到 D03 串列埠監控視窗那一串奇怪的文字開始吧。

Untitled

串列通訊傳輸資料時,都是一個 byte 一個 byte 進行傳輸,一個 byte 表示 0~255 的數值,意思是不管甚麼文字或符號,都會被轉換成 0~255 之間的數值。

數值與字元之前的對照關係就是「ASCII」,每個符號都有自己對應的數值,如下表(圖片只包含部分內容):

Untitled

圖片來源:wiki - ASCII

中文或其他語系文字則會使用多個 byte 進行表示,詳細資料請見連結

意思是「hi」這段文字透過串列通訊傳輸時會是「104 105」,而 Arduino IDE 的串列埠監控視窗會自動將數值轉換成字元,所以 Firmata 的內容看起來會是一堆亂碼,因為他並不是傳文字字元。

不過我們希望可以直接觀察原始數值內容,所以這裡要請出另一個工具 — 「AccessPort」。

(其實不下載 AccessPort 也沒關係,,因為只用這一次 ( ´∀` ))

下載、解壓縮完成後,打開程式,會跑出以下畫面:

如果長的不一樣,請確認紅框選項為「Terminal」

D04 - AccessPort.png

接著按下橘框的「齒輪」按鈕,打開設定,並檢查紅框內的設定是否相符。

「串口」請選擇 Arduino Uno 對應的 COM

D04 - AccessPort 設定 (1).png

設定完成後按下確定,AccessPort 會自動開啟 Port,這個時候應該會跑出一串數值,如下圖。

如果是一串亂碼,請確認紅框內的 Hex 選項被啟用。

D04 - Firmata 啟動訊息.png

讓我們來好好分析這串數值。

   第一個數值
 ⇙
F9 02 05 F0 79 02 05 53 00 74 00 61 00 6E 00 64 00 61 00 72 00 64 00 46 00 69 00 72 00 6D 00 61 00 74 00 61 00 50 00 6C 00 75 00 73 00 2E 00 69 00 6E 00 6F 00 F7

protocol.md 中搜尋第一個數值「F9」,就會在「Message Types」找到他。

Untitled

可以發現其實前 3 個 Byte 是用來描述協定版本,也就是說:

F9 02 05

意思為:

  • F9:告知回應的數值是 protocol version
  • 02:表示 major version
  • 05:表示 minor version

所以我們可以得出此韌體協定版本為 2.5 版。

接著讓我們去除已知意義的數值,接下來的第一個數值是「F0」

F9 02 05 // 協定版本

   接下來的第一個數值
 ⇙
F0 79 02 05 53 00 74 00 61 00 6E 00 64 00 61 00 72 00 64 00 46 00 69 00 72 00 6D 00 61 00 74 00 61 00 50 00 6C 00 75 00 73 00 2E 00 69 00 6E 00 6F 00 F7

一樣會在「Message Types」找到「F0」。

Untitled

會發現「F0」為 sysex 的起始值,所以甚麼是「sysex」呢?讓我們移駕到「Sysex Message Format」的部分。

Untitled

System exclusive (sysex) messages are used to define sets of core and optional firmata features. Core features are related to functionality such as digital and analog I/O, querying information about the state and capabilities of the microcontroller board and the firmware running on the board. All core features are documented in this protocol.md file. Optional features extend the hardware capabilities beyond basic digital I/O and analog I/O and also provide APIs to interface with general and specific components and system services. Optional features are individually documented in separate markdown files.

從以上文檔的說明中,我們可以知道 sysex 表示一種用來描述並定義核心功能與各種 I/O 的訊息格式。

所以我們可以在 SysEx commands 中找到第二個數值「79」的蹤影:

Untitled

並在「Query Firmware Name and Version」中找到詳細的回應內容說明:

Untitled

大家會注意到裡面出現了 LSB、MSB,我們先解釋一下這是甚麼,他們分別為:

  • MSB:最高有效位元組(Most Significant Byte)
  • LSB:最低有效位組(Least Significant Byte)

接著探討一個問題。
分屍位元01
分屍位元02
分屍位元03

將超過 1 bye 的數值拆分成多個 byte 傳輸,接收時再將數值組裝回來即可,具體過程如下:

D04 - 拆分位元.png

接下來根據以下說明:

0  START_SYSEX       (0xF0)
1  queryFirmware     (0x79)
2  major version     (0-127)
3  minor version     (0-127)
4  first char of firmware name (LSB)
5  first char of firmware name (MSB)
6  second char of firmware name (LSB)
7  second char of firmware name (MSB)
... for as many bytes as it needs
N  END_SYSEX         (0xF7)

我們可以得知:

  • F0 為 sysex 起始值
  • 79 為查詢韌體命令
  • 接續第 3、4 Byte 都是版本號(剛好對應剛剛「F0」的內容)
  • 剩下的內容每 2 Byte 為一組(LSB、MSB),用來表示 firmware name

所以我們將剛才的數值分類、整理一下,得:

F9 02 05 // 協定版本

F0       // 起始值
79       // 查詢韌體命令
02       // major version
05       // minor version

53 00    // firmware name
74 00 
61 00 
6E 00 
64 00 
61 00 
72 00 
64 00 
46 00 
69 00 
72 00 
6D 00 
61 00 
74 00 
61 00 
50 00 
6C 00 
75 00 
73 00 
2E 00 
69 00 
6E 00 
6F 00 

F7       // 結束值

firmware name 的部分,因為 MSB 都是 00,所以數值組合後也等於 LSB,我們接著比對 ASCII 表(注意數值為 16 進位),就可以得出數值表示的字元,得:

F9 02 05 // 協定版本

F0       // 起始值
79       // 查詢韌體命令
02       // major version
05       // minor version

53 00    // 53 = S
74 00    // 74 = t
61 00    // 61 = a
6E 00    // 6E = n
64 00    // 64 = d
61 00    // 61 = a
72 00    // 72 = r
64 00    // 64 = d
46 00    // 46 = F
69 00    // 69 = i
72 00    // 72 = r
6D 00    // 6D = m
61 00    // 61 = a
74 00    // 74 = t
61 00    // 61 = a
50 00    // 50 = P
6C 00    // 6C = l
75 00    // 75 = u
73 00    // 73 = s
2E 00    // 2E = .
69 00    // 69 = i
6E 00    // 6E = n
6F 00    // 6F = e

F7       // 結束值

firmware name 的部分合併之後就會得到「StandardFirmataPlus.ino」。

最後總結一下,我們知道原本的那一大串數值其實有兩個部分:

// 第一部分
F9 02 05 

// 第二部分
F0 79 02 05 53 00 74 00 61 00 6E 00 64 00 61 00 72 00 64 00 46 00 69 00 72 00 6D 00 61 00 74 00 61 00 50 00 6C 00 75 00 73 00 2E 00 69 00 6E 00 6F 00 F7

第一部分:

  • 版本號:2.5

第二部分:

  • 版本號:2.5
  • 韌體名稱:StandardFirmataPlus.ino

以上我們成功邁出看懂 Firmata 的第一步了!

總結

  • 讀懂 Firmata 開機訊息
  • 成功取得「版本號」與「韌體名稱」

上一篇
D03 - Hello Firmata
下一篇
D05 - 準備前端環境
系列文
你渴望連結嗎?將 Web 與硬體連上線吧!33

尚未有邦友留言

立即登入留言