モエレの雪上絵 GPSロガー最終版

1月9日(明後日!)はモエレの雪上絵のワークショップなので、やり残していたコードの追加をしていきます。
SDカードに保存される GPS.LOG というcsvファイルですが、起動するたびに後ろにデータが書き足されていく状態のままになっています。
これだと、使い始める前にカードを初期化しなければならず面倒なので、今回は、起動するたびに新たなファイル名でログを残していく仕様にしたいと思います。

偉そうに書いていますが、実はArduinoはあまり馴染みがないのでちょろっとググったところ、
SD.exists( String ) というのが存在するので、一番安直な方法で書いてみました。
存在しない新しいファイル名を取得する関数。

String getNewFileName(){
  
  String s;
  int fileNum = 0;

  while(1){
    s = "GPS_";
    if (fileNum < 10) {
      s += "00";
    } else if(fileNum < 100) {
      s += "0";
    }
    
    s += fileNum;
    s += ".log";
    
    if(!SD.exists(s)){
      break;
    }
    
    fileNum++;
  }

  return s;
}

あとは、起動時、SDカードを初期化した後で呼んでやって変数に代入しておいて、書き込み時に使うだけです。

fileNameToWrite = getNewFileName();

全体はこんな感じ。

#include <TinyGPS++.h>
#include 
#include 

#define SERIAL_BAUD 9600

const int GPS_RX = 8;
const int GPS_TX = 9;
const int LED_PIN = 6;  //for LED

const int CHIP_SELECT = 4;  //for SD

TinyGPSPlus gps;
SoftwareSerial gpsSerial(GPS_RX, GPS_TX);
String fileNameToWrite;

void setup() {

  Serial.begin(SERIAL_BAUD);
  while (!Serial) {} // wait
  Serial.println("serial initialized\n");

  gpsSerial.begin(9600);

  setupSD();
  fileNameToWrite = getNewFileName();
  Serial.println( fileNameToWrite );

  pinMode(LED_PIN, OUTPUT);
  
}

void loop() {

  while (gpsSerial.available() > 0) {
    
    char c = gpsSerial.read();
    //Serial.print(c);
    gps.encode(c);

    if (gps.time.isUpdated()) {

      writeData();

      Serial.print("year : "); Serial.println(gps.date.year());
      Serial.print("mon : "); Serial.println(gps.date.month());
      Serial.print("day : "); Serial.println(gps.date.day());

      Serial.print("hour : "); Serial.println(gps.time.hour());
      Serial.print("min : "); Serial.println(gps.time.minute());
      Serial.print("sec : "); Serial.println(gps.time.second());

      Serial.print("lat : "); Serial.println(gps.location.lat(), 6);
      Serial.print("lng : "); Serial.println(gps.location.lng(), 6);
      Serial.print("alt : "); Serial.println(gps.altitude.meters());

    }
  }
}


String getNewFileName(){
  
  String s;
  int fileNum = 0;

  while(1){
    s = "GPS_";
    if (fileNum < 10) {
      s += "00";
    } else if(fileNum < 100) {
      s += "0";
    }
    
    s += fileNum;
    s += ".log";
    
    if(!SD.exists(s)){
      break;
    }
    
    fileNum++;
  }

  return s;
}


void setupSD() {
  
  Serial.print("Init SD.");
  
  if (!SD.begin(CHIP_SELECT)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  Serial.println("SD initialized.");
}


void writeData() {

  File dataFile = SD.open(fileNameToWrite, FILE_WRITE);

  if (dataFile) {

    digitalWrite(LED_PIN, HIGH);

    String str;
    str = String(gps.date.year());
    str += "/";
    str += String(gps.date.month());
    str += "/";
    str += String(gps.date.day());
    str += ",";
    str += String(gps.time.hour());
    str += ":";
    str += String(gps.time.minute());
    str += ":";
    str += String(gps.time.second());
    str += ",";
    str += String(gps.location.lat(), 6);
    str += ",";
    str += String(gps.location.lng(), 6);
    str += ",";
    str += String(gps.altitude.meters());

    dataFile.println(str);
    dataFile.flush();
    digitalWrite(LED_PIN, LOW);

  } else {
    Serial.println("error opening log");
    Serial.println(fileNameToWrite);
    
    
    digitalWrite(LED_PIN, LOW);
  }

  dataFile.close();

}

GPS_000.LOG
GPS_001.LOG
GPS_002.LOG

といった感じで起動するたびに新しいファイルが保存されていきます。