如何安全地在 Jetson Nano 或 Raspberry Pi 樹莓派上使用 GPIO
簡單一句話:不要在這些中高階(或也可以解釋成昂貴)的平台上應用 GPIO 做電子實驗。當然,電子電路高手例外。
所謂的電子實驗,就是指將這類平台,透過電線方式與周邊模組、電子元件的接腳一一連接。這樣做的風險不小,因為很容易因為短路或電流需求過大等原因,燒壞你心愛的平台又傷害您的荷包。
基本概念
很多 Maker 可能不是科班出身,不過已經能夠玩 Arduino 上手,所以覺得自己動手外接這些模組或元件很簡單啊... 但是可能就是 Arduino 經驗帶來的錯誤習慣,以為 MCU 都很強壯,隨便接、接錯線,重新來過就好,沒什麼大不了!直到把昂貴的新玩具燒壞,才發現事情大條了!
首先,這些平台的核心多半是採用比較先進製程的 SoC (System on Chip),而且他們原本是以 MPU(Micro Procssesor Unit)當作設計目標,目的是用於運算而非控制。所以它們的 CPU 核心與 I/O 都必須是低電壓、低電流設計。因此 I/O 電壓必定是 3.3V 以下,驅動電流也小很多。各代 Raspberry Pi 的 GPIO pin 容許經過電流的上限大概是 16mA,而 Jetson Nano 則是 +/-1mA 或 +/-2mA!可以參考這個討論串:https://forums.developer.nvidia.com/t/gpio-current-limits-on-jetson-nano/72980
相對 Arduino 而言,這幾乎是降維了整整 1 - 2 個 Order 的嚴謹規格!這會有什麼影響?這篇 JetsonHacks 文章 也提供了很好的解釋:以前 Arduino 接 LED 時只要接個限流電阻,在 Jetson Nano 上則需要加上電晶體作為開關才行!所以除了一些諸如 UART、I2C、SPI 等簡單通訊介面之外,完全不建議自行外接電子零組件。
其實即使是最基本便宜的 Uno,採用的 Atmel 328P 已經算是很強壯耐操,但是 Arduino 原廠還是推出可替換晶片的 DIP 版本。原因不是怕你太勤勞抹寫程式次數超過 Flash 上限,而是使用 Arduino 的新手眾多,容易犯錯把 328P 短路燒毀。因為 Arduino 晶片便宜、腳位少,所以替換維修容易也不心疼。但是中高階平台的 SoC 動輒數百根接腳,且採用有利自動化焊接的特殊插座,倘若核心晶片真的燒壞時,需要解焊再更換晶片,費工又費錢,連原廠都不願收費維修,多半建議直接重買。
即便不是核心晶片燒毀,要找到這類平台電路板實際燒毀的元件加以替換,通常也是相當高難度的專業技能。為了避免找自己荷包與時間的麻煩,建議就是能免就免!
解決方案
那怎麼辦?就是有實際需求需要外接傳感器、顯示裝置、或是人機介面啊... 建議是稍微花點時間、通常也是要多花點錢透過下列兩種方式進行:
- 尋找專門模組
關於擴充方面,其實不少公司針對 Raspberry Pi 設計了專門的擴充模組。所以有現成的就用現成的,不過要注意的是雖然 Raspberry Pi 與 Jetson Nano 的 GPIO 插座長得一模一樣,但是因為 Jetson Nano 介面的電氣規格更為嚴苛,所以能夠兩者通用的模組非常稀少。
- 使用 I/O 擴充板
另一個思路則是找中間替死鬼,也就是有些擴充板本身沒有應用功能,而是提供 I/O 介面的擴充與緩衝,這方面也是有很多針對 Raspberry Pi 設計的產品,通常替死鬼是找專門的晶片扮演的,其實都還滿強壯的。只是這種解決方式,成本可能就更高了!
建議方案
其實我們推薦的是另一個方式:透過 USB 去串接簡單的 MCU 開發板進行 I/O 控制,尤其是像 Arduino 之類、具備 USB 串列通訊介面的迷你控制器。
中高階平台基本上都配置有強大又眾多的 USB 端口,能夠透過 USB 串接是快速、便宜、又方便的。更棒的是現在很多廠商都提供有 Arduino 或 STM32 等 MCU 的 sample code。光是能夠簡單地修改一下就能立即應用周邊功能,省下大筆的開發時間成本就非常值得!
對於一般的傳感器而言,這個架構的 USB 傳輸速率應該都足堪應付。因為並不是需要將細部的控制訊號傳遞給 MCU,而是傳遞高階的抽象指令,MCU 再負責實際的 I/O 控制訊號,尤其是 MCU 工作單一,更能精準地掌控訊號時序。此外,平台端也能擺脫即時控制的需求,無需追求 RTOS 等級的工作切換。更棒的是還可以用以讀寫類比周邊,有機會省略 ADC 的需求。
如果需要控制多個傳感器並回傳資料呢?那就自己設計簡單的通訊協定傳送命令與資料。為了準確地解讀序列資料,可以參考採用如 Consistent Overhead Byte Stuffing 之類的技巧,確切地將訊息以封包形式傳送與接收,提高傳輸與執行效率(確認收到一個完整封包後再執行)。就可以愉快地分工處理。而且 USB 的隔離效果挺不錯的,即使 MCU 開發板不幸犧牲了,波及中高階平台的機率已經降至非常低了!Arduino 上常用的函式庫為 PacketSerial,Host 端可用的實作就更多了...
Raspberry Pi Pico 應該足以勝任這項工作,尤其是 MCU 上直接附帶理論上可達到 12Mbps 的 Fullspeed USB 介面,還有可程式化 I/O 時序控制功能,是個高性價比的選擇!
目前比較不太能夠勝任的大概是 SPI 等級的大量資料傳輸需求,這個部分倒是可以考慮直接接入平台,因為是純粹數位訊號,電流需求相當微弱。再高的話都是 USB 與網路介面的範圍了!
結論
雖然中高階平台上都已經配置了豐富的 GPIO 介面,但是在實驗風險與維護便利性的考量下,採用上述兩個方案,是我們認為比較好的解決方式,您以為呢?
PS. 封面照片取自 https://www.jetsonhacks.com/2019/06/07/jetson-nano-gpio/