     if (GPSECHO)
       if (c) Serial.print(c);
   }
-  
-  // if a sentence is received, we can check the checksum, parse it...
-  if (GPS.newNMEAreceived()) {
-    // a tricky thing here is if we print the NMEA sentence, or data
-    // we end up not listening and catching other sentences! 
-    // so be very wary if using OUTPUT_ALLDATA and trying to print out data
-    
-    // Don't call lastNMEA more than once between parse calls!  Calling lastNMEA 
-    // will clear the received flag and can cause very subtle race conditions if
-    // new data comes in before parse is called again.
-    char *stringptr = GPS.lastNMEA();
-    
-    if (!GPS.parse(stringptr))   // this also sets the newNMEAreceived() flag to false
-      return;  // we can fail to parse a sentence in which case we should just wait for another
-
-    // Sentence parsed! 
-    Serial.println("OK");
-    if (LOG_FIXONLY && !GPS.fix) {
-      Serial.print("No Fix");
-      return;
-    }
-
-    // Rad. lets log it!
-    Serial.println("Log");
-
-    uint8_t stringsize = strlen(stringptr);
-    if (stringsize != logfile.write((uint8_t *)stringptr, stringsize))    //write the string to the SD file
-        error(4);
-    if (strstr(stringptr, "RMC") || strstr(stringptr, "GGA"))   logfile.flush();
+
+  { // If it's been LOG_RATE milliseconds since the last log:
+  if ((lastLog + LOG_RATE) <= millis())
+
+    // if a sentence is received, we can check the checksum, parse it...
+    if (GPS.newNMEAreceived() && GPS.parse(GPS.lastNMEA())) {
+
+      if (LOG_FIXONLY && !GPS.fix) {
+        Serial.println("No Fix");
+        return;
+      }
+
+      if (logGPSData()) // Log the GPS data
+      {
+        lastLog = millis(); // Update the lastLog variable
+      }
+      else // If we failed to log GPS
+      { // Print an error, don't update lastLog
+        Serial.println("Failed to log new GPS data.");
+      }
+
+    }
+  }
+}
+
+byte logGPSData()
+{
+  if (GPSECHO)
+  {
+    Serial.print(GPS.longitudeDegrees, 4);
+    Serial.print(',');
+    Serial.print(GPS.latitudeDegrees, 4);
+    Serial.print(',');
+    Serial.print(GPS.altitude, 1);
+    Serial.print(',');
+    Serial.print(GPS.speed, 1);
+    Serial.print(',');
+    Serial.print(GPS.angle, 1);
+    Serial.print(',');
+    Serial.print(GPS.day, DEC); Serial.print('/');
+    Serial.print(GPS.month, DEC); Serial.print("/20");
+    Serial.print(GPS.year, DEC);
+    Serial.print(',');
+    Serial.print(GPS.hour, DEC); Serial.print(':');
+    Serial.print(GPS.minute, DEC); Serial.print(':');
+    Serial.print(GPS.seconds, DEC); Serial.print('.');
+    Serial.print(GPS.milliseconds);
+    Serial.print(',');
+    Serial.print((int) GPS.satellites);
+    Serial.print(',');
+    Serial.print((int)GPS.fix);
+    Serial.print(',');
+    Serial.print((int)GPS.fixquality);
     Serial.println();
   }
+
+  File logFile = SD.open(logFileName, FILE_WRITE);
+  if (logFile)
+  {
+    logFile.print(GPS.longitudeDegrees, 4); logFile.print(GPS.lon);
+    logFile.print(',');
+    logFile.print(GPS.latitudeDegrees, 4); logFile.print(GPS.lat);
+    logFile.print(',');
+    logFile.print(GPS.altitude, 1);
+    logFile.print(',');
+    logFile.print(GPS.speed, 1);
+    logFile.print(',');
+    logFile.print(GPS.angle, 1);
+    logFile.print(',');
+    logFile.print(GPS.day, DEC); logFile.print('/');
+    logFile.print(GPS.month, DEC); logFile.print("/20");
+    logFile.print(GPS.year, DEC);
+    logFile.print(',');
+    logFile.print(GPS.hour, DEC); logFile.print(':');
+    logFile.print(GPS.minute, DEC); logFile.print(':');
+    logFile.print(GPS.seconds, DEC); logFile.print('.');
+    logFile.print(GPS.milliseconds);
+    logFile.print(',');
+    logFile.print((int) GPS.satellites);
+    logFile.print(',');
+    logFile.print((int)GPS.fix);
+    logFile.print(',');
+    logFile.print((int)GPS.fixquality);
+    logFile.println();
+    logFile.close();
+
+    return 1; // Return success
+  }
+
+  return 0; // If we failed to open the file, return fail
+}
+
+// printHeader() - prints our column names to the top of our log file
+void printHeader()
+{
+  File logFile = SD.open(logFileName, FILE_WRITE); // Open the log file
+
+  if (logFile) // If the log file opened, print our column names to the file
+  {
+    int i = 0;
+    for (; i < LOG_COLUMN_COUNT; i++)
+    {
+      logFile.print(log_col_names[i]);
+      if (i < LOG_COLUMN_COUNT - 1) // If it's anything but the last column
+        logFile.print(','); // print a comma
+      else // If it's the last column
+        logFile.println(); // print a new line
+    }
+    logFile.close(); // close the file
+  }
+}
+
+// updateFileName() - Looks through the log files already present on a card,
+// and creates a new file with an incremented file index.
+void updateFileName()
+{
+  int i = 0;
+  for (; i < MAX_LOG_FILES; i++)
+  {
+    memset(logFileName, 0, strlen(logFileName)); // Clear logFileName string
+    // Set logFileName to "gpslogXX.csv":
+    sprintf(logFileName, "%s%d.%s", LOG_FILE_PREFIX, i, LOG_FILE_SUFFIX);
+    if (!SD.exists(logFileName)) // If a file doesn't exist
+    {
+      break; // Break out of this loop. We found our index
+    }
+    else // Otherwise:
+    {
+      Serial.print(logFileName);
+      Serial.println(" exists"); // Print a debug statement
+    }
+  }
+  Serial.print("File name: ");
+  Serial.println(logFileName); // Debug print the file name
 }
 
 

// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  true
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY false  

// this keeps track of whether we're using the interrupt
// off by default!

  // if you want to debug, this is a good time to do it!
  #ifdef UDR0
      if (GPSECHO)
        if (c) UDR0 = c;
      // writing direct to UDR0 is much much faster than Serial.print
      // but only one character can be written at a time.
  #endif
}

