Arduinoで遊ぼう - GPSで現在位置を取得する
Posted by arms22 on 2010年02月04日

SparkFun Electronicsの32 Channel LS20031 GPS 5Hz Receiverはアンテナ内蔵型の32チャンネルGPSモジュールで秒間最大5回、位置情報を出力する。消費電流が3.3V動作時に41mAと少なくバッテリー動作に最適のGPSモジュールだ。サイズも30x30mmとかなり小さい。
このモジュールの仕様は次の通り。
- MediaTek MT3318チップ搭載
- シリアルインターフェース
- 32チャンネル対応
- 秒間最大5回更新
- ホットスタート2秒
- コールドスタート32秒
- 動作電圧3V~4.2V、消費電流41mA
- 外形30x30mm
今回、このGPSモジュールから送られてくる位置情報をArduino経由して、パソコンに取り込んでみるよ。
※LS20031はスイッチサイエンスで取り寄せてもらいました。入荷までに少し時間がかかるけど、送料が気になる人は取り寄せてもらうといいよ。
LS20031のピンアサイン

このGPSモジュールはワイヤが接続されていませんが、パッドの間隔が2.54mmなので十分手で半田付けできます。
Arduinoに接続する


GPSモジュールとArduinoは次のように接続する。
3.3V --> VCC端子例によって5V動作のArduinoと接続する時は、3番 --> RX端子の間に抵抗(R1=1.8KΩ、R2=3.3KΩ)を入れて接続する。
2番 <-- TX端子
3番 --> RX端子
GND --> GND端子
ライブラリをインストールする
GPSモジュールとの通信にはソフトウェアシリアルを利用する。その為、次のURLからソフトウェアシリアルライブラリをダウンロードしてください。Arduinoのハードウェアシリアル(0番、1番)はパソコンとの通信に使用する。
Arduiniana - NewSoftSerial
http://arduiniana.org/libraries/newsoftserial/
ダウンロードして解凍したフォルダを~/Documents/Arduino/librariesフォルダにコピーしてください。librariesフォルダがない場合は新しく作成してください。
サンプルスケッチ
#include <NewSoftSerial.h>
#include <ctype.h>
NewSoftSerial gps(2,3);
void setup()
{
Serial.begin(9600);
delay(2000);
auto_detect_baud_rate();
send_pmtk_packet("PMTK220,1000");
send_pmtk_packet("PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
send_pmtk_packet("PMTK251,9600");
auto_detect_baud_rate();
}
void loop()
{
if(gps.available()){
Serial.print((char)gps.read());
}
}
void auto_detect_baud_rate(void)
{
const unsigned int bauds[] = {
57600, 38400, 28800, 14400, 9600, 4800 };
Serial.print("auto detect... ");
for(int i=0; i<(sizeof(bauds)/sizeof(bauds[0]));i++){
int p = 0;
int r = 0;
gps.begin(bauds[i]);
gps.flush();
do{
if(gps.available()){
if(isprint(gps.read())){
p++;
}
r++;
}
}
while(r < 20);
if(p > 15){
Serial.print(bauds[i]);
Serial.println(" ok");
return;
}
delay(100);
}
Serial.println("fail");
while(1);
}
void send_pmtk_packet(char *p)
{
uint8_t checksum = 0;
gps.print('$');
do {
char c = *p++;
if(c){
checksum ^= (uint8_t)c;
gps.print(c);
}
else{
break;
}
}
while(1);
gps.print('*');
gps.println(checksum,HEX);
}
setup()でGPSモジュールにいくつかのコマンドを送信します。
位置情報の出力間隔をミリ秒で指定します。
PMTK220,1000
出力する位置情報の種類を設定します。RMC(Recommended Minimum Specific GNSS Data)とGGA(Global Positioning System Fix Data)。
PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
ボーレートを設定します。
PMTK251,9600
※注意※
このスケッチではgpsとのシリアル通信のボーレートを自動検出しています。このGPSモジュールのデフォルトのボーレートは9600bpsとデーターシートに書かれていますが、実際には57600bpsでした。他にも38400bpsだったりすることもあるみたいなので、自動検出できるようにしています。時々、間違ったボーレートにしてしまうので、予めボーレートが分かっている場合は、自動検出を使わず、直接ボーレートを指定してください。
loop()でgpsが出力したデータをパソコン側に送信します。シリアルモニタを開くと次のような文字列が送られてきます。これらの文字列はNMEA-0186フォーマットと呼ばれています。カンマで区切られた数値が測位時刻、経度、緯度、対地速度、進行方向などの情報です。詳しくは下記、URLを参照してください。
NMEA-0183フォーマット
http://bg66.soc.i.kyoto-u.ac.jp/forestgps/nmea.html
$GPRMC,145059.000,V,3445.7660,N,13531.3476,E,0.00,0.00,030210,,,N*78
$GPGGA,145100.000,3445.7663,N,13531.3474,E,0,1,,41.5,M,34.3,M,,*74
$GPRMC,145100.000,V,3445.7663,N,13531.3474,E,0.00,0.00,030210,,,N*74
$GPGGA,145101.000,3445.7655,N,13531.3480,E,0,1,,41.5,M,34.3,M,,*7B
$GPRMC,145101.000,V,3445.7655,N,13531.3480,E,0.00,0.00,030210,,,N*7B
$GPGGA,145102.000,3445.7656,N,13531.3479,E,0,1,,41.5,M,34.3,M,,*7D
$GPRMC,145102.000,V,3445.7656,N,13531.3479,E,0.00,0.00,030210,,,N*7D
$GPGGA,145103.000,3445.7653,N,13531.3481,E,0,1,,41.5,M,34.3,M,,*7E
$GPRMC,145103.000,V,3445.7653,N,13531.3481,E,0.00,0.00,030210,,,N*7E
$GPGGA,145104.000,3445.7660,N,13531.3476,E,0,1,,41.5,M,34.3,M,,*71
この文字列をGoogle Mapコンバータに入力するとGoogle Map上にその位置が表示されるよ。GPS NMEA data to Google Map converter
http://www.gonmad.co.uk/nmea.php
電源投入直後、GPSモジュールから有効な位置情報が送られてくるまでに30秒以上かかります。空が見えるベランダにモジュールを出してしばらく待ちましょう。モジュールが衛星を補足し、有効な位置情報を送りだすとモジュール上のLEDが1秒間隔で点滅します。
SparkFun Electronics - 32 Channel LS20031 GPS 5Hz Receiver
http://www.sparkfun.com/commerce/product_info.php?products_id=8975
Leadtek NMEA Protocol Manual for MTK
ftp://ftp.leadtek.com.tw/gps/9023/LeadtekNMEAProtocolManualforMTKV1.0.pdf
Ads by Google
18 Comments
いつも楽しく拝見させていただいております。
さて、今回NewSoftSerialを利用されて、
NewSoftSerial gps(2,3);とありますので、
D2・・・RX(割り込みベース)
D3・・・TX
でご使用されていることと思います。
ところで当方の環境ArduinoUNOでは、D2(INT0)が他のシステムからの外部割込みに使用しているため、D3(INT1)をRXとして使用し、TXは例えばD9などの適当なポートに移し、
すなわちサンプルスケッチのところを
NewSoftSerial gps(3,9);
とするだけで問題ないでしょうか。
恐縮ですが、教えていただけますと幸いです。
どうぞよろしくお願いいたします。
さて、今回NewSoftSerialを利用されて、
NewSoftSerial gps(2,3);とありますので、
D2・・・RX(割り込みベース)
D3・・・TX
でご使用されていることと思います。
ところで当方の環境ArduinoUNOでは、D2(INT0)が他のシステムからの外部割込みに使用しているため、D3(INT1)をRXとして使用し、TXは例えばD9などの適当なポートに移し、
すなわちサンプルスケッチのところを
NewSoftSerial gps(3,9);
とするだけで問題ないでしょうか。
恐縮ですが、教えていただけますと幸いです。
どうぞよろしくお願いいたします。
> NewSoftSerial gps(3,9);
> とするだけで問題ないでしょうか。
試した事はりませんが、
それで問題ないと思います。
> とするだけで問題ないでしょうか。
試した事はりませんが、
それで問題ないと思います。
ありがとうございました!
よく拝見させていただいています。
こちらを参考に実装してみたのですが、見慣れないエラーが出てしまったので、対処法が分かりましたら、おしえていただけますでしょうか?
・環境
Mac OSX 10.6
Arduino UNO
・症状
NewSoftSerialをインストールして、指定フォルダにコピーした後に以下のようなコンパイルエラーが表示される。
In file included from sketch_aug17a.cpp:1:
/Documents/Arduino/libraries/NewSoftSerial/NewSoftSerial.h:33:2: error: #error NewSoftSerial has been moved into the Arduino core as of version 1.0. Use SoftwareSerial instead.
In file included from sketch_aug17a.cpp:1:
/Documents/Arduino/libraries/NewSoftSerial/NewSoftSerial.h:99: error: conflicting return type specified for 'virtual void NewSoftSerial::write(uint8_t)'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
こちらを参考に実装してみたのですが、見慣れないエラーが出てしまったので、対処法が分かりましたら、おしえていただけますでしょうか?
・環境
Mac OSX 10.6
Arduino UNO
・症状
NewSoftSerialをインストールして、指定フォルダにコピーした後に以下のようなコンパイルエラーが表示される。
In file included from sketch_aug17a.cpp:1:
/Documents/Arduino/libraries/NewSoftSerial/NewSoftSerial.h:33:2: error: #error NewSoftSerial has been moved into the Arduino core as of version 1.0. Use SoftwareSerial instead.
In file included from sketch_aug17a.cpp:1:
/Documents/Arduino/libraries/NewSoftSerial/NewSoftSerial.h:99: error: conflicting return type specified for 'virtual void NewSoftSerial::write(uint8_t)'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
連投失礼いたします。NewSoftSerial はArduino1.0以降に対応していないそうですね。。
1.0以降の場合はどのようにスケッチすれば良いか分かりますでしょうか。何卒、よろしくお願いいたします。
1.0以降の場合はどのようにスケッチすれば良いか分かりますでしょうか。何卒、よろしくお願いいたします。
NewSoftSerialをSoftwareSerialに変えて試してみてください。
このコメントは管理人のみ閲覧できます
特定の信号発信源をカメラで追尾するってことかな?
GPSじゃなくてもよさそうだけど。
発信器側がGPS情報を受信側に送ってるんじゃない?
GPSじゃなくてもよさそうだけど。
発信器側がGPS情報を受信側に送ってるんじゃない?
GPSモジュールからのデータで サーボを制御したいのですが
登録された 緯度経度高度を 基に その物が どの方向にあるか
サーボに矢印当を付け 示したいのですが 測定機が どこに置かれていても 登録地点を 直線所に示す Arduino スケッチ 教えていただけな
いでしょうか 2個のサーボで 仰角 旋回 で 方向を示すようにした。いのです
登録された 緯度経度高度を 基に その物が どの方向にあるか
サーボに矢印当を付け 示したいのですが 測定機が どこに置かれていても 登録地点を 直線所に示す Arduino スケッチ 教えていただけな
いでしょうか 2個のサーボで 仰角 旋回 で 方向を示すようにした。いのです
このコメントは管理人のみ閲覧できます
LS20031の電源を3.3Vにしているので、5Vを印加しないように抵抗で分圧してRX端子に信号を入れています。
私が買ったLS20031はボーレートが115200bpsだそうです。そこで、bauds[]のところに115200を追加してこのサイトで紹介されているのと同じ配線で試したのですが、auto detect...と表示された後何も表示されません。LS20031のランプは点滅しているので、信号は受信できているようです。何が間違っているのでしょうか?
まず簡単なスケッチをかいてGPSからデータを受信できているか確認してみてください。
OKそうなら
auto_detect_baud_rate();
を削除して下記に変えてみてください。
gps.begin(115200);
OKそうなら
auto_detect_baud_rate();
を削除して下記に変えてみてください。
gps.begin(115200);
やはりうまくいきません。今回は何も表示されません。こちらのサイト
https://www.sparkfun.com/tutorials/176
のquick testというのはうまくいったのですが、Using the TinyGPS libraryのところではうまくいきません。quck testでデータの表示ができたので、信号の受信はできているはずなのですが。
https://www.sparkfun.com/tutorials/176
のquick testというのはうまくいったのですが、Using the TinyGPS libraryのところではうまくいきません。quck testでデータの表示ができたので、信号の受信はできているはずなのですが。
NewSoftSerialのかわりにSoftwareSerialを使ってみてください。
http://arduino.cc/en/Reference/softwareSerial
それとRX/TXは2/3番ピンになるので実際の配線もあわせてください。
http://arduino.cc/en/Reference/softwareSerial
それとRX/TXは2/3番ピンになるので実際の配線もあわせてください。
このコメントは管理人のみ閲覧できます
Leave a reply
該当の記事は見つかりませんでした。