GPSを利用する
GPSとは
概要
GPSとは、Global Positioning System=地球全体で場所を測定するためのシステムです。地球を周回する複数の人工衛星が発信する電波を利用して現在位置を知ることができます。1970年代よりアメリカ合衆国の国防総省によって開発が開始されました。しばらくは米軍だけが試験的に利用していましたが、1993年までに24個以上の衛星が打ち上げられて正式運用が開始されました。
運用開始当初は他国・民間向けには乱数で変調された信号が用いられ、取得できる位置情報がわざと低い精度に制限されていましたが、2000年より制限が解除され、民間用の機器でも実用上充分な精度を得られるようになりました。
現在は民間用の安価な機器でも誤差10m程度で位置が取得できるようになり、スマートフォンやデジタルカメラにもGPSの受信器が装備されて広く活用されています。
原理
GPSにより現在位置を知る基本原理は、実はそれほど難しくありません。
GPS衛星は、定期的に自身の軌道情報および搭載された原子時計による時刻を電波により発信しています。\(i\)番目の衛星からの電波を受信した受信者は、その内容から、
電波が発信されたときの衛星の位置 \((X_{Si},\ Y_{Si},\ Z_{Si})\)
発信時刻 \(T_{Si}\)
を知ることができます。
このとき、\(i\)番目の衛星と受信者との距離 \(d_i\) は、受信者の位置を \((x,\ y,\ z)\) とすると、
\[d_i=\sqrt{(X_{Si}-x)^2+(Y_{Si}-y)^2+(Z_{Si}-z)^2}\]
となります。また、電波は光速で伝わるので、衛星から受信者まで電波が届くのにかかる時間を考えると、光速を \(c\) として
\[d_i=c(t-T_{Si})\]
と表すこともできます。この2つの\(d_i\)は当然同じ値のはずなので、
\[c(t-T_{Si})=\sqrt{(X_{Si}-x)^2+(Y_{Si}-y)^2+(Z_{Si}-z)^2}\]
という式を得ることが出来ます。
この式について、受信者が原子時計など正確な受信時刻 \(t\) を知る手段を持っていれば未知数は座標 を表す \((x,\ y,\ z)\) の3つ、原子時計を持っていなければ \(t\) も含めた4つとなります。
よって、原子時計を持っている場合は3つの衛星からの情報(\(X_{Si},\ Y_{Si},\ Z_{Si},\ T_{Si}\))を得ることが出来れば、それらによって得られる3つの式を連立させて位置 \((x,\ y,\ z)\) を求めることができ、原子時計がなくても4つの衛星からの情報を得ることが出来れば位置 \((x,\ y,\ z)\) および \(t\) を求めることが出来るのです。
以上はもっとも基本的な原理ですが、さらにアンテナを複数利用するなどして誤差1cm以下の測定を行うこともできます。
他にもいろいろな原理で測定精度を上げているのですが、話が難しくなるので割愛します(実はブログ主にもよく判っていません…)。
一般人が原子時計を持ち歩くのは困難なので、4つ以上の衛星からの電波を受信できないと位置及び時刻を取得することができません。現在は6軌道平面に各4機以上の衛星が配置されており、上空がひらけていれば常に6機以上の衛星からの電波を受信可能です。逆にビルの谷間など空がほとんど見えない状態・屋内で窓側からしか電波を受信できない状態での測定は困難です。トンネル内などまったく空が見えない環境では測定ができません。
なお、座標および時刻の計算はGPSレシーバーモジュールがやってくれる場合が多いので、マイコン側で計算するプログラムを作る必要はほぼありません。まぁ一般常識として一応知っておこう、ということで。
GPSレシーバーモジュール GY-NEO6MV2
今回は安価なGPSレシーバーモジュール GY-NEO6MV2 を使用します。
僕が入手したのは、モジュールの基板とアンテナのセットでした(写真左がアンテナ)。入手価格は750円です。この写真だと基板奧側にあるホールにピンヘッダを半田付けして使うのがよいと思いますが、このセットにはピンヘッダが添付されていませんでした。ブログ主の手元にはピンヘッダのストックがあったので問題ないのですが、これから購入する方はご注意を。
このレシーバーモジュールの使い方は非常に簡単です。電源を接続するとすぐ9600bpsのシリアル通信でENMAフォーマットのデータが繰り返し送信されてきますので、マイコン側でそれを受信するだけです。初期設定も、データ送信要求などもする必要はありません。
制作
回路
シリアル通信なので、電源(VCC、GND)と信号(上り・下り)を接続するだけです。チップのデータシートによるとGY-NEO6MV2の電源は 2.7~3.6V ですが、基板上に低損失3端子レギュレータが実装されているのでVCC端子には5Vを供給して大丈夫なようです。それなら入出力のレベルはどうなんだ?5Vと3.3Vのロジックレベル変換モジュールを挟んだ方がいいのか?という気もしますが、今回はなしで試してみます。
PCともUSB接続したままで動作テストをしたいので、例によってArduino側のデータ端子はD0とD1を避けて、D2をArduino側のRX、D3をArduino側のTXとしました。
判っている人にはいわずもがなですが、TX同士・RX同士をつなぐのではなく、Arduino側のTXとGPSモジュール側のRX、Arduino側のRXとGPSモジュール側のTXを接続します。
配線
配線もシンプルです。ジャンパ線4本で接続するだけです。
写真ではブレッドボードを使用しています。
プログラム
今回のプログラムはGPSモジュールの動作確認だけのもので実用性はまったくありません…。
ソースコード
#include "SoftwareSerial.h"
#define GPS_TX 2
#define GPS_RX 3
SoftwareSerial gpsSerial(GPS_TX, GPS_RX);
void setup() {
Serial.begin(115200);
gpsSerial.begin(9600);
delay(1000);
}
void loop() {
if(gpsSerial.available()>0){
Serial.write(gpsSerial.read());
}
}
プログラムの解説
ライブラリのインクルード
#include "SoftwareSerial.h"
GPSモジュールとはシリアル通信を行いますので、SoftwareSerial.h をインクルードします。
端子の設定
#define GPS_TX 2
#define GPS_RX 3
GPSモジュールとの接続には2番と3番の端子を使用します。Arduino側のRX(GPSのTXと接続)はD2、Arduino側のTX(GPSのRXと接続)はD3です。
SoftwareSerialオブジェクトの生成
SoftwareSerial gpsSerial(GPS_TX, GPS_RX);
SoftwareSerialクラスのオブジェクト gpsSerial を生成しています。
シリアル通信の初期化
void setup() {
Serial.begin(115200);
gpsSerial.begin(9600);
delay(1000);
}
NMEA機器の通信規格は4800bpsなのですが、このGY-NEO6MV2モジュールのデフォルト速度は9600bpsです。gpsSerial.begin(9600) で通信速度を設定しています。
loop()関数
void loop() {
if(gpsSerial.available()>0){
Serial.write(gpsSerial.read());
}
}
loop()関数内では、gpsSerialから受信した内容をそのままSerialに書き出しています。PCのArduino IDE上のシリアルモニタなどで動作を確認できます。
動作
はじめて使用したときは、衛星を補足して測定が始まるまでに数十分かかることもあるようですが、通信自体は通電直後から行われます。
下の写真のようにNMEAフォーマットの文字列ではありますが、まだ測定が出来ていないのでほとんどのフィールドが空欄になっています。
とはいえ、これで一応モジュールが正常に動作していることは確認できました。
屋内では電波が弱く、窓際でギリギリ電波をとれるか…?という感じでした。拙宅にベランダでもあればよかったのですが…。
いずれバッテリーで駆動できるようにして屋外に持ち出して試してみます。
コメント