Arduinoでエアコンの1時間タイマーを自作する

ArduinoでGPSロガーを自作する

この記事は別ブログ(2021/03/26投稿)から移行したものです。

今日も今日とて電子工作。

以前から作りたかったGPSロガーをArduinoを使って作ろうと思います。
今回の内容は主に「設計」と「テスト」になります。

とりあえずはNMEAセンテンスのうち、「GPGGA」と「GPRMC」のみを".LOG"ファイルで記録して、各種変換ソフトでGoogleEarthで表示できる.kmzファイルに変換しようと思います。



 準備した物

早速ですが準備したもの一覧です。
  • ArduinoUnoR3(自作したやつ)
  • GPSアンテナモジュール(AE-GYSFDMAXB,秋月のやつ)
  • microSDカードアダプター(SPIマイクロSDアダプタ)
  • 10kΩのカーボン抵抗1本
  • ダイオード1本(1N4148)
以上。

回路図

まずは回路図です。
GPSモジュールのRXDピンへの接続にひと手間かかりますが、その他はただ繋ぐだけ。
GND、5V(VCC)もそのままArduinoへ繋ぎます。


組み立て

テスト段階ですのでブレッドボード上に組み立てます。
車で動作テストをしたので輪ゴムで縛ってあります…



プログラム

メインルーチン

#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

const int cs = 10;//SDカードCS
File logFile;
char fileName[16];
int fileNum = 0;
SoftwareSerial mySerial(2,3); //rx=2 tx=3

void setup(){
  INIT_GPS();//GPS初期化
  INIT_SD();//SDカード初期化、準備
}

void loop(){
  READ_GPS();//GPSを読み込みSDカードへデータを書き込む関数
}

GPS初期化&設定関数

void INIT_GPS(void){//GPSの初期化と設定
  mySerial.begin(9600); //GPSデフォルトの通信レート9600
  //mySerial.print("$PMTK251,19200*22\r\n");//通信レートを19200に設定
  mySerial.print("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");//$GGA、RMCのみ送信
  mySerial.print("$PMTK225,0*2B\r\n");//間欠モードオフ(省エネモードオフ)
  while(1){
  String GGA = mySerial.readStringUntil('\n');//改行まで読み込む
    if(GGA != ""){
    int i, index = 0, GGALEN = GGA.length();
    String str = "";

    String list[20];//listを作成
      for(i=0; i<20; i++)
      {
      list[i] = "";
      }

      for(i=0; i<GGALEN; i++)//,区切りで配列を生成
      {
        if(GGA[i] == ',')
        {
        list[index++] = str;
        str = "";
        continue;
        }
      str += GGA[i];
      }
    if(list[0]=="$GPRMC"){
      if(list[2]=="A")//"$GPRMC"のデータが有効(A)なら初期化関数を終える(Vは無効)
      {
        break;
      }
    }
    }
  }
}

SDカード初期化関数

void INIT_SD(void){//SDカード初期化とログファイル作成
  if(!SD.begin(cs)){
  return;
  }
  String t;
  while(1){
    t = "GPS";
    if (fileNum < 10){
      t += "00";
    }
    else if(fileNum < 100){
      t += "0";
    }
    t += fileNum;
    t += ".LOG";
    t.toCharArray(fileName, 16);
    if(!SD.exists(fileName)) break;
    fileNum++;
  }
  // ログファイルに1行目を書き込む
  logFile = SD.open(fileName, FILE_WRITE);
  logFile.println("@※自分のIDとか適当に/ver1.0/wgs84");
  logFile.close();
  Serial.println("SD準備完了");
}

GPS読み込み&SDカード書き込み関数

void READ_GPS(void)//GPSを読み込みログファイルへ書き込む
{
  String GGA = mySerial.readStringUntil('\n');//改行まで読み込む
  String RMC = mySerial.readStringUntil('\n');//同上
  if(GGA != ""){//このあたりはGPS初期化の内容と同じ
    int i, index = 0, GGALEN = GGA.length();
    String str = "";

    String list[20];
    for(i=0; i<20; i++)
    {
      list[i] = "";
    }

    for(i=0; i<GGALEN; i++)
    {
      if(GGA[i] == ',')
      {
        list[index++] = str;
        str = "";
        continue;
      }
      str += GGA[i];
    }
    
    if(list[0] == "$GPGGA"){//list[0]が$GPGGAの
      if(list[6] == "1"){//list[6]が"1"の場合ログファイルに書き込む。"0"の場合測位できていないので記録しない
      logFile = SD.open(fileName, FILE_WRITE);
      logFile.print(GGA.c_str());
      logFile.print(RMC.c_str());
      logFile.close();
      }
    }
    else
    {
    //測位失敗  
    }
  }
}

出来上がった.LOGファイル

間の空白は緯度経度の情報が載っているので消しています。




この.LOGファイルを各種変換ソフトで変換してあげます。
今回は「NMEA2KMZ」というソフトを使わせていただきました。

今回のログファイルは1秒ごとというかなりな高頻度でログを残すのですが、このソフトは秒数や移動距離から変換する地点の数を減らすことが出来ます。


.kmzファイルに変換したので早速GoogleEarthで表示してみました。
無事に記録でき、変換も問題なく行えていることが確認できました。




ということで無事動作が確認できたので次回は基板を設計して1枚の基板にまとめてしまおうと思います。

それではお疲れ様でした。