Qt C++ 桌面讀取教學
用 Qt SerialPort 建立桌面測試工具,讀取 ANROT 即時姿態封包並快速做 GUI 驗證。
- qt
- cplusplus
- serial
- tutorial
Qt C++ 桌面讀取範例
協議支援
| 協議 / frame | 支援狀態 | 這份 example 的處理方式 |
|---|---|---|
0x91 IMUSOL | 支援 | 單機 float frame,輸出到 receive_imusol 並更新 UI。 |
0x62 GWSOL | 支援 | Gateway float collection,輸出到 receive_gwsol。 |
0x63 GWSOL Compact | 支援 | Compact int16 gateway frame,含 0x93 node block,轉成 float 後顯示。 |
0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xD1 | 支援 | 可解析單欄位輸出模式。 |
0xF0 Pressure | 略過 | decoder 跳過此 item,UI 不顯示 pressure。 |
這份範例使用 Qt Widgets 與 Qt SerialPort 建立一個簡單的桌面工具,適合先確認 ANROT 裝置輸出是否正常,再把解碼器整合到自己的 C++ / GUI 專案。
下載範例
瀏覽器下載並解壓縮: demo-qt-cplusplus-en.zip
主要結構:
demo_qtc++/
├── CHReceiver.pro
├── main.cpp
├── mainwindow.h / mainwindow.cpp / mainwindow.ui
└── include/
├── packet.h / packet.cpp
└── imu_data_decode.h / imu_data_decode.cpp
測試環境
- Qt 5.9.9 + Windows 10。
- 產品透過 USB 或 USB-UART 連到電腦。
- 支援 ANROT binary frame:
0x91、0x62、0x63。
1. 開啟專案
用 Qt Creator 開啟 demo_qtc++/CHReceiver.pro。專案已加入 Qt SerialPort:
QT += serialport
若要把解碼功能搬到自己的 Qt 專案,至少需要加入:
#include "include/imu_data_decode.h"
#include "include/packet.h"
並把 include/packet.*、include/imu_data_decode.* 加入專案。
2. 初始化解碼器
開始接收串列資料前呼叫一次:
imu_data_decode_init();
3. 選擇串列埠與波特率
程式提供串列埠與波特率選單。波特率必須與產品端設定一致。
| 波特率 | 建議場景 |
|---|---|
| 115200 | 單機模式、低資料率 |
| 230400 | 中等資料率 |
| 460800 | 多節點 Gateway |
| 921600 | 高 ODR 或高節點數 |
4. 接收資料
範例在 QSerialPort::readyRead 觸發時讀取所有 byte,再逐一送進 packet_decode():
void MainWindow::read_serial()
{
QByteArray arr = m_reader.readAll();
for (int i = 0; i < arr.size(); i++) {
uint8_t c = static_cast<uint8_t>(arr[i]);
packet_decode(c);
}
}
packet_decode() 會處理 frame sync、長度、CRC 與 payload item。解碼成功後,資料會寫入全域資料結構。
5. 讀取單機資料
單一 IMU 的 0x91 資料會在 receive_imusol:
float roll = receive_imusol.eul[0];
float pitch = receive_imusol.eul[1];
float yaw = receive_imusol.eul[2];
float ax = receive_imusol.acc[0];
float ay = receive_imusol.acc[1];
float az = receive_imusol.acc[2];
float qw = receive_imusol.quat[0];
float qx = receive_imusol.quat[1];
float qy = receive_imusol.quat[2];
float qz = receive_imusol.quat[3];
6. 讀取 Gateway 多節點資料
0x62 與 0x63 會統一轉成 receive_gwsol.receive_imusol[],應用層可以用同一段程式遍歷:
if (receive_gwsol.tag == KItemGWSOL || receive_gwsol.tag == KItemGWSOL_Compact)
{
uint8_t gw_id = receive_gwsol.gw_id;
uint8_t node_count = receive_gwsol.n;
for (int i = 0; i < node_count; i++)
{
uint8_t node_id = receive_gwsol.receive_imusol[i].id;
float roll = receive_gwsol.receive_imusol[i].eul[0];
float pitch = receive_gwsol.receive_imusol[i].eul[1];
float yaw = receive_gwsol.receive_imusol[i].eul[2];
}
}
0x63 是壓縮格式,封包較小,解碼後仍會轉成 float 欄位,方便 UI 或資料記錄直接使用。
支援封包
| Tag | 名稱 | 說明 |
|---|---|---|
0x91 | IMUSOL | 單一 IMU 完整資料,float 格式 |
0x62 | GWSOL | Gateway 聚合多個 0x91 節點 |
0x63 | GWSOL Compact | Gateway 壓縮聚合資料,解碼後轉成 float |
常見問題
UI 沒有更新
確認串列埠已開啟、波特率一致,並確認產品正在輸出 ANROT binary frame。
自己專案編譯失敗
先確認 .pro 有 QT += serialport,並且 packet.*、imu_data_decode.* 都被加入專案。若 include path 不同,請同步調整 #include 路徑。