はじめに
GPSモジュール「GY-NEO6MV2」は、高精度な位置情報を簡単に取得できる便利なデバイスです。本記事では、このGPSモジュールをラズベリーパイやラズベリーパイPicoに接続して活用する方法を紹介します。
GY-NEO6MV2とは
u-blox社製のNEO-6Mチップを搭載したGPSモジュールで、以下の特徴があります
・シリアル通信でデータ送受信ができる
・高感度で安定した受信性能がある
・外部アンテナ接続が可能
・デフォルトの通信速度が9600bps
非常に簡単にデータを取得することができます。Raspberry picoでもRaspberry Piのどちらでも使えます。
取得できるデータとその意味
GPSモジュール(GY-NEO6MV2)が出力するデータは、NMEAと呼ばれるフォーマットで構成されています。以下に主要なNMEA文とその意味を一覧で説明します。
ID | 内容 | 含まれる情報 |
GPRMC | 最小推奨ナビゲーション情報 | UTC時刻、緯度、経度、速度、進行方向、日付、データ有効性など |
GPVTG | 地上速度と進行方向 | コース(真北基準/磁北基準)、地上速度(ノット、km/h) |
GPGGA | GPS位置データ | UTC時刻、緯度、経度、Fix status、衛星数、HDOP、海抜高度、ジオイド高など |
GPGSA | 衛星のDOP(精度)と使用衛星一覧 | Fixモード、DOP値(PDOP, HDOP, VDOP)、使用衛星PRN番号 |
GPGSV | 可視衛星の詳細 | 衛星番号、仰角、方位角、SNR(信号対雑音比) |
GPGLL | 緯度・経度とUTC時刻 | 緯度、経度、UTC時刻、データ有効性 |
GPRMC(Recommended Minimum Navigation Information)
このような文字列データが取得できます。
$GPRMC,110857.00,A,3543,N,13850,E,2.108,,120125,,,A*70
フィールド番号 | 内容 | 例 | 説明 |
1 | UTC時刻 | 110857.00 | 11:08:57(UTC) |
2 | データ有効性 | A | A=有効、V=無効 |
3 | 緯度 | 3540.46863 | 緯度(35°40.46863′ 北) |
4 | 北/南 | N | N=北、S=南 |
5 | 経度 | 13934.28708 | 経度(139°34.28708′ 東) |
6 | 東/西 | E | E=東、W=西 |
7 | 地上速度(ノット) | 2.108 | 地上速度(単位: ノット) |
8 | 進行方向(度) | 空欄 | 進行方向(単位: 度) |
9 | 日付 | 120125 | 2025年1月12日 |
10 | 磁気偏角(度) | 空欄 | 磁北と真北の差 |
11 | 磁気偏角方向 | 空欄 | E=東、W=西 |
12 | チェックサム | *70 | データエラー検出用 |
GPVTG(Track Made Good and Ground Speed)
このような文字列データが取得できます。
$GPVTG,,T,,M,2.108,N,3.904,K,A*26
フィールド番号 | 内容 | 例 | 説明 |
1 | 進行方向(真北基準) | 空欄 | コース(真北基準) |
2 | 真北基準 | T | 常に T (True) |
3 | 進行方向(磁北基準) | 空欄 | コース(磁北基準) |
4 | 磁北基準 | M | 常に M (Magnetic) |
5 | 地上速度(ノット) | 2.108 | 地上速度(単位: ノット) |
6 | 地上速度(km/h) | 3.904 | 地上速度(単位: km/h) |
7 | データ有効性 | A | A=有効、V=無効 |
GPGGA(Global Positionig System Fix Data)
このような文字列データが取得できます。
$GPGGA,110857.00,3540.46863,N,13934.28708,E,1,04,4.09,16.2,M,39.1,M,,*65
フィールド番号 | 内容 | 例 | 説明 |
1 | UTC時刻 | 110857.00 | 11:08:57(UTC) |
2 | 緯度 | 3540.46863 | 緯度(35°40.46863′ 北) |
3 | 北/南 | N | N=北、S=南 |
4 | 経度 | 13934.28708 | 経度(139°34.28708′ 東) |
5 | 東/西 | E | E=東、W=西 |
6 | Fix status | 1 | 0=未特定、1=2D Fix、2=3D Fix |
7 | 使用中の衛星数 | 04 | 使用している衛星の数 |
8 | HDOP | 4.09 | 水平精度(小さいほど良い) |
9 | 海抜高度(単位: メートル) | 16.2 | 測定地点の海抜高度 |
10 | ジオイド高 | 39.1,M | ジオイド高(単位: メートル) |
GPGSA(GPS DOP and Active Satellites)
このような文字列データが取得できます。
$GPGSA,A,3,03,14,06,04,,,,,,,,,4.86,4.09,2.61*04
フィールド番号 | 内容 | 例 | 説明 |
1 | モード | A | A=自動、M=手動 |
2 | Fixタイプ | 3 | 1=未特定、2=2D Fix、3=3D Fix |
3-14 | 使用衛星のPRN番号 | 03,14,06,04 | 使用中の衛星ID |
15 | PDOP(総合精度) | 4.86 | 小さいほど精度が良い |
16 | HDOP(水平精度) | 4.09 | 小さいほど精度が良い |
17 | VDOP(垂直精度) | 2.61 | 小さいほど精度が良い |
GPGSV(Satellites in View)
このような文字列データが取得できます。
GPGSV,4,1,14,01,44,045,,02,41,051,,03,71,097,16,04,09,139,26*7C
フィールド番号 | 内容 | 例 | 説明 |
1 | 総メッセージ数 | 4 | 衛星情報が複数文に分かれている場合の総数 |
2 | 現在のメッセージ番号 | 1 | 今解析している文の番号 |
3 | 可視衛星数 | 14 | 現在視界にある衛星の数 |
4-7 | 衛星情報(PRN、仰角、方位、SNR) | 01,44,045,, | 衛星番号、仰角(度)、方位角(度)、SNR |
配線
RXはTXにTXはRXに接続することを間違えないようにしてください。
RaspberryPi Pico | GY-NEO6MV2 |
VSYS(39番) | VCC |
GND(38番) | GND |
GP0(1番) | RX |
GP1(2番) | TX |
データを取得する
シンプルにすべてのデータを取得します。屋外でしばらく待ってみてください。
from machine import UART, Pin
import time
# UARTの初期化
uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
def read_gps():
while True:
if uart.any():
# GPSデータを読み取る
gps_data = uart.readline()
try:
gps_data = gps_data.decode('utf-8').strip()
print(gps_data)
except UnicodeDecodeError:
pass # デコードエラーを無視
time.sleep(0.5)
# GPSデータの読み取りを開始
read_gps()
GPRMCから時刻と速度を取得します。衛星が補足できていないときは文をだします。
データが正常であるか?をまず確認することが大切です。
データの取得には、”,(カンマ)”区切りを利用します。
from machine import UART, Pin
import time
# UARTの初期化
uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
def parse_gprmc(sentence):
"""
GPRMC文を解析して時刻と速度を取得
"""
parts = sentence.split(',')
if len(parts) > 7 and parts[2] == 'A': # データが有効であることを確認
utc_time = parts[1] # UTC時刻
speed_knots = float(parts[7]) if parts[7] else 0 # 地上速度 (ノット)
speed_kmh = speed_knots * 1.852 # ノットをkm/hに変換
return utc_time, speed_kmh
return None, None, None
def parse_gpgsv(sentence):
"""
GPGSV文を解析して可視衛星の数を取得
"""
parts = sentence.split(',')
if len(parts) > 3:
try:
return int(parts[3]) # 可視衛星の数
except ValueError:
pass
return 0
def read_gps():
visible_satellites = 0
while True:
if uart.any():
# GPSデータを読み取る
gps_data = uart.readline()
try:
gps_data = gps_data.decode('utf-8').strip()
if gps_data.startswith('$GPRMC'):
utc_time, speed_kmh = parse_gprmc(gps_data)
if utc_time:
print(f"Time (UTC): {utc_time}, Speed: {speed_kmh:.2f} km/h, Visible Satellites: {visible_satellites}")
elif gps_data.startswith('$GPGSV'):
visible_satellites = parse_gpgsv(gps_data)
if visible_satellites == 0:
print("No satellites currently visible")
except UnicodeDecodeError:
pass # デコードエラーを無視
time.sleep(1)
# GPSデータの読み取りを開始
read_gps()
まとめ
身近にあるデバイスですがいろいろなデータを取得することが可能です。他のデバイスと組み合わせてもいろいろなことができると思いますので是非試してみてください。
コメント