Arduinoの基礎 - GPS
概要
ここでは手軽に利用可能なGPSモジュール(NEO-6M)のGPSデータを、Arduinoで読み込み液晶ディスプレイに表示する方法を記載する。
なお、GPSモジュールは、U-blox NEO-6Mを使用している。
このGPSモジュールは、 TTLシリアルインターフェイスを使用してArduinoと簡単に接続できる。
<br
GPSモジュールからGPSデータを取得する
GPSデータは、NMEAプロトコルというデータフォーマットが広く使用されている。
ここで使用するNEO-6Mにおいても、NMEAプロトコルがサポートされている。(NMEAプロトコルについては、後述のセクションを参照する)
GPSモジュールで受信したGPSデータは、UART(TTLシリアル)インターフェイスから直ちに文字列形式で取得できる。
(GPSモジュールとPCを接続してGPSデータを確認する方法は、後述のセクションを参照する)
GPSモジュールのUART(TTLシリアル)から取得できるGPSデータをArduinoで受信して、それをパースすればよい。
NMEAプロトコル
NMEAプロトコルとは
NEO-6M等の多くのGPSモジュールからは、NMEAプロトコルと呼ばれるデータ形式でGPSデータが取得できる。
Arduino等でGPSモジュールを使用する場合は、一般的に、TinyGPS等のライブラリを使用して、NMEAプロトコルを直接解析せずに必要なGPSデータを取得することができる。
しかし、GPSデータを理解することは問題が発生した時の調査等で役に立つことが多いので、ここでは、NMEAプロトコルのGPSデータを確認する。
NMEAプロトコルのGPSデータを取得する
NEO-6Mを使用して、PC(シリアルポート)へ送信されたGPSデータをシリアルモニタ等で見ると、下図のような文字列が取得できる。
下図において、$GPRMCや$GPVTG等の文字に続いて、カンマ区切りでGPSデータが記載されていることが確認できる。
ここでは、例として、$GPRMCの内容を解析する。
$GPRMCは、推奨最小GPSデータである。
$GPRMC,071323.00,A,3348.65406,N,11819.22616,W,0.047,,270716,,,A*6C
1番目のセクションは、071323
とあり、UTC時刻の07:13:23 UTC
であることを示している。
2番目のセクションは、A
とあり、ナビゲーション受信機の警告を表す。A
は"OK"、V
は"警告"である。
3〜4番目のセクションは、3348.65406,N
とあり、緯度を表す。このデータでは、北緯(N) 33度48.65406分である。
5〜6番目のセクションは、11819.22616,W
とあり、経度を表す。このデータでは、西経(W) 118度19.22616分である。
7番目のセクションは、0.047
とあり、地表面に対する速度(ノット)を表す。1ノットは約1.9[km/h]なので、0.047ノットは時速0.09[km/h]程度である。
8番目のセクションは、空である。
9番目のセクションは、270716
とあり、UTC時刻を表す。このデータでは、2016年7月27日(DDMMYY形式)である。
10番目のセクションは、進んでいる向きを表す。このデータでは空である。
11番目のセクションは、NMEAプロトコル 2.3から追加されたモードインジケータを表す。このデータでは空である。
最後の12番目のセクションは、チェックサムである。
以上、$GPRMCの内容から緯度経度とUTC時刻がわかる。
GPSモジュールとPC(シリアルポート)を接続して、GPSデータを確認する
GPSモジュールのGPSデータを、PCのシリアルポートを使用して直接確認する方法を記載する。
ここで使用するのは、NEO-6M GPSモジュールとFTDI FT232RL USB-TTLシリアルアダプタである。
まず、NEO-6Mの入力電圧は、2.7[V]〜3.6[V]の範囲とする必要があるので、FT232RLのジャンパーを設定して3.3[V]にする。
下図左のように、FT232RLとNEO-6Mを、以下のようにそれぞれ接続する。
- FT232RLのGRDとNEO-6MのGRD
- FT232RLのVCCとNEO-6MのVSS
- FT232RLのRXとNEO-6MのTX
- FT232RLのTXとNEO-6MのRX
次に、FT232RLとPCを接続する。
ここでは、シリアルポートターミナルは、gtktermを使用している。ポートは、/dev/ttyUSB0としている。
下図右において、gtktermのウィンドウタイトルにある9600-8-N-1とは、ボーレート(9600[bps])、データビット長(8)、パリティ無し(N)、ストップビット(1)を意味する。
Linuxで使用できるシリアルポートを探すには、FT232RLアダプタとPCを接続した後、以下のコマンドを実行する。
setserial -g /dev/ttyUSB[01234]
もし、シリアルポートにアクセスできない場合は、ユーザをdialoutグループに追加する。
ls -l /dev/ttyUSB0 sudo adduser $USER dialout
サンプルコード
Arduinoでは、GPSデータを解析するためのライブラリは多く存在する。
ここでは、TinyGPS++ライブラリを使用している。
Arduino IDE上でライブラリをzip形式でダウンロードして開発環境に追加するには、
[Sketch] - [Include Library] - [Add .ZIP Library...]からzipファイルを指定する。
または、手動でライブラリをArduino IDEのインストールディレクトリ下のlibrariesディレクトリ内に展開する。
NEO-6MからGPSデータをUARTで受信するには、FT232RLの8番ピン(RX)と9番ピン(TX)をそれぞれ、NEO-6MのTXとRXに接続している。
そして、SoftwareSerialライブラリを使用して、FT232RL(TTLシリアル)からGPSデータを取得する。
サンプルコードは以下の通りである。
SoftwareSerialライブラリのボーレート等が合致しないとデータが正常に受信できないので、動作しない場合は設定を変更すること。
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd( 4, 6, 10, 11, 12, 13 );
const int PIN_RX = 8, PIN_TX = 9;
TinyGPSPlus gps;
SoftwareSerial ss(PIN_RX, PIN_TX);
void setup()
{
lcd.begin(16,2);
lcd.clear();
ss.begin(9600);
}
void loop()
{
while (ss.available() > 0)
{
if (gps.encode(ss.read()))
{
display_coordinate();
}
}
}
void display_coordinate()
{
if (gps.location.isValid())
{
String s;
s = "lat=";
s += String(gps.location.lat(), 6);
lcd.setCursor(0,0);
lcd.print(s);
s = "lng=";
s += String(gps.location.lng(), 6);
lcd.setCursor(0,1);
lcd.print(s);
}
}