GPS 模組的使用

上方這是一款常見的USB介面的GPS衛星接收器,透過USB模擬TTY介面,我們可以使用程式讀取serial port獲得GPS的資訊。以Linux環境(包含Raspberry OS)為例,OS透過所謂的UDEV daemon來進行設備的管理,對應並維護/dev目錄底下的裝置節點。因此,當我們插入了此USB GPS,會在/dev目錄下產生一個ttyUSB0的序列埠裝置,此時我們便可依tty的讀取方式,取得即時的GPS資訊。

如果您購買的GPS裝置不是USB介面而是UART介面,那麼就要接到Raspberry GPIO的序列埠,Raspberry Pi比較特殊的是,在/dev下它本機的UART介面不叫ttyS0或ttyS1,而是ttyAMA0或ttyAMA1,這是在使用TTY時需要注意的。

GPS的格式

目前GPS標準的規格稱為NMEA 0183,由美國國家海洋電子協會(National Marine Electronics Association,NMEA)所制定,其傳輸規範如下:(來源:WIKI)

  • Baud rate:4,800
  • Data bits:8
  • Parity:None
  • Stop bits:1
  • Handshake:None

保留字元:(已使用於GPS訊息中)

ASCII Hex Dec Use
<CR> 0x0d 13 Carriage return
<LF> 0x0a 10 Line feed, end delimiter
! 0x21 33 Start of encapsulation sentence delimiter
$ 0x24 36 Start delimiter
* 0x2a 42 Checksum delimiter
, 0x2c 44 Field delimiter
\ 0x5c 92 TAG block delimiter
^ 0x5e 94 Code delimiter for HEX representation of ISO/IEC 8859-1 (ASCII) characters
~ 0x7e 126 Reserved

讀取GPS

  1. 將GPS插上USB port後,在/dev目錄下會多出一個ttyUSB0的檔案。
  2. 安裝pySerial,透過Python讀取serial的模組:
pip install pyserial
  1. 執行下方的程式:
# -*- coding: UTF-8 -*-
import serial

COM_PORT = '/dev/ttyUSB0' 
BAUD_RATES = 4800 
ser = serial.Serial(COM_PORT, BAUD_RATES) 

try:
    while True:
        while ser.in_waiting: 
        data_raw = ser.readline()
        data = data_raw.decode() # 預設的UTF-8解碼
        print('Raw data:', data_raw)
        print('Decoded :', data)

except KeyboardInterrupt:
    ser.close() 
    print('by...')

第一行的「# -*- coding: UTF-8 -*-」一定要加上,否則decode()編碼為UTF-8時會出現如下的error message。

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xc6 in position 2: invalid continuation byte

解碼GPS

執行後會持續收取到如下的message,這些資訊很明顯為CSV格式,每一行稱為一個sentence,一個sentence最長不會超過82個字元:

Raw data: b’,11,32,32,149,,29,18,043,,18,02,102,*48\r\n’

Decoded : ,11,32,32,149,,29,18,043,,18,02,102,*48

Raw data: b’$GPRMC,095912.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*65\r\n’

Decoded : $GPRMC,095912.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*65

Raw data: b’$GPGGA,095913.000,2446.4094,N,12101.0267,E,1,06,1.8,125.8,M,15.0,M,,0000*53\r\n’

Decoded : $GPGGA,095913.000,2446.4094,N,12101.0267,E,1,06,1.8,125.8,M,15.0,M,,0000*53

Raw data: b’$GPGSA,A,3,26,16,27,04,03,22,,,,,,,2.9,1.8,2.2*31\r\n’

Decoded : $GPGSA,A,3,26,16,27,04,03,22,,,,,,,2.9,1.8,2.2*31

Raw data: b’$GPRMC,095913.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*64\r\n’

Decoded : $GPRMC,095913.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*64

每行sentence具有以下的結構:

start character

每行的啟始字元只有兩種:$以及!,「$」符號表示該行為正確的GPS資訊,「!」符號表示該行有特殊的異常資訊。

Ex: $GPRMC,095912.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*65

identify characters

啟始字元後方的五個字元稱為identifier,表示該sentence的種類,目前已知超過五十多種。(下方資料來源:http://aprs.gids.nl/nmea/#allgp)

  1. $GPAAM – Waypoint Arrival Alarm
  2. $GPALM – GPS Almanac Data
  3. $GPAPA – Autopilot Sentence “A"
  4. $GPAPB – Autopilot Sentence “B"
  5. $GPASD – Autopilot System Data
  6. $GPBEC – Bearing & Distance to Waypoint, Dead Reckoning
  7. $GPBOD – Bearing, Origin to Destination
  8. $GPBWC – Bearing & Distance to Waypoint, Great Circle
  9. $GPBWR – Bearing & Distance to Waypoint, Rhumb Line
  10. $GPBWW – Bearing, Waypoint to Waypoint
  11. $GPDBT – Depth Below Transducer
  12. $GPDCN – Decca Position
  13. $GPDPT – Depth
  14. $GPFSI – Frequency Set Information
  15. $GPGGA – Global Positioning System Fix Data
  16. $GPGLC – Geographic Position, Loran-C
  17. $GPGLL – Geographic Position, Latitude/Longitude
  18. $GPGSA – GPS DOP and Active Satellites
  19. $GPGSV – GPS Satellites in View
  20. $GPGXA – TRANSIT Position
  21. $GPHDG – Heading, Deviation & Variation
  22. $GPHDT – Heading, True
  23. $GPHSC – Heading Steering Command
  24. $GPLCD – Loran-C Signal Data
  25. $GPMTA – Air Temperature (to be phased out)
  26. $GPMTW – Water Temperature
  27. $GPMWD – Wind Direction
  28. $GPMWV – Wind Speed and Angle
  29. $GPOLN – Omega Lane Numbers
  30. $GPOSD – Own Ship Data
  31. $GPR00 – Waypoint active route (not standard)
  32. $GPRMA – Recommended Minimum Specific Loran-C Data
  33. $GPRMB – Recommended Minimum Navigation Information
  34. $GPRMC – Recommended Minimum Specific GPS/TRANSIT Data
  35. $GPROT – Rate of Turn
  36. $GPRPM – Revolutions
  37. $GPRSA – Rudder Sensor Angle
  38. $GPRSD – RADAR System Data
  39. $GPRTE – Routes
  40. $GPSFI – Scanning Frequency Information
  41. $GPSTN – Multiple Data ID
  42. $GPTRF – Transit Fix Data
  43. $GPTTM – Tracked Target Message
  44. $GPVBW – Dual Ground/Water Speed
  45. $GPVDR – Set and Drift
  46. $GPVHW – Water Speed and Heading
  47. $GPVLW – Distance Traveled through the Water
  48. $GPVPW – Speed, Measured Parallel to Wind
  49. $GPVTG – Track Made Good and Ground Speed
  50. $GPWCV – Waypoint Closure Velocity
  51. $GPWNC – Distance, Waypoint to Waypoint
  52. $GPWPL – Waypoint Location
  53. $GPXDR – Transducer Measurements
  54. $GPXTE – Cross-Track Error, Measured
  55. $GPXTR – Cross-Track Error, Dead Reckoning
  56. $GPZDA – Time & Date
  57. $GPZFO – UTC & Time from Origin Waypoint
  58. $GPZTG – UTC & Time to Destination Waypoint

但不是每種GPS裝置都支援(可輸出)這麼多種,以我手上的這支環天出品的GPS為例,僅支援GPRMC、GPGGA與GPGSA這三種identifier。

GPGGA格式

  1. 為identify characters
  2. 為UTC 時間,格式:hhmmss(時分秒)。
  3. 緯度ddmm.mmmm(度分)格式
  4. 緯度半球N(北半球)或S(南半球)
  5. 經度dddmm.mmmm(度分)格式
  6. 經度半球E(東經)或W(西經)
  7. Fix Quality:0=未定位,1=非差分定位,2=差分定位,6=正在估算
  8. 已抓取定位的衛星數目:如本例為7個
  9. Horizontal Dilution of Precision (HDOP) 海拔高度
  10. 海拔高度(-9999.9~99999.9),指高於海平面的高度。
  11. 衛星高度單位:M為公尺
  12. 地球橢球面相對大地水準面的高度
  13. 水平面高度單位:M為公尺
  14. 差分時間(從最近一次接收到差分信號開始的秒數,如果不是差分定位將為空)
  15. 差分站ID號0000~1023(前面的0也將被傳輸,如果不是差分定位將為空)

GPGSA格式

  1. 為identify characters
  2. 定位方式:M = 手動, A = 自動。
  3. 定位型式 1 = 未定位, 2 = 二維定位, 3 = 三維定位。
  4. 第一組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  5. 第二組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  6. 第三組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  7. 第四組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  8. 第五組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  9. 第六組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  10. 第七組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  11. 第八組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  12. 第九組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  13. 第十組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  14. 第十一組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
  15. 第十二組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
    (最多可接收12顆衛星資訊)
  16. PDOP位置精度因數(0.5~99.9)
  17. HDOP水準精度因數(0.5~99.9)
  18. VDOP垂直精度因數(0.5~99.9)
  19. Checksum.(檢查位).

GPRMC格式

  1. 為identify characters
  2. UTC時間,hhmmss(時分秒)格式
  3. 定位狀態,A=有效定位,V=無效定位
  4. 緯度ddmm.mmmm(度分)格式
  5. 緯度半球N(北半球)或S(南半球)
  6. 經度dddmm.mmmm(度分)格式
  7. 經度半球E(東經)或W(西經)
  8. 地面速率(000.0~999.9節)
  9. 地面航向(000.0~359.9度,以真北為參考基準)
  10. UTC日期,ddmmyy(日月年)格式
  11. 磁偏角(000.0~180.0度)
  12. 磁偏角方向,E(東)或W(西)
  13. 模式指示(A=自主定位,D=差分,E=估算,N=資料無效)

使用GPS

以這支Globalsat 環天衛星接收器(BU-353S4 GPS)為例,它可輸出三種格式的資訊:GPRMC、GPGGA與GPGSA,從上方表格的identify資訊我們可以知道,如果要取得目前GPS所在位置,使用GPRMS是最適合的,如果要取得目前海拔高度,就要使用GPGGA,而如果要知道各衛星的詳細定位資訊,那麼就要用GPGSA。

透過TTY來使用GPS模組相當的容易且方便,因此,我們可以利用Arduino或樹莓派等開發板,快速的開發出各式功能以滿足與「位置」情境相關的應用需求。