Cannot log two data source into SD card

Guys, I really need your help. I am going to log data into SD card from two external applications, one is GPS data, the other is Range finder. Interestingly, I can log them into my sd card INDIVIDUALLY, but after I combine the code and try to log them COLLECTIVELY, I am not be able to do that. The serial monitor can print both of the information fine, but the situation in sd card is all of three files are created, but there is only one entry logged(should be a lot entries in all of three files) in the gap width file(the first file created), the other two files(NMEA, GPSdata) are empty.I attached the code, please read it and help!

#include<SD.h>// install the SD card library
#include<SPI.h>// load the SPI library

#include <Adafruit_GPS.h>   // install the adafruit GPS library
#include <SoftwareSerial.h> //load the software serial library
SoftwareSerial mySerial(3,2); //initialize the software Serial port
Adafruit_GPS GPS(&mySerial);// Create the GPS object

String NMEA1; // Variable fot first NEAMA sentence.
String NMEA2; // Variable fot second NEAMA sentence.
char c; // to read characters coming from the GPS
int switchPin = 9; 
int x=0;

int chipSelect = 4; // chip select is connected to pin 4
File mySensorData; // Declare variable for your sd card library

void setup(){
 pinMode(switchPin,INPUT);
 Serial.begin(9600); // turn on serial monitor
 GPS.begin(9600);// turn on GPS at 9600 baud
 GPS.sendCommand("$PGCMD,33,0*6D");// Turn off GPS Antenna upadate
 GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Tell GPS we want only $GPRMC and $GPGGA NMEA sentences
 GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);// Set update rate to 10 HZ 
 delay(1000);
  pinMode(10, OUTPUT); //Must declare 10 an output and reserve it to keep SD card happy
  SD.begin(chipSelect);// Initialize our SD card and say it is connected to chipselect
  if (SD.exists("NMEA.txt")) { //Delete old data files to start fresh
   SD.remove("NMEA.txt");
 }
 if (SD.exists("GPSData.txt")) { //Delete old data files to start fresh
   SD.remove("GPSData.txt");
 }
   if (SD.exists("gap.txt")) { //Delete old data files to start fresh
   SD.remove("gap.txt");
 }
 pinMode (6,OUTPUT);//attach pin 6 to vcc
 pinMode (5,OUTPUT);//attach pin 5 to GND
 // initialize serial communication:


}
 
 void loop() {
   digitalWrite(6, HIGH);
 // establish variables for duration of the ping,
 // and the distance result in inches and centimeters:
 long duration, inches, cm;

 // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
 pinMode(7, OUTPUT);// attach pin 7 to Trig
 digitalWrite(7, LOW);
 delayMicroseconds(2);
 digitalWrite(7, HIGH);
 delayMicroseconds(5);
 digitalWrite(7, LOW);

 // The same pin is used to read the signal from the PING))): a HIGH
 // pulse whose duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off of an object.
 pinMode (8, INPUT);//attach pin 8 to Echo
 duration = pulseIn(8, HIGH);

 // convert the time into a distance
 inches = microsecondsToInches(duration);
 cm = microsecondsToCentimeters(duration);



 delay(1000);
 Serial.print(inches);
 Serial.print("in, ");
 Serial.print(cm);
 Serial.print("cm");
 Serial.println();
mySensorData=SD.open("gap.txt",FILE_WRITE);
mySensorData.print(inches);
mySensorData.print("in, ");
mySensorData.print(cm);
mySensorData.print("cm");
mySensorData.println();
mySensorData.close();// close file

readGPS();
mySensorData=SD.open("NMEA.txt",FILE_WRITE);//OPEN NMEA for writing 

//[color=red]!!! I think the problem reside here, the following code may not be executed!!![/color]//
mySensorData.println(NMEA1);// Write first sentence to the SD card   
mySensorData.println(NMEA2);// Write second sentence to the SD card
mySensorData.close();// close file
mySensorData=SD.open("GPSData.txt",FILE_WRITE);//OPEN NMEA for writing   
mySensorData.print(GPS.latitude,4);//Write lattitude to GPSData file
mySensorData.print(GPS.lat); //Give you whether N or S
mySensorData.print(",");
mySensorData.print(GPS.longitude,4);
mySensorData.print(GPS.lon);// Whehter E or W
mySensorData.print(",");
mySensorData.println(GPS.altitude,4);
mySensorData.close();// close file

 

   delay(250); //


}
long microsecondsToInches(long microseconds)
{
 // According to Parallax's datasheet for the PING))), there are
 // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
 // second).  This gives the distance travelled by the ping, outbound
 // and return, so we divide by 2 to get the distance of the obstacle.
 // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
 return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
 // The speed of sound is 340 m/s or 29 microseconds per centimeter.
 // The ping travels out and back, so to find the distance of the
 // object we take half of the distance travelled.
 return microseconds / 29 / 2;
}
void readGPS(){
clearGPS(); 
while(!GPS.newNMEAreceived()){ // Loop until you have a new GPS sentence
c=GPS.read();

 } 
 GPS.parse(GPS.lastNMEA()); //Parse the last goof GPS sentence
 NMEA1=GPS.lastNMEA();
 
 while(!GPS.newNMEAreceived()){ // Loop until you have a new GPS sentence
c=GPS.read();

 } 
 GPS.parse(GPS.lastNMEA()); //Parse the last goof GPS sentence
 NMEA2=GPS.lastNMEA();
 
 Serial.println(NMEA1);
 Serial.println(NMEA2);
 Serial.println("");

 
}

void clearGPS(){ // clear old and corrput data from serial port
 while(!GPS.newNMEAreceived()){ // Loop until you have a new GPS sentence
c=GPS.read();

 }
 GPS.parse(GPS.lastNMEA()); //Parse the last goof GPS sentence
 while(!GPS.newNMEAreceived()){ // Loop until you have a new GPS sentence
c=GPS.read();

 } 
 GPS.parse(GPS.lastNMEA()); //Parse the last goof GPS sentence
}

GPS_SDcard_RF_no_fix.ino (5.06 KB)

It looks like the code should work but SD.open can fail when memory is low. Try adding some error checks like this.

 mySensorData=SD.open("gap.txt",FILE_WRITE);
 if (!mySensorData) {
   Serial.println(F("open failed - gap.txt"));
   return;
 }

// .....

 mySensorData=SD.open("NMEA.txt",FILE_WRITE);//OPEN NMEA for writing
 if (!mySensorData) {
   Serial.println(F("open failed - NEMA.txt"));
   return;
 }

//....


 mySensorData=SD.open("GPSData.txt",FILE_WRITE);//OPEN NMEA for writing
 if (!mySensorData) {
   Serial.println(F("open failed - GPSData.txt"));
   return;
 }

I think the file is open correctly but fail to write. I will correct it as you said. Thanks a lot.

I think the file is open correctly but fail to write

You can't tell unless you check. There is a malloc call in SD.open and when the free RAM falls below a threshold, open fails.

readGPS() uses String objects, and Strings often cause this problem since they use dynamic memory.

Write/print is not likely to fail since no dynamic memory is used.

I think it may fail to open, I attached the output from the serial monitor. Thanks a lot

0in, 0cm

$GPRMC,201303.089,V,,,,,0.00,0.00,040115,,,N*4E

$GPGGA,201304.089,,,,,0,00,,,M,,M,,*7D

open failed - NMEA.txt
1in, 4cm
open failed - gap.txt
2in, 6cm
open failed - gap.txt
2in, 6cm
open failed - gap.txt
2in, 6cm
open failed - gap.txt
2in, 6cm
open failed - gap.txt
2in, 6cm
open failed - gap.txt
2in, 6cm
.....

fat16lib:
You can't tell unless you check. There is a malloc call in SD.open and when the free RAM falls below a threshold, open fails.

readGPS() uses String objects, and Strings often cause this problem since they use dynamic memory.

Write/print is not likely to fail since no dynamic memory is used.

How can I address that problem?

How can I address that problem?

You application might work if you can free some RAM.

I really can't help you since I avoid any libraries that use dynamic memory, like the Adafruit GPS library or SD.h.

Use of dynamic memory is forbidden in the type software I design professionally so I don't use it in hobby apps either.

You never know when the heap is fragmented or exhausted and allocation of dynamic memory will fail. That's why its use is forbidden in critical applications where life or property is at risk.

readGPS() uses String objects, and Strings often cause this problem since they use dynamic memory.

That should say "since they misuse...".

You can waste a surprising amount of RAM with the strings used for talking to the user. 'Constant' strings used in your code will use RAM unless you specifically tell it not to.

Try doing this everywhere you have a string longer than 3-4 characters:

GPS.sendCommand(F("$PGCMD,33,0*6D"));