跳到正文

Wiki

UART序列埠通訊

約 4 分鐘閱讀

本文由簡體中文內容確定性轉換,並受版本化術語表保護。

1.Linux 序列埠通訊

序列埠通訊是機器人和嵌入式專案中最常見的底層通訊方式之一。

在實際專案中,上位機經常需要通過序列埠和 STM32、ESP32、Arduino、感測器模組、除錯板等裝置進行資料互動。例如:

  • 上位機向 STM32 傳送電機速度指令
  • STM32 向上位機返回編碼器資料
  • 讀取 IMU、GPS、雷射測距模組等感測器資料
  • 使用 USB 轉序列埠模組進行除錯
  • 在 ROS 2 底盤控制中和下位機通訊

序列埠通訊的特點是簡單、通用、成本低,特別適合上位機和微控制器之間的點對點通訊。

1.1.序列埠通訊是什麼

序列埠通訊通常指 UART 通訊。在 Linux 上,常見的 USB 轉序列埠裝置會被識別為類似下面的裝置檔案:

/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyACM0

程式只需要開啟對應的裝置檔案,並設定好波特率、資料位、停止位、校驗位等引數,就可以進行資料收發。

常見引數包括:

引數 說明
裝置名 例如 /dev/ttyUSB0/dev/ttyACM0
波特率 例如 115200、921600
資料位 常見為 8 位
停止位 常見為 1 位
校驗位 常見為無校驗
流控 一般專案中常關閉硬體流控

在機器人專案中,序列埠通常不會只發送普通字串,而是會設計自己的二進位制通訊協議,例如幀頭、長度、命令字、資料區、CRC 校驗等。

1.2.Linux 下常見序列埠庫

Linux 下使用序列埠通訊有多種方案,常見的包括:

方案 型別 特點 適合場景
termios Linux 原生介面 最底層、依賴少、通用性強,但程式碼相對繁瑣 想深入理解 Linux 序列埠機制
boost::asio 通用 C++ 庫 支援同步/非同步,程式碼結構較清晰,跨平臺能力較好 推薦用於 C++ 工程封裝
libserial 第三方序列埠庫 使用簡單,比 termios 更易上手 普通序列埠收發專案
serial_driver ROS 2 生態封裝 更方便接入 ROS 2,但不適合只依賴 ROS 2 以外的專案 純 ROS 2 專案或參考實現
pyserial Python 序列埠庫 使用非常簡單,適合快速測試 Python 除錯指令碼

這些庫本質上都是為了完成序列埠的開啟、配置、讀取和寫入,只是封裝層次不同。

1.3.各方案對比

方案 優點 缺點
termios Linux 原生、依賴最少、底層能力強 配置繁瑣,初學者容易寫錯
boost::asio C++ 工程友好,非同步通訊方便,適合封裝 driver 需要理解 asio 的基本模型
libserial 簡單易用,上手快 靈活性和工程可控性不如自己封裝
serial_driver 和 ROS 2 生態結合方便 離開 ROS 2 後複用性較差
pyserial 除錯快,適合指令碼 不適合作為高效能 C++ 底層驅動主線

1.4.本教程建議選擇

本教程建議優先選擇:

boost::asio

原因是:

  • 比直接使用 termios 更適合 C++ 工程開發
  • 可以封裝成普通 C++ driver,方便複用
  • 不依賴 ROS 2,OpenCV、Qt、普通 C++ 專案都能使用
  • 後續也可以很自然地接入 ros2_control hardware_interface
  • 比較適合機器人上位機和 STM32 通訊場景

推薦的工程結構是:

上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序

自己封装的 SerialDriver 类

boost::asio

/dev/ttyUSB0

STM32 / ESP32 / 传感器

1.5.與 ROS 2 的關係

學習 Linux 序列埠通訊,並不代表不用 ROS 2。

在 ROS 2 專案中,可以將序列埠通訊封裝成一個普通 C++ 類,然後在 ROS 2 節點或 ros2_control hardware_interface 中呼叫它。

例如:

ros2_control controller

hardware_interface

自己封装的 SerialDriver

boost::asio

STM32

這樣做的好處是,序列埠通訊程式碼不會和 ROS 2 強繫結。以後即使寫 OpenCV 專案、Qt 上位機或者普通 C++ 除錯程式,也可以繼續複用同一套序列埠 driver。

1.6.本章學習目標

學習完本章後,應該能夠掌握:

  • Linux 下序列埠裝置的基本概念
  • 如何檢視和開啟 /dev/ttyUSB0 等序列埠裝置
  • 序列埠波特率、資料位、停止位、校驗位等基本引數
  • 使用 C++ 進行序列埠資料收發
  • 設計簡單的上位機與下位機通訊協議
  • 將序列埠通訊封裝成可複用的 C++ 類
  • 為後續接入 ROS 2、OpenCV、Qt 專案打基礎