2018年2月18日日曜日

ArduinoでGPSロガー製作(みちびき対応)

 ArduinoにSDメモリーを使えるようにしてデータ保存できる様になったので、応用してGPSの位置情報を記録するロガーを作ることにした。

 GPSユニットは秋月電子で購入した「みちびき」に対応した物を持っているので使う事に。昔、使った時はさほど精度が上がったと思えなかったので御蔵入りしていたのだが、昨年4号機まで上がったので精度がどうなったか気になるところもあります。

 ArduinoでGPSユニットを使うには「ライブラリー」にTinyGPS++を追加するだけで簡単にプログラムを組むことができます。
GPSユニットはシリアルポートを使用しますので、SoftwareSerialも必要です。
【秋月のAE-GPS。1PPSは使用しません】


 SDメモリーの試験で使っていたのは3.3Vが必要だったのですが、別に購入していたmicroSD用の物は、よく見たら信号線にLV125Aが実装されており5Vのみで使えるようです。これを使うと5V-3.3vのレベル変換ICが不要になります。
 microSDは16Gを使用中です。
 【microSDカード。3.3Vレギュレータとレベル変換ICを実装している】


 GPSの動作表示はユニットに付属しているLEDの点滅でも分かりますが、位置情報も見えると便利です。位置情報を表示するためにLCD(1602A)を使いましたが、LCDの信号線を少なくするためI2C接続用のユニットを追加実装しました。
 なお、LCDのI2Cアドレス設定が”0x3f”だったので最初は動きませんでした。物に合わせてスケッチのアドレスを修正する必要が有ります。
【LCDに「GPS信号なし」を表示中。ほかにSDカード不良も出ます】


 Arduino自体はNANOを使い小型化しています。UNOと同等の性能・機能があるのでとても楽です。
 スケッチにはGPS、SD、LCD用に3種類を組み込みます。
【Arduino NANO】


 SDに記録するデータフォーマットは最初は年月日、時分秒、北緯、東経をカンマ","区切りとしておりました。記録したデータを色々と加工するには丁度良いフォーマットです。

 しかし、パソコンで記録を確認するに当たり「カシミール3D」を使うと、対応するフォーマット”.trk”に変換する必要があり、Excelのマクロで作成しておりました。
 それも面倒なので、SDに直接”.trk”のフォーマット・拡張子で記録し試験しています。
Arduinoの使用メモリーがギリギリの模様です。余計なコメントやシリアルポートへの出力は使っていません。

仮に100均の弁当箱に入れています。モバイルバッテリー使用中


 実際に使ってみると「みちびき」のおかげでしょうか?精度がとても良くなっております。車で使用していて1時間近く駐車した場合では、昔は結構位置が微妙にズレる揺らぎがありましたが、現在はほとんどありません。
 GPSユニットから真上が見えないと精度が下がるような気がします。

 下の絵はカシミール3Dで表示したトラックログです。車を駐車場に駐車した軌跡が残っています。反時計回りに進み、バックで駐車、駐車中はほとんど動かず。買い物をしてから時計回りに出場。


これは使えると思います。
この後は、釣行のログとして使えるよう更に機能UPさせましょう。

注意:本記事を参考にして不具合が有っても私は責任を取りません。参考は自己責任で行って下さい。

【プログラム:trkフォーマットで出力】
#include <SPI.h>
#include <SD.h>
File myFile;
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
TinyGPSPlus gps;
SoftwareSerial mySerial(3, 2);
LiquidCrystal_I2C lcd(0x3f,16,2);
void setup() {
 lcd.init();lcd.backlight();lcd.setCursor(0, 0);
 if (!SD.begin(4)) {lcd.println("SD failed!");return;}
 lcd.print("GPS_LOST!");
 mySerial.begin(9600);mySerial.println("Hello, world?");}

void loop() { // run over and over
while (mySerial.available() > 0){
char c = mySerial.read();
gps.encode(c);
if (gps.location.isUpdated()){
String FN=String(gps.date.value())+".trk"; 
myFile = SD.open(FN, FILE_WRITE);
myFile.print("T N");
lcd.setCursor(0,0);
lcd.print("LAT="); lcd.print(gps.location.lat(), 6);
myFile.print(gps.location.lat(), 6);myFile.print(" E");
lcd.setCursor(0,1);
lcd.print("LONG=");lcd.print(gps.location.lng(), 6);
myFile.print(gps.location.lng(), 6);myFile.print(" ");
FN=(gps.date.day());if (FN.length()<2){FN="0"+FN;}
myFile.print(FN);myFile.print("-");
FN=(gps.date.month());if (FN.length()<2){FN="0"+FN;}
myFile.print(FN);myFile.print("-");
FN=(gps.date.year());
myFile.print(FN.charAt(2));myFile.print(FN.charAt(3));
myFile.print(" ");
FN=(gps.time.hour());if (FN.length()<2){FN="0"+FN;}
myFile.print(FN);myFile.print(":");
FN=(gps.time.minute());if (FN.length()<2){FN="0"+FN;}
myFile.print(FN);myFile.print(":");
FN=(gps.time.second());if (FN.length()<2){FN="0"+FN;}
myFile.print(FN);myFile.println(" 0");
myFile.close();
}
}
}

0 件のコメント:

コメントを投稿