讀取 GPS 數據 - 樹莓派
在本課程的這部分,你將為樹莓派添加一個 GPS 傳感器,並從中讀取數據。
硬體
樹莓派需要一個 GPS 傳感器。
你將使用的傳感器是 Grove GPS Air530 傳感器。這個傳感器可以連接到多個 GPS 系統,以獲得快速、準確的定位。該傳感器由兩部分組成 - 傳感器的核心電子元件和通過細線連接的外部天線,用於接收來自衛星的無線電波。
這是一個 UART 傳感器,因此通過 UART 傳輸 GPS 數據。
連接 GPS 傳感器
Grove GPS 傳感器可以連接到樹莓派。
任務 - 連接 GPS 傳感器
連接 GPS 傳感器。
-
將 Grove 電纜的一端插入 GPS 傳感器上的插座。它只能以一種方式插入。
-
在樹莓派關機的情況下,將 Grove 電纜的另一端連接到樹莓派上的 Grove Base hat 上標有 UART 的 UART 插座。該插座位於中間排,靠近 SD 卡插槽的一側,遠離 USB 端口和以太網插座的另一端。
-
將 GPS 傳感器放置在附帶的天線可以看到天空的位置 - 最好靠近開放的窗戶或在室外。天線沒有障礙物時更容易獲得清晰的信號。
編程 GPS 傳感器
現在可以編程樹莓派以使用連接的 GPS 傳感器。
任務 - 編程 GPS 傳感器
編程設備。
-
啟動樹莓派並等待其啟動
-
GPS 傳感 器有兩個 LED - 一個藍色 LED 在數據傳輸時閃爍,另一個綠色 LED 在接收來自衛星的數據時每秒閃爍一次。確保在啟動樹莓派時藍色 LED 閃爍。幾分鐘後綠色 LED 會閃爍 - 如果沒有,可能需要重新定位天線。
-
啟動 VS Code,可以直接在樹莓派上啟動,或者通過 Remote SSH 擴展連接。
⚠️ 如果需要,可以參考 在第 1 課中設置和啟動 VS Code 的說明。
-
對於支持藍牙的較新版本的樹莓派,藍牙使用的串行端口與 Grove UART 端口使用的串行端口之間存在衝突。要解決此問題,請執行以下操作:
-
從 VS Code 終端,使用以下命令編輯
/boot/config.txt
文件,使用內置終端文本編輯器nano
:sudo nano /boot/config.txt
由於需要使用
sudo
權限( 提升的權限)編輯此文件,因此無法通過 VS Code 編輯。VS Code 不會以此權限運行。 -
使用光標鍵導航到文件末尾,然後複製以下代碼並粘貼到文件末尾:
dtoverlay=pi3-miniuart-bt
dtoverlay=pi3-disable-bt
enable_uart=1你可以使用設備的常規鍵盤快捷鍵粘貼(Windows、Linux 或樹莓派 OS 上使用
Ctrl+v
,macOS 上使用Cmd+v
)。 -
按
Ctrl+x
保存此文件並退出 nano。當被問及是否要保存修改的緩衝區時,按y
,然後按enter
確認要覆蓋/boot/config.txt
。如果出錯,可以不保存退出,然後重複這些步驟。
-
使用以下命令在 nano 中編輯
/boot/cmdline.txt
文件:sudo nano /boot/cmdline.txt
-
該文件包含多個用空格分隔的鍵/值對。刪除任何鍵為
console
的鍵/值對。它們可能看起來像這樣:console=serial0,115200 console=tty1
你可以使用光標鍵導航到這些條目,然後使用常規的
del
或backspace
鍵刪除。例如,如果你的原始文件看起來像這樣:
console=serial0,115200 console=tty1 root=PARTUUID=058e2867-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
新版本將是:
root=PARTUUID=058e2867-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
-
按照上述步驟保存此文件並退出 nano
-
重新啟動樹莓派,然後在樹莓派重新啟動後重新連接 VS Code。
-
-
從終端,在
pi
用戶的主目錄中創建一個名為gps-sensor
的新文件夾。在此文件夾中創建一個名為app.py
的文件。 -
在 VS Code 中打開此文件夾
-
GPS 模塊通過串行端口發送 UART 數據。安裝
pyserial
Pip 包以從 Python 代碼與串行端口通信:pip3 install pyserial
-
將以下代碼添加到你的
app.py
文件中:import time
import serial
serial = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
serial.reset_input_buffer()
serial.flush()
def print_gps_data(line):
print(line.rstrip())
while True:
line = serial.readline().decode('utf-8')
while len(line) > 0:
print_gps_data(line)
line = serial.readline().decode('utf-8')
time.sleep(1)此代碼從
pyserial
Pip 包中導入serial
模塊。然後它連接到/dev/ttyAMA0
串行端口 - 這是 Grove Pi Base Hat 用於其 UART 端口的串行端口地址。然後它清除此串行連接中的任何現有數據。接下來定義了一個名為
print_gps_data
的函數,該函數將傳遞給它的行打印到控制台。接下來,代碼無限循環,每次循環從串行端口讀取盡可能多的行文本。它為每行調用
print_gps_data
函數。在讀取所有數據後,循環休眠 1 秒鐘,然後再次嘗試。
-
運行此代碼。你將看到來自 GPS 傳感器的原始輸出,如下所示:
$GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$BDGSA,A,1,,,,,,,,,,,,,,,*0F
$GPGSV,1,1,00*79
$BDGSV,1,1,00*68如果在停止和重新啟動代碼時遇到以下錯誤之一,請將
try - except
塊添加到你的 while 循環中。UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 0: invalid start byte
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation bytewhile True:
try:
line = serial.readline().decode('utf-8')
while len(line) > 0:
print_gps_data()
line = serial.readline().decode('utf-8')
# There's a random chance the first byte being read is part way through a character.
# Read another full line and continue.
except UnicodeDecodeError:
line = serial.readline().decode('utf-8')
time.sleep(1)
💁 你可以在 code-gps/pi 文件夾中找到此代碼。
😀 你的 GPS 傳感器程序成功了!