PR

ArduinoのライブラリでGPSモジュールで時刻を取得する

組み込みエンジニア
本記事はプロモーションが含まれています。

こんにちは、ENGかぴです。

GPSモジュールは現在地の情報や時刻情報などを衛星からの電波を受信してユーザーに通知するモジュールです。Arduino環境ではGPSモジュールのためのライブラリをインストールすることで時刻データや位置情報を簡単に取得できます。

GPSモジュールのライブラリである「TinyGPSPlus」を使ってGPSモジュールから取得した時刻をシリアルモニタに表示して動作確認しています。GPSモジュールは秋月電子の「GPS受信機キット:AE-GYSFDMAXB」を使っています。ライブラリを使用せずNMEAパケットの仕様に合わせて電文を生成して時刻を表示する方法を下記記事にまとめています。

ArduinoとGPSモジュールで時刻を取得してLCDに表示する

Arduino UNO(以下Arduinoとします。)を対象とします。Arduinoのライブラリを使用して動作確認したことをまとめています。

Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方

GPSモジュール用ライブラリを使用する

ArduinoのIDEの初期ではGPSモジュールに関するライブラリがありません。(あるのかもしれませんが分かりませんでした。)GPSモジュール用のライブラリは複数ありますが今回はTinyGPSPlusライブラリをインストールして使用します。

TinyGPSPlusのインストール

Arduino-ライブラリマネージャでTinyGPSPlusを追加
Arduino-ライブラリマネージャでTinyGPSPlusを追加

Arduino IDEのツール内のライブラリを管理を選択するとライブラリマネージャ画面が表示されます。検索をフィルタに「tinygps」(大文字小文字はどちらでもよい)を入力すると表示される「TinyGPSPlus」が候補として表示されます。インストールボタンを押すとライブラリが追加されます。

ライブラリの準備と初期化

#include <TinyGPSPlus.h>
#include <time.h>
#include <SoftwareSerial.h>

#define PIN_DI1 13

TinyGPSPlus gps; //gpsの情報を格納する変数
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(115200); //シリアルモニタ用
  mySerial.begin(9600); //GPSモジュール用
  pinMode( PIN_DI1, INPUT_PULLUP ); //1pps用のDI
}

ライブラリを使用するためTinyGPSPlus.hをインクルードします。Timer.hは標準関数で時間管理を行う際に使用するためインクルードしています。

Arduino UNOではシリアル通信専用のポートがシリアルモニタを兼ねているためGPSから取得したデータをモニター上に表示するとGPSモジュールに対して通信してしまいます。そのためソフトウェアシリアル(DO・DIポートでシリアルを模擬)を使用してGPSモジュールからデータを取得します。

GPSモジュールのボーレートのデフォルトに合わせてソフトウェアシリアルのボーレートを9600bpsにしています。GPSモジュールが衛星を補足UTC時刻が確定すると1ppsからパルスが出力されます。1ppsのパルス出力をDIで確認するために13ピンをプルアップ付きのDIピンにしています。

PR:スキマ時間で自己啓発!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!

GPSの情報を獲得

void loop() {
  while (mySerial.available()){
    if( gps.encode(mySerial.read())){ //受信した文字を解釈
      GpsTimeRead();
    }
  }
}

encode()関数では受信した文字を解釈していきGPS関係の一連の文字列が取得できるとtrueを返します。GpsTimRead()関数内でGPSモジュールから取得した情報を表示します。

void  GpsTimeRead(void){
  tm t;
  time_t tim;
  tm* ltim;

  if( gps.time.isValid() && gpsok == true){
    t.tm_year = gps.date.year() - 1900;
    t.tm_mon = gps.date.month() - 1; //0からカウントするので-1

    t.tm_hour = gps.time.hour() + 9; //日本:世界標準時から9時間ずれ

    tim = mktime(&t); //UNIX時間からの経過
    ltim = localtime(&tim); //ローカル時間に置き換え

    year = ltim->tm_year + 1900;
    month = ltim->tm_mon + 1;
    Serial.print(year); //年を表示

    if (gps.location.isValid() && gpsok == true){
      gpsok = false;
      Serial.print(gps.location.lat(), 6); //経度
      Serial.print(",");
      Serial.println(gps.location.lng(), 6); //緯度
  }
}

time.isValid()で時刻情報の取得を確認します。例では日付データから先に取得してtmの型の変数tに格納しています。dateではyear(年)・month(月)・day(日)を取得します。timeではhour(時)・minite(分)・second(秒)を取得します。

GPSモジュールから取得できる時間は世界標準時なので日本時間に直すと+9時間する必要があります。+9時間によりあり得ない時間になることを防ぐためmktime()関数を使用します。

mktime()はUNIX時間(1970年1月1日0時0分0秒)からの経過時間を時刻の桁上がりなどを考慮しての補正を行いtime_tの型で戻り値として格納できる関数です。

localtime()はtime_tの型のUNIX時間をtmの型(年・月・日・時・分・秒に分けてtmの型に変換する関数です。

location.isValid()で位置情報の取得を確認します。location.lat()で経度、location.lng()で緯度が取得できます。

時刻の繰り上がりによる計算の煩雑さを回避するためmktime()を使用してUNIX時間からの経過時間を補正しlocaltime()で日時分秒などを分割して表示すると楽に時刻を管理できます。

PR:(即戦力のスキルを身に着ける:DMM WEBCAMP 学習コース(はじめてのプログラミングコース))

動作確認

GPSモジュール動作確認の回路図
GPSモジュール動作確認の回路図

GPSモジュールからの受信データをシリアルモニタに表示するための回路図です。GPSモジュールが測位を完了して時刻や位置情報が確定すると1ppsのパルス出力が1秒毎に出力します。このタイミングでシリアルモニタに表示時刻を表示しています。

GPSモジュールから時刻情報を取得した結果
GPSモジュールから時刻情報を取得した結果

動作確認する際は位置情報の表示をコメントアウトしているためシリアルモニタに表示していませんが、位置情報をGoogle Map上で座標を入力すると最大で100m程度の誤差が出ることもありましたが位置情報が取得できていました。

PR:あなたのキャリアのお供に「生涯学習のユーキャン」

ソースコード全体

ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。

リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。

ソースコードをダウンロード

TinyGPSPlusライブラリを使用せずNMEAパケットの仕様に合わせて電文を生成して時刻を表示する方法を下記記事にまとめています。

ArduinoとGPSモジュールで時刻を取得してLCDに表示する

関連リンク

Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。

Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方

Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方

ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方

PR: わからないを放置せず、あなたにあったスキルを身に着けるコツを教える テックジムPython入門講座の申込

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました