GPSモジュール(LS20031)
今回は度と分で構成される座標情報を抽出し、度だけに単位変換するプログラムについてみてみたいと思います。
1. プログラム
前回もご紹介致しましたが「度」と「分」であらわされたGPSの座標「例:北緯35度42.6023分、東経139度48.6436分等」を計算しやすい様に「度」だけに変換するには、座標を抽出後「分」だけを60で割った後、それを初めの「度」に足し戻すだけです。
言葉では一行で説明出来ますがプログラムで書くと下記の通り大分ややこしいです。
volatile float Lat/*緯度*/, Long/*経度*/; void setup () { Serial.begin(115200); } void loop () { if (GpsRead() == 1) { //GPS情報(緯度・経度)が取得出来たら以下実行 Serial.print("Lat = "); Serial.print(Lat, 6); Serial.print(":Long = "); Serial.println(Long, 6); } } byte GpsRead() { char buf[256], *gps, szLat[16], szLong[16]; int count = 0; float temp , deg; //変数の宣言 volatile float *A[] = {&Lat, &Long}; //ポインタ変数による配列の宣言 do { if (Serial.available() > 0) { buf[count] = Serial.read(); count++; } if (count > 250) break; //bufは256文字列以上は受信できないのでdo~whileを抜ける } while (buf[count - 1] != 0x0A); //文字列の最後「cr(\r) LF(\n) CR:0x0d、LF:0x0A」確認 buf[count] = '\0'; //ヌル文字をbufに代入 if (0 == strncmp("$GPRMC", buf, 6)) { //buf中の先頭が"$GPRMC"であったら以下実行 strtok(buf, ","); strtok(NULL, ","); //トークンを2回飛ばす for (int i = 0; i <= 1; i++) { //以下、度のみに変換した緯度・緯度をLat・Longに代入 strtok(NULL, ","); //トークンを1回飛ばす gps = strtok(NULL, ","); //緯経度のデータが格納されているアドレスを取得 temp = atof(gps); //計算できる様に文字列をdouble 型の数値に変換 deg = (int)(temp / 100); //度のみ整数にし端数を切り捨て度だけ抽出 *A[i] = (temp - deg * 100) * 16666.67; //度を引いて分のみにし、分を度に変換し整数化 *A[i] = (*A[i] + deg * 1000000) / 1000000; //引いた度整数を足し戻し、小数点位置を戻す } strtok(NULL, ","); strtok(NULL, ","); //トークンを2回飛ばす return 1; } return 0; //測定出来たら1、そうでなければ0を返し終了 }
図1:プログラム例
GPSモジュールを、データ取得編の時と同じ様に配線した状態で、上記プログラムを実行するとデフォルトのGPS設定では一秒間に5回、今回はストロベリー・リナックスさんのサイトからminiGPSと言うソフトを入手して設定を変更したので一秒間に10回現在の緯度(Lat)と経度(Long)が図1の様に出力されます。
図1:シリアルモニタへの出力結果
図1の座標を前回の記事のやり方で地図検索した所、見事に私が居る部屋の上にピンが刺さりました!誤差は少なそうです
2. まとめ
GPSを使った工作としてラジコンにフォロミー(うちの猫の様に散歩について来る)機能を付けたいです!
GPSは2個使い、1つはラジコンのGPS座標(方位センサーも)用から、プロポ送信機用のGPS座標(無線マイコンTWE-LITE DIPで送信)に向かう方位と距離を計算すればラジコンが、プロポの送信機を持っている私のお供をしてくれるはずです!
また私のウニモグちゃんはベビーカーを牽引出来るくらい力もちなので私は手ぶらで荷物を全てラジコンが牽引して持って来てくれたら尚良いです!
実現出来るかは別として夢は広がります
励みになりますのでよければクリック下さい(^o^)/