LoginSignup
3
5

More than 3 years have passed since last update.

ESP32 - MicroPythonにて、GPS受信キットを制御する

Last updated at Posted at 2020-02-09

はじめに

ESP32 - MicroPythonを使い、GPS受信キットから受信方法について記載します。

000.jpg

GPS受信機キット - 1PPS出力付き「みちびき」3機受信対応

今回、秋月電子さんで購入できるGPS受信機キット - 1PPS出力付き「みちびき」3機受信対応を使用します。

以下が主な仕様です。

  • GPSモジュール:GYSFDMAXB(太陽誘電)
  • 搭載GPS受信チップ:MT3339(MediaTek)
  • 受信周波数:1575.42MHz(L1,C/Aコード)
  • 受信チャネル数:66(アクイジション)、22(トラッキング)
  • 対応測位衛星システム:GPS(米国)、QZSS(日本)
  • 受信(トラッキング)感度:-164dBm(typ.)
  • 測位確度:2m(typ.緯経度の水平位置)@-135dBm
  • 出力データ形式:NMEA0183V3.01準拠
  • 測地系:WGS1984(デフォルト)
  • 電源電圧:DC5V(3.8V~12V)/・電源電流:40mA
  • 入出力信号レベル:C-MOSロジック(3.3V)レベル、非同期シリアル信号
  • UART通信速度:9600bps(デフォルト)、4800~115200bps
  • 出力データ更新レート:毎秒1回(デフォルト)、毎秒1~10回出力可
  • 1PPS出力:C-MOSロジック(3.3V)レベル、パルス幅:100mS(アクティブLow)
  • インジケータ:赤色LEDによる通電表示、衛星追尾中(1PPS)表示
  • 基板サイズ:30×30×13.5mm(電池ボックス実装時)
  • 重量:約11g(バックアップ電池装着時)

商品ページへのリンク

!!!本商品は、はんだ付けが必要です。!!!

開発環境

以下が確認した環境となります。

  • ホストPC
    • windows10 64bit Home
    • VSCode - 1.41.1
      • Pymakr 1.1.5
    • NodeJS - 12.14.1 LTS
  • ターゲット
    • MicroPython v1.12 on 2019-12-20; ESP32 module with ESP32

機材

※型名が購入先のリンクになっています。

項目 型名 備考
ESP32-WROOM-32 開発ボード NodeMCU-32S ESP32-WROOM-32 -
GPS受信機キット 秋月電子 -
ダイオード(1N4148) 秋月電子 GPS取説 - 推奨回路に記載
抵抗 10kΩ GPS取説 - 推奨回路に記載
ジャンパーケーブル 指定なし

接続図

SampleGpsfzz_ブレッドボード.png

※今回、「1PPS出力」は使用しないので、未接続になっています。
 評価基板によって、RX2,TX2は、D16, D17と記載されています。

モジュール

GPSモジュールからNMEAフォーマットで送られてきます。

制御文字などが入っているため、パースする必要があります。

調査したところ、micropyGPSというライブラリを使うとできそうなことがわかりました。

inmcm/micropyGPS

ただ、README.mdに下記の記載があります。

ESP32
You can follow the setup instructions for the pyboard.
The only difference is, that you shoud use micropyGPS as a frozen module.
Otherwise there will be exceptions, because there is not enough heap space available.

ヒープが足りなくなるから、"frozen module"として扱ってねとのこと。

コード

動作確認したコードは以下となります。

ファイル名:sample_gps.py

from machine import UART
from micropyGPS import MicropyGPS
import utime, gc, _thread

uart = UART(2, baudrate=9600, timeout=200)
my_gps = MicropyGPS(local_offset=0, location_formatting='dd')

def test():
    n = 0
    mem_free = gc.mem_free()
    tm_last = 0
    while True:
        len = uart.any()
        if len > 0:
            b = uart.read(len)
            for x in b:
                if 10 <= x <= 126:
                    stat = my_gps.update(chr(x))
                    if stat:
                        tm = my_gps.timestamp
                        tm_now = (tm[0] * 3600) + (tm[1] * 60) + int(tm[2])
                        if (tm_now - tm_last) >= 10:
                            print('=' * 20)
                            print(my_gps.date_string(), tm[0], tm[1], int(tm[2]))
                            print("latitude:", my_gps.latitude[0], ", longitude:", my_gps.longitude[0])
                            print("altitude:", my_gps.altitude)
                            print("satellites_used:", my_gps.satellites_used)
                            n += 1
                            tm_last = tm_now
                            if (n % 10) == 0:
                                print("Mem free:", gc.mem_free(), mem_free - gc.mem_free())
                                gc.collect()
        else:
            utime.sleep_ms(100)

testth=_thread.start_new_thread(test, ())

ファイル構成

>>> import os
>>> os.listdir()
['boot.py', 'project.pymakr', 'sample_gps.py', 'micropyGPS.py']

実行結果例

10秒ごとに、printのログが表示されます。
※xxxは伏せています。

>>> import sample_gps
I (58850) uart: ALREADY NULL
>>> ====================
00/00/00 12 59 11
latitude: 36.xxxxxx , longitude: 139.xxx
altitude: 139.5
satellites_used: []
====================
02/09/20 12 59 21
latitude: 36.xxxxxx , longitude: 139.xxx
altitude: 139.5
satellites_used: [3, 1, 193, 30, 8, 194]
====================
02/09/20 12 59 31
latitude: 36.xxxxxx , longitude: 139.xxx
altitude: 139.5
satellites_used: [3, 1, 193, 30, 194]
====================
02/09/20 12 59 41
latitude: 36.xxxxxx , longitude: 139.xxx
altitude: 139.5
satellites_used: [11, 3, 1, 17, 193, 30, 8, 194]

...

気づいたことと

最初の起動は時間がかかる

取説にも記載されていますが、時間がかかります
"40秒~数十分"と記載。
私の場合は、2分ほどかかりました。
受信できるとLEDの点滅で教えてくれます。

各項目の精度について

当たり前かもしれませんが、時刻はきっちり取れています。
緯度経度は、数十~100メートルぐらいといった感じでしょうか。
十分な精度だと思います。
ただ、ログ上は同じ値になっていますが、海抜は安定していない気がします。
40メートル ~ 180メートルの値をとってしまう。

ヒープ領域について

gc.collect()を実施しないと、利用可能なヒープが減っていきます。
上記のコードで、数時間ほど走らせてましたが、
とりあえず落ちることはなかったです。
もう少しエージングして確認しますが、
ダメなら別の方法が必要になるかもしれません。

参考にさせていただいたサイト

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5