MicroPythonで実践!Raspberry PiとGY-NEO6MV2によるGPS位置情報の取得手順

はじめに

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)
GPGGAGPS位置データ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

フィールド番号内容説明
1UTC時刻110857.0011:08:57(UTC)
2データ有効性AA=有効、V=無効
3緯度3540.46863緯度(35°40.46863′ 北)
4北/南NN=北、S=南
5経度13934.28708経度(139°34.28708′ 東)
6東/西EE=東、W=西
7地上速度(ノット)2.108地上速度(単位: ノット)
8進行方向(度)空欄進行方向(単位: 度)
9日付1201252025年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データ有効性AA=有効、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

フィールド番号内容説明
1UTC時刻110857.0011:08:57(UTC)
2緯度3540.46863緯度(35°40.46863′ 北)
3北/南NN=北、S=南
4経度13934.28708経度(139°34.28708′ 東)
5東/西EE=東、W=西
6Fix status10=未特定、1=2D Fix、2=3D Fix
7使用中の衛星数04使用している衛星の数
8HDOP4.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モードAA=自動、M=手動
2Fixタイプ31=未特定、2=2D Fix、3=3D Fix
3-14使用衛星のPRN番号03,14,06,04使用中の衛星ID
15PDOP(総合精度)4.86小さいほど精度が良い
16HDOP(水平精度)4.09小さいほど精度が良い
17VDOP(垂直精度)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 PicoGY-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()

まとめ

身近にあるデバイスですがいろいろなデータを取得することが可能です。他のデバイスと組み合わせてもいろいろなことができると思いますので是非試してみてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする