非公式Rock研究所

Radxaのシングルボード(主にRock4c+)について書いています

GPSモジュール

注意:当サイトに掲載されている手順は動作を保証するものではないもの、また、当サイトに掲載されている情報をもとに電子回路を作成した結果によって生じたことについて、一切の責任を負えないことをご了承ください。

【Article】「Peripheralページに掲載する記事について」 - 非公式Rock研究所
https://informal-r-labo.net/posts/article011



GPSモジュール機器写真

ここではGPSモジュールを使ってGPS情報を取得してみる。

機器について

今回、GPS情報を取得するために以下のモジュールを使用した。

GPSモジュール単体写真

OSOYOO U-BLOX NEO-6M GPS モジュール

機器に関するメーカーサイトのリンク

NEO-6 series | u-blox
https://www.u-blox.com/en/product/neo-6-series

NEO-6 u-blox 6 GPS Modules Data Sheet
https://content.u-blox.com/sites/default/files/products/documents/NEO-6_DataSheet_%28GPS.G6-HW-09005%29.pdfs

裏面にセラミックアンテナがついており、これ単体でGPSを受信することができる。また、別の外部GPSアンテナを接続することも可能である。

受信したGPS情報はUart通信で転送される。U-BLOX NEO-6M GPS モジュールのUartの設定はメーカーのデータシートやosoyooのサイトの内容から以下の設定と思われる。

接続端子は5つあるが、GPS取得に使用する端子は4つだけで、PPS端子は使用しない。

ちなみに、PPSは正確な1秒を示す信号を出力する端子で時刻補正などに利用するようである。

GPSでよくみるPPS信号とはなにか - 或る阿呆の記
https://hack-le.com/whatispps/

外部アンテナの接続

今回使用するGPSモジュールには本体にアンテナがあるので、本体を電波の良い窓際に置けば単独でGPSを取得可能なのだが、私の環境では雨の日だと、本体を窓際に置いてもなかなかGPSを取得できないことがあった。

そのため、GPSモジュールに外部GPSアンテナを接続する。

外部GPSアンテナの写真

waves GPS 外付けアンテナ SMA端子 IPX-SMA変換ケーブル付属

外部アンテナの接続方法は、

外部GPSアンテナとの接続部分

このIPX端子部分に外部アンテナの変換ケーブル端子を接続する。パーツが小さく、少し硬いので、金具を破損しそうで心配になるが、ぐっと押せばはまる。

外部GPSアンテナ接続後のGPSモジュール

外部アンテナを接続したU-BLOX NEO-6M GPS モジュール

機器接続

GPSモジュールへの電源供給はVCCおよびGNDのPin、GPS信号についてはRXDおよびTXDのPinを使用する。

具体的な接続方法はosoyooの製品紹介ページにRaspberry Piを使った接続方法が紹介されている。GPIOのPin配列がRaspberry PiとRock4c+では異なるが、GPSモジュール側の接続を参考にした。

Rapsberry Pi を使って、U-BLOX NEO-6M GPS モジュールを作動する « osoyoo.com
https://osoyoo.com/ja/2016/10/25/use-rapsberry-pi-to-drive-u-blox-neo-6m-gps-module/

Rock4c+側はGPS信号を受信するためにUart4を使用する。
Uart4を動作させるための設定については以下のページを参照されたい。

【GPIO】Uart Communication-準備編 - 非公式Rock研究所
https://informal-r-labo.net/posts/gpio007

Rock4c+とU-BLOX NEO-6M GPS モジュールを接続するための回路図は以下のようになる。

GPSモジュールの回路図

Pythonコード

~/pyディレクトリに"Gps_recieve.py"のファイル名でviを起動し、編集モードで以下のコードを入力する。 (Rock4c+には日本語が入力できないため、カッコ書きのコメント行は入力不要。)

# (ライブラリのimport)
import mraa

# (Uart4を指定)
port = "/dev/ttyS4"
u = mraa.Uart(port)

# (Uart通信では一般的な設定)
# (ボーレートは9600)
u.setBaudRate(9600)
# (データビット数:8,パリティビット:なし,ストップビット:1,フロー制御なし)
u.setMode(8, mraa.UART_PARITY_NONE, 1)
u.setFlowcontrol(False, False)

while True:
    # (読み取り可能なデータがあるか)
    if u.dataAvailable():
        # (GPSモジュールよりGPSデータ読み取り)
        recieve_data = u.readStr(200)
        # (改行せずにRock4c+に画面出力)
        print(recieve_data, end='')

コーディングが完了すれば保存する。

コードの実行

外部GPSアンテナ(もしくはGPSモジュール)を電波を受信しやすい窓際などに配置する。

窓際の外部アンテナ

GPSモジュールとRock4c+の結線が間違っていないか確認し、問題がなければ先程のコードを管理者権限で実行する。
(GPIOを操作するには管理者権限が必要。)

$ sudo python3 ~/py/Gps_recieve.py
Gps_recieve.py実行結果(直後)

実行すると、様々なレイアウトのGPSデータが連続して画面に出力される。しかし、測位まで少し時間がかかるようで、実行結果にはGPSの緯度や経度を示す値はまだ表示されていない。

GPSモジュールのLED点灯

GPSの受信状況を確認する方法として、U-BLOX NEO-6M GPS モジュールはLEDがついており、LEDの点灯パターンで判断することができる。

アンテナの位置が良ければ、しばらくするとLEDが点滅する。この段階で実行結果を確認すると、

Gps_recieve.py実行結果(測位)

GPSの緯度経度と思われる値が出力されている。(画像はモザイク処理している。)

試しに、緯度経度の値をGoogle Mapで検索してみたが、正確に測位できていた。

ちなみに検索の際は、出力値をそのまま張り付けるのではなく、小数点から左に2桁目と3桁目に空白をいれる必要がある。たとえば、"12345.67890"という出力値の場合、"123 45.67890"で検索する。

GPSのフォーマットの詳細については以下のサイトが参考になったのでリンクを貼っておく。

GPSのNMEAフォーマット
https://www.hiramine.com/physicalcomputing/general/gps_nmeaformat.html

GPSデータとその取得タイミング

GPSモジュールから出力されるGPSデータは"$GPGGA”など$から始まる複数のセンテンスで構成されている。GPSのNMEAフォーマットのサイトにも書かれているように、各センテンスの末尾には改行コードが入っている。

GPSのNMEAフォーマットの改行説明部分
-『GPSのNMEAフォーマット』より

PythonコードはGPSモジュールから順次送られてくるGPSデータをUartのreadStr処理で次々と読み取っていくが、Uartの読み取り範囲はGPSのセンテンスと一致しない。

Pythonのprint処理は実行後に改行されるため、GPSセンテンスの改行コード以外に、readStr処理で読み取った範囲をprintで画面出力するタイミングでも改行されてしまう。

これをイメージにすると、以下のようになる。

GPSデータとUartのread位置

そこで、printの引数に改行を無効にする end='' を指定することで、画面にはGPSの各センテンスの改行コード部分でのみ改行される。

今回紹介したPythonコードはUartで読み取った結果を文字列として画面表示しているだけである。出力結果をリストに格納する場合、センテンスの頭出しなど、もう少し考慮すべき必要があるだろう。