Issues with data-logging multiple sensors

So I am trying to make a data-logger for my R/C Car and I have the code mostly working, but I am having issues with it writing to the SD card reliably. Most of the code is copied and pasted from the various sample sketches and then modified to supposedly work with what I am trying to do. My main issues are that it seems to log inconsistently and will often have errors in the log such as corrupted files.

What I want it to do is monitor and log all the sensors to a text file that I can later import into excel and overlay onto a FPV as 'live telemetry'. I would like it to log as often as possible, now I know that the GPS is going to be the limiting factor in the logging speed, but I want all other sensors to log as fast as possible and if I get repeat data for the GPS info in the log file that is fine. If I can get this to work I would like to be able to output the max recorded speed and G-force to the LCD screen, I would also like the ability to use the buttons on the LCD screen to start/stop the logging.

Any help would be greatly appreciated!

Here is what I have for hardware:

Arduino UNO R3
Adafruit Ultimate GPS Logger Shield - Adafruit Ultimate GPS Logger Shield - Includes GPS Module : ID 1272 : $29.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Adafruit RGB LCD Shield Kit w/ 16x2 Character Display - RGB LCD Shield Kit w/ 16x2 Character Display - Only 2 pins used! [NEGATIVE DISPLAY] : ID 714 : $24.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Pololu LSM303DLM 3D Compass and Accelerometer Carrier - Pololu - LSM303DLM 3D Compass and Accelerometer Carrier with Voltage Regulators
Pololu L3G4200D 3-Axis Gyro Carrier - Pololu - L3G4200D 3-Axis Gyro Carrier with Voltage Regulator
LM35 Temp Sensor (2x)

Here is the code I currently have:

//#include <avr/pgmspace.h>
#include <SoftwareSerial.h>
#include <Adafruit_GPS.h>
//#include <Adafruit_MCP23017.h>
//#include <Adafruit_RGBLCDShield.h>
#include <L3G.h>
#include <LSM303.h>
#include <Wire.h>
#include <SD.h>

// Adafruit GPS Shield Start Here

SoftwareSerial mySerial(8, 7);
Adafruit_GPS GPS(&mySerial);
const int chipSelect = 10;

  // Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
  // Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  true

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

// LSM303DLM 3D Compass and Accelerometer Carrier Start Here

LSM303 compass;

// L3G4200D 3-Axis Gyro Carrier Start Here

L3G gyro;

// Adafruit RGB Character LCD Shield Start Here
/*
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7
*/
void setup()
{
  Serial.begin(115200);
  
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
  
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since
  // the parser doesn't care about other sentences at this time
  
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  // For the parsing code to work nicely and have time to sort thru the data, and
  // print it out we don't suggest using anything higher than 1 Hz

  // Request updates on antenna status, comment out to keep quiet
  GPS.sendCommand(PGCMD_ANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);

  delay(1000);
  // Ask for firmware version
  mySerial.println(PMTK_Q_RELEASE);
  
  Wire.begin();

  if (!gyro.init())
  {
    Serial.println(F("Failed to autodetect gyro type!"));
    while (1);
  }

  gyro.enableDefault();
  
  compass.init();
  compass.enableDefault();
/*  
  lcd.begin(16, 2);
  lcd.setBacklight(WHITE);
*/  
  Serial.print(F("Initializing SD card..."));
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println(F("Card failed, or not present"));
    // don't do anything more:
    return;
  }
  Serial.println(F("card initialized."));
  
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    dataFile.println(F(" GPS Time , GPS Fix , GPS Quality , Lat , Lon , GPS Speed , GPS Angle , GPS Altitude , GPS Satellites , AX , AY , AZ , MX , MY , MZ , GX , GY , GZ , ESC Temp , Motor Temp "));
    dataFile.close();
  }
  
}


// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // 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
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();
void loop()
{
  // in case you are not using the interrupt above, you'll
  // need to 'hand query' the GPS, not suggested :(
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    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 trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
  
    if (!GPS.parse(GPS.lastNMEA()))   // 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
  }

  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis())  timer = millis();

  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 2000) { 
    timer = millis(); // reset the timer
  
  }

  int gpsspeed = (GPS.speed, DEC * 1.151);
  compass.read();
  gyro.read();
  int temp1 = analogRead(A1);
  int temp2 = analogRead(A2);
  float esctemp = ((((temp1 * (5.0 / 1023.0)) * 100) * 1.8) + 32.0);
  float motortemp = ((((temp2 * (5.0 / 1023.0)) * 100) * 1.8) + 32.0);
  
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.print(GPS.hour, DEC);
    dataFile.print(":");
    dataFile.print(GPS.minute, DEC);
    dataFile.print(":");
    dataFile.print(GPS.seconds, DEC);
    dataFile.print(".");
    dataFile.print(GPS.milliseconds, DEC);
    dataFile.print(" , ");
    dataFile.print((int)GPS.fix);
    dataFile.print(" , ");
    dataFile.print((int)GPS.fixquality);
    dataFile.print(" , ");
    dataFile.print(GPS.latitude, 4); //dataFile.print(GPS.lat);
    dataFile.print(" , ");
    dataFile.print(GPS.longitude, 4); //dataFile.print(GPS.lon);
    dataFile.print(" , ");
    dataFile.print(gpsspeed);
    dataFile.print(" , ");
    dataFile.print(GPS.angle);
    dataFile.print(" , ");
    dataFile.print(GPS.altitude);
    dataFile.print(" , ");
    dataFile.print(GPS.satellites);
    dataFile.print(" , ");
    dataFile.print((int)compass.a.x);
    dataFile.print(" , ");
    dataFile.print((int)compass.a.y);
    dataFile.print(" , ");
    dataFile.print((int)compass.a.z);
    dataFile.print(" , ");
    dataFile.print((int)compass.m.x);
    dataFile.print(" , ");
    dataFile.print((int)compass.m.y);
    dataFile.print(" , ");
    dataFile.print((int)compass.m.z);
    dataFile.print(" , ");
    dataFile.print((int)gyro.g.x);
    dataFile.print(" , ");
    dataFile.print((int)gyro.g.y);
    dataFile.print(" , ");
    dataFile.print((int)gyro.g.z);
    dataFile.print(" , ");
    dataFile.print(esctemp);
    dataFile.print(" , ");
    dataFile.println(motortemp);
    dataFile.close();
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
  
}

DATALOG.TXT (6.06 KB)

// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();

Ummm. No, it doesn't. It reads one character, and maybe prints it, then discards it. It does NOT store it.

uint32_t timer = millis();

Crappy name. When an event occurs has a completely separate meaning from a timer. You might as well call the variable "Bob".

  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }

So, if you are not using interrupts, read and throw the character away, too. What's the purpose?

  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 trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false

Not to worry, since this function will never return true.

  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis())  timer = millis();

I don't see the point in this.

  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 2000) { 
    timer = millis(); // reset the timer
  
  }

That's not what that code does.

  int gpsspeed = (GPS.speed, DEC * 1.151);

What do you think that this code is doing? It isn't, but I'm curious what you think it is doing.

Thank you for taking the time to look at it, but as I stated in my first post, most of the code is copied from the example sketches. I will also fully admit that I am a complete novice at coding. I am trying to teach myself as I go. Now, every piece of code you mentioned was a direct copy-paste, except the last one. That last line is where I tried to convert Knots to MPH. As for the rest of the code, I have no clue as to what the hell is going on.

As for the rest of the code, I have no clue as to what the hell is going on.

That's going to be a problem, then, because you failed to copy enough of the example sketches. You should study each of the, to understand them, before you go copying code to another sketch. You need to make sure you copy EVERYTHING that is needed to make the desired functionality work. Since you haven't even indicated WHICH examples you cribbed from, it's hard to tell you what you missed copying.

I did go through all the example sketches, but I guess I just didn't understand very much. I will go through them again and try to figure out what is going on.

I took code from the following example sketches:

LSM303
->Serial
L3G
->Serial
Adafruit_RGB_LCD_Shield_Library
->HelloWorld
Adafruit_GPS
->parsing
SD
->Datalogger
01.Basics
->ReadAnalogVoltage

I have uploaded my Arduino folder with all my sketches and libraries to my Google drive.

https://drive.google.com/folderview?id=0B7_wYqRQ2P5pRzdrUzhMS1NTNmM&usp=sharing

bump

It does no good to bump a post without providing more details.

You have a sketch that you created by copying some (not all) of a working sketch. You need to delete it. Copy the whole sketch, and edit that. First, run the sketch AS-IS to make sure that it works. Then, delete stuff you think you don't need. After each session, TEST! If it doesn't work, put the stuff back.

When you have a working sketch that JUST gets data from the GPS and logs it, add ONE more sensor at a time.