I do not know what the “frequencies” have to do with your problem, but I
would bet that you would get more reliable results if you handle one
NMEA sentence at a time, instead of trying to handle six of them at
once, and hoping to get the right ones.
Below is a function that processes one complete sentence at a time. It
records the sentence to the SD file if its type belongs to a list of
“interesting” types you want to monitor:
// Sentence types that are to be recorded.
const char monitoredTypes[6][4] = {
"GGA", "VTG", "ZDA", "GLL", "GNS", "GRS"
};
// Process a complete, CRLF-terminated NMEA sentence.
void processSentence(String &sentence) {
// Sanity check.
if (sentence.substring(0, 3) != "$GP") {
Serial.print("WARNING: invalid sentence: ");
Serial.print(sentence);
return;
}
// Record the sentence if it has an interesting type.
String type = sentence.substring(3, 6);
for (int i = 0; i < 6; i++) {
if (type == monitoredTypes[i]) {
File dataFile = SD.open("GPS1.txt", FILE_WRITE);
if (type == "GGA") { // this type seems to be special
dataFile.print(dt);
dataFile.print(" ");
dataFile.print(tm);
dataFile.print(msec);
dataFile.print(",");
}
dataFile.print(sentence);
dataFile.close();
}
}
}
The way to use it is to buffer the incoming characters until you get a
complete sentence (identified by the final LF), then submit that buffer
to this function:
String buffer;
void loop() {
while (Serial.available() > 0) {
char c = Serial.read();
buffer += c;
// On end of sentence, process and clear the buffer.
if (c == '\n') {
processSentence(buffer);
buffer = "";
}
}
}
Note that it wouldn't take too much work to get rid of the String
class and use plain C strings instead. Pain strings are way more memory
friendly.