Hello all,
I'm working on a portable GPS logger based on the T3.6, but I've been stuck on a weird issue I've been having regarding missing characters.
My code reads raw NMEA data from the GPS, stores and stores it in a 256-byte buffer. When the buffer is full, it dumps the contents into a .txt file an SD card. The problem is, it will randomly skip characters, sometimes only 2-3, other times whole sentences. What makes this more interesting is that if I comment out all of the data-logging code, I no longer have this issue.
My initial reaction was to add a 4700uF capacitor to the VDD line (overkill, I know ) in case current spikes during the SD write-cycle somehow caused the GPS to glitch out, but that didn't seem to fix the problem. For what it's worth, I'm using a PNY High Performance 32GB card in the T3.6's builtin slot. Although this could very well be the problem, my gut tells me it isn't the case.
Now I'm wondering if the SD write routine has a higher interrupt priority than the Serial read buffer, which would cause it to completely miss chunks of data.
I have a few theories as to what it could be, but I would like a fresh set of eyes to check my code and make sure there isn't something I missed.
Here's my code.
And here's an example of the data I'm getting.
I'm working on a portable GPS logger based on the T3.6, but I've been stuck on a weird issue I've been having regarding missing characters.
My code reads raw NMEA data from the GPS, stores and stores it in a 256-byte buffer. When the buffer is full, it dumps the contents into a .txt file an SD card. The problem is, it will randomly skip characters, sometimes only 2-3, other times whole sentences. What makes this more interesting is that if I comment out all of the data-logging code, I no longer have this issue.
My initial reaction was to add a 4700uF capacitor to the VDD line (overkill, I know ) in case current spikes during the SD write-cycle somehow caused the GPS to glitch out, but that didn't seem to fix the problem. For what it's worth, I'm using a PNY High Performance 32GB card in the T3.6's builtin slot. Although this could very well be the problem, my gut tells me it isn't the case.
Now I'm wondering if the SD write routine has a higher interrupt priority than the Serial read buffer, which would cause it to completely miss chunks of data.
I have a few theories as to what it could be, but I would like a fresh set of eyes to check my code and make sure there isn't something I missed.
Here's my code.
Code:
#include <SD.h>
#include <SPI.h>
File file;
const int BUFSIZE = 256;
char charbuf[BUFSIZE];
int buflevel = 0;
const int led1 = 24;
const int led2 = 26;
void setup(){
pinMode(led1, OUTPUT);
digitalWrite(led1, HIGH);
pinMode(led2, OUTPUT);
digitalWrite(led2, HIGH);
Serial.begin(115200);
Serial4.begin(115200); //GPS device
while(!Serial);
Serial.print("Initializing SD card...");
while(!SD.begin(BUILTIN_SDCARD)) {
Serial.println("initialization failed!");
digitalWrite(led2, LOW);
delay(750);
digitalWrite(led2, HIGH);
delay(750);
}
Serial.println("initialization done.");
if(SD.exists("NMEA.txt"))
SD.remove("NMEA.txt");
delay(100);
file = SD.open("NMEA.txt", FILE_WRITE);
if(file){
Serial.print("Writing to NMEA.txt...");
Serial.println("done.");
file.close();
}
else{
Serial.println("error opening NMEA.txt");
}
}
void loop(){
while(Serial4.available()){ //if a new character is available
charbuf[buflevel] = Serial4.read(); //copy it into the buffer
//if(charbuf[buflevel] == '$'){ //dump buffer contents to SD at the beginning of each NMEA sentence
if(buflevel == BUFSIZE-1){ //dump buffer contents to SD when the buffer is full
file = SD.open("NMEA.txt", FILE_WRITE);
if(file){
digitalWrite(led1, LOW); //turn on led
file.write(charbuf, buflevel); //write buffer data to SD
file.close();
Serial.write(charbuf, buflevel); //dump buffer contents to Serial monitor as well
digitalWrite(led1, HIGH); //turn off led
buflevel = 0; //reset buffer level to zero
}
else{
Serial.println("error opening NMEA.txt");
}
}
buflevel++;
}
}
And here's an example of the data I'm getting.