ホーム > カテゴリ > ロボット・電子工作・マイコン >

みちびき対応のGPS受信機(GYSFDMAXB)の使い方 [Arduino]

スマホなどでお馴染みのGPS(Global Positioning System)は「全地球測位システム」と呼ばれ、現在地の「緯度、経度」などの位置情報を取得する事が可能です。

次の動画は4衛星以上を追尾している「三次元測位中」(3D-Fix)の状態です。この赤いLEDが点滅している状態を15分以上維持することにより、安定した位置情報を得る事ができます。

[スケッチ1の実行例] - GPSのセンテンス(NMEAフォーマット)の表示

[スケッチ2の実行例] - 時刻、緯度、経度、海抜の表示

目次

1. 使用部品・材料
2. 配線図
3. スケッチ1(GPSセンテンスの表示)
4. スケッチ2(時刻、緯度、経度、海抜の表示)
5. 緯度経度について
6. Googleマップの座標フォーマット
7. Googleマップで2点間の距離を測定する
8. 日本の東西南北の緯度経度
9. NMEAフォーマット

1. 使用部品・材料

総額で約2,470円です。(Arduino本体の値段を除く)

部品/材料値段備考
ブレッドボード¥270秋月電子の通販コード(P-00315)
GPS受信機キット 1PPS出力付き 「みちびき」対応 GYSFDMAXB¥2200秋月電子の通販コード(K-09991)
汎用小信号高速スイッチング・ダイオード 1N4148 100V200mA
1本
数円秋月電子の通販コード(I-00941)
カーボン抵抗器数円10kΩ(1個)を使用。

2. 配線図

今回はUART通信にSoftwareSerial(2ピン/3ピン)を使用しています。

GPS受信機の「GYSFDMAXB」(MT3339)の接続方法は秋月電子の取扱説明書の記載通りです。

GYSFDMAXBの入出力信号レベルが3.3Vですので、スイッチングダイオードを使用して、Arduinoからの5V送信(TX)を止めています。その代わりに3.3Vの電圧を10kΩを通してかけています。

バックアップ電池を装着後、取扱説明書に記載されている「初期動作テスト」を必ず行ってください。(目安:合計30分)

3. スケッチ1 - GPSセンテンスの表示

シリアルモニターに「GPSのセンテンス」を表示します。
※シリアルモニターの通信速度は115200bpsにして下さい。

#include <SoftwareSerial.h>

// rxPin = 2  txPin = 3
SoftwareSerial mySerial(2, 3);

void setup() {
  mySerial.begin(9600);
  Serial.begin(115200);
}
void loop() {
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
}

4. スケッチ2 - 時刻、緯度、経度、海抜の表示

シリアルモニターに現在の「時刻、緯度、経度、海抜」を表示します。
※シリアルモニターの通信速度は115200bpsにして下さい。

#include <SoftwareSerial.h>

// rxPin = 2  txPin = 3
SoftwareSerial mySerial(2, 3);

// NMEAの緯度経度を「度分秒」(DMS)の文字列に変換する
String NMEA2DMS(float val) {
  int d = val / 100;
  int m = ((val / 100.0) - d) * 100.0;
  float s = ((((val / 100.0) - d) * 100.0) - m) * 60;
  return String(d) + "度" + String(m) + "分" + String(s, 1) + "秒";
}

// (未使用)NMEAの緯度経度を「度分」(DM)の文字列に変換する
String NMEA2DM(float val) {
  int d = val / 100;
  float m = ((val / 100.0) - d) * 100.0;
  return String(d) + "度" + String(m, 4) + "分";
}

// NMEAの緯度経度を「度」(DD)の文字列に変換する
String NMEA2DD(float val) {
  int d = val / 100;
  int m = (((val / 100.0) - d) * 100.0) / 60;
  float s = (((((val / 100.0) - d) * 100.0) - m) * 60) / (60 * 60);
  return String(d + m + s, 6);
}

// UTC時刻から日本の標準時刻に変換する(GMT+9:00)
String UTC2GMT900(String str) {
  int hh = (str.substring(0,2).toInt()) + 9;
  if(hh > 24) hh = hh - 24;

  return String(hh,DEC) + ":" + str.substring(2,4) + ":" + str.substring(4,6);  
}

void setup() {
  mySerial.begin(9600);
  Serial.begin(115200);
}
void loop() {
  // 1つのセンテンスを読み込む
  String line = mySerial.readStringUntil('\n');

  if(line != ""){
    int i, index = 0, len = line.length();
    String str = "";
  
    // StringListの生成(簡易)
    String list[30];
    for (i = 0; i < 30; i++) {
      list[i] = "";
    }

    // 「,」を区切り文字として文字列を配列にする
    for (i = 0; i < len; i++) {
      if (line[i] == ',') {
        list[index++] = str;
        str = "";
        continue;
      }
      str += line[i];
    }
    
    // $GPGGAセンテンスのみ読み込む
    if (list[0] == "$GPGGA") {
      
      // ステータス
      if(list[6] != "0"){      
        // 現在時刻
        Serial.print(UTC2GMT900(list[1]));
        
        // 緯度
        Serial.print(" 緯度:");
        Serial.print(NMEA2DMS(list[2].toFloat()));
        Serial.print("(");
        Serial.print(NMEA2DD(list[2].toFloat()));
        Serial.print(")");

        // 経度
        Serial.print(" 経度:");
        Serial.print(NMEA2DMS(list[4].toFloat()));
        Serial.print("(");
        Serial.print(NMEA2DD(list[4].toFloat()));
        Serial.print(")");

        // 海抜
        Serial.print(" 海抜:");
        Serial.print(list[9]); 
        list[10].toLowerCase();
        Serial.print(list[10]); 
      }else{
        Serial.print("測位できませんでした。");
      }
      
      Serial.println("");
    }
  }
}

GPSのセンテンスはCSV形式ですので「,」を区切り文字としてStringList(文字列リスト)を生成します。後は、StringListから緯度、経度などを取り出して、標準的な形式に変換しています。

Googleマップでは「緯度、経度」の誤差を確認できます。(5章-7章参照)。地理院地図(国土地理院)では「標高」(海抜)の誤差を確認可能です。

5. 緯度経度について

緯度赤道(0度)を基準として南(S)または北(N)へ90度を表す。
経度イギリスのグリニッジ子午線(0度)を基準に東(E)または西(W)へ180度を表す。

緯度、経度は「度分秒」や「度」(10進数)などで位置を表します。

例えば、皇居(Googleマップ)の 緯度は35度41分06.6秒(35.685178)、経度は139度45分10.1秒(139.752804)となります。

※1度 = 60分 = 3600秒。1度の1/60が1分で1分の1/60が1秒となります。

6. Googleマップの座標フォーマット

Googleマップで「緯度, 経度」を入力して位置を検索するには、次の3つの書式を使用できます。※3つとも同じ座標となります。

緯度, 経度
度分秒(DMS)41°24'12.2"N, 2°10'26.5"E
度分(DMM)41 24.2028, 2 10.4418
度(DD)41.40338, 2.17403

※「度 = °」「分 = '」「秒 = "」

7. Googleマップで2点間の距離を測定する

マップを右クリックで表示されるポップアップメニューで「距離を測定」で計測できます。2点間の距離を測る事ができますので、GPSにどれくらいの誤差があるかを確認できます。

8. 日本の東西南北の緯度経度

緯度経度
最北端(北海道択捉島)45度33分26秒148度45分08秒
最南端(東京都沖ノ鳥島)20度25分31秒136度04分11秒
最東端(東京都南鳥島)24度16分59秒153度59分11秒
最西端(沖縄県与那国島)24度26分58秒122度56分01秒

※国土地理院が公表している日本の最東西南北の座標です。若干、座標がずれてる模様です。

9. NMEAフォーマット

UART通信でGPS受信機からマイコンなどへ送信されるデータはNMEA(NMEA0183)フォーマットです。このNMEAフォーマットは「$GPGGA」や「$GPRMC」などの1行のセンテンスの集合体です。

※センテンスは日本語では「文」という意味です。また、1センテンスは1行で行端は必ず改行コード(¥r¥n)となります。

センテンスの例

$GPGGA,135250.000,3541.123,N,13945.123,E,1,4,1.75,31.7,M,39.5,M,,*65
$GPGLL,3541.123,N,13945.123,E,135250.000,A,A*5D
$GPGSA,A,3,07,29,193,06,,,,,,,,,1.98,1.75,0.92*3B
$GPGSV,4,1,13,02,86,273,,193,83,346,26,05,56,315,16,50,48,170,*48
$GPGSV,4,2,13,06,40,135,30,13,40,216,16,30,34,112,,07,28,069,32*7A
$GPGSV,4,3,13,29,21,309,28,20,14,284,,09,13,045,,19,04,175,*78
$GPGSV,4,4,13,15,04,229,*42
$GPRMC,135250.000,A,3541.123,N,13945.123,E,0.25,71.12,140617,,,A*5D
$GPVTG,71.12,T,,M,0.25,N,0.47,K,A*0C
$GPZDA,135250.000,14,06,2017,,*51

センテンスの一覧

次はGYSFDMAXBのデフォルトで出力されるセンテンスです。

$GPGGAGPS位置情報
$GPGLL地理的位置 - 緯度/経度
$GPGSADOP及びアクティブ衛星
※DOP(Dilution Of Precision)はGPSの精度低下率です。
$GPGSV衛星情報
$GPRMC最小ナビゲーション情報(推奨?)
$GPVTG針路と速度
$GPZDA時刻と日付(UTC)

$GPGGA

GPS位置情報

番号内容
1世界協定時(UTC)の時刻。hhmmss.sss形式
2緯度。ddmm.mmmm形式
3北緯(N) or 南緯(S)
4経度。dddmm.mmmm形式。
5東経(E) or 西経(W)
6GPS品質。
0:測位不可 1:GPS 2:DGPS
7使用衛星数。
8HDOP値(水平方向の精度)
9アンテナの海抜高度
10アンテナの海抜高度の単位
11ジオイド高度
12ジオイド高度の単位
13DGPSデータの時間。
※この項目は私の環境では常に空でした。
14DGPS基準局ID。
※この項目は私の環境では存在しません。
15チェックサム

$GPGLL

地理的位置 - 緯度/経度

番号内容
1緯度。ddmm.mmmm形式
2北緯(N) or 南緯(S)
3経度。dddmm.mmmm形式。
4東経(E) or 西経(W)
5世界協定時(UTC)の時刻。hhmmss.sss形式
6ステータス。
A:データ有効 V:データ無効
7モード。
A:単独測位 D:DGPS N:データ無効
8チェックサム

※私の環境では7と8の間に「,」がなく繋がっていました。

$GPGSA

DOP及びアクティブ衛星

番号内容
12D/3D切り替えモード。
M:手動 A:自動
2測位モード。
1:測位なし 2:2D 3:3D
3-14使用している衛星番号。
※最大12個の衛星が出力されます。ない場合は空です。
15PDOP値(位置精度)
16HDOP値(水平精度)
17VDOP値(垂直精度)
18チェックサム

※私の環境では17と18の間に「,」がなく繋がっていました。

GPGSV

衛星情報

番号内容
1このGPGSVセンテンスの総数。
2このGPGSVセンテンスの番号。
3現在位置から受信可能な衛星数。
41個目の衛星番号。
※みちびきは「193」。
※ひまわり6号は「129」(42)。
※ひまわり7号は「137」(50)。
51個目の衛星仰角。00から99度
61個目の衛星方位角。000から359度
71個目の衛星のSNR in dB。00から99dBHz
8-112個目の衛星(4-7と同じ項目)
12-153個目の衛星(4-7と同じ項目)
16-194個目の衛星(4-7と同じ項目)
20チェックサム

※初期時などは一部項目が省略されるようです。(「,」も省略)

$GPRMC

最小ナビゲーション情報(推奨?)

番号内容
1世界協定時(UTC)の時刻。hhmmss.sss形式
2ステータス。
A:データ有効 V:データ無効
3緯度。ddmm.mmmm形式
4北緯(N) or 南緯(S)
5経度。dddmm.mmmm形式。
6東経(E) or 西経(W)
7地表の移動速度(ノット)。000.0から999.9ノット
※1ノット=1852m/h
8真方位(真北は0度)。000.0~359.9度
9世界協定時(UTC)の日付。ddmmyy形式
10磁気偏差
※この項目は私の環境では常に空でした。
11磁気偏差方向
※この項目は私の環境では常に空でした。
12モード。
A:単独測位 D:DGPS N:データ無効
13チェックサム

※私の環境では12と13の間に「,」がなく繋がっていました。

$GPVTG

針路と速度

番号内容
1真方位(真北は0度)。000.0~359.9度
2常にT
3磁気方位(磁北は0度)。000.0~359.9度
4常にM
5地表の移動速度(ノット)。000.0から999.9ノット
※1ノット=1852m/h
6常にN
7地表の移動速度(km/h)。
8常にK
9モード。
A:単独測位 D:DGPS N:データ無効
10チェックサム

※私の環境では9と10の間に「,」がなく繋がっていました。

$GPZDA

時刻と日付(UTC)

番号内容
1時刻。hhmmss.sss形式
2日。dd形式
3月。mm形式
4年。yyyy形式
5???
※この項目は私の環境では常に空でした。
6チェックサム

※この時刻、日付は世界協定時(UTC)です。

最後に

今回は「海抜」が含まれる$GPGGAを使用しました。各フォーマットの簡易的な解説を記載しましたので色々と試してみると良いと思います。

測位の精度に関しては屋内(2F)でしか観測していませんが、誤差は3m-5m程度のようです。屋外の場合はもう少し精度が良いと思います。





掲示板

ArduinoやRaspberry Piなどの電子工作の掲示板を作成しました。質問やわからない事は電子工作 (Arduino・ラズパイ等)でユーザー同士で情報を共有して下さい。

関連記事



公開日:2017年06月16日 最終更新日:2017年06月18日
記事NO:02422