Nothing written to SD card when using file.println

Hi there, I seem to have some quite intermittently working code. I was managing to create a file named gps.txt on an SD card yesterday and write some output from a GPS module to it. However, this morning something seems to have changed. When looking at the serial monitor, the SD card seems to be opened and closed sucessfully but the writing in between those two actions doesn't seem to take place.

#include <SD.h>
#include <SPI.h>

#define GPS_SERIAL Serial3

char lati[20];
char longdi[20];
char nmea[82] = "";
boolean gpsDone = false;
volatile int counter = 0;

int CS_PIN = 10;
File file;
char DUMP_FILE[] = "gps.txt";


void setup() {
  Serial.begin(115200);
  Serial3.begin(9600);

  startSD();
  makeFile("gps.txt");


  attachInterrupt(7, readGPS, RISING);
}

void loop() {
  if (gpsDone) {
    Serial.println(nmea);
    openFile("gps.txt");
    writeToFile(nmea);
    closeFile();
    //parseGPS();
    //Serial.println(lati);
    //Serial.println(longdi);
    gpsDone = false;
    for (int i = 0; i < 82; i++) {
      nmea[i] = {0};
    }

    counter = 0;
  }

}

void readGPS() {
  noInterrupts();
  while (Serial3.available()) {
    char nextChar = (char)Serial3.read();

    nmea[counter] = nextChar;
    counter++;

    if (nextChar == '\n') {
      gpsDone = true;
    }
  }
  interrupts();
}


void startSD() {
  pinMode(CS_PIN, OUTPUT);

  if (SD.begin())
  {
    Serial.println("SD initialized");
  } else
  {
    Serial.println("Couldn't start the SD card!");
    return;
  }
}


int makeFile(char filename[])
{
  file = SD.open(filename, FILE_WRITE);

  if (file)
  {
    Serial.println("File created successfully.");
    return 1;
  } else
  {
    Serial.println("Error while creating file.");
    return 0;
  }
}

int writeToFile(char text[])
{
  if (file)
  {
    file.println(text);
    Serial.println("Writing to file: ");
    Serial.println(text);
    return 1;
  } else
  {
    Serial.println("Couldn't write to file");
    return 0;
  }
}

void closeFile()
{
  if (file)
  {
    file.close();
    Serial.println("File closed");
  }
}

int openFile(char filename[])
{
  file = SD.open(filename);
  if (file)
  {
    Serial.println("File opened with success!");
    return 1;
  } else
  {
    Serial.println("Error opening file...");
    return 0;
  }
}

Any help would be majorly appreciated :slight_smile:

a few things:

if you are unlucky your nmea buffer has reached full capacity without finding the '\n' and you overflow.

--> you should check for buffer overflow in readGPS()

the   noInterrupts(); ...  interrupts(); thingy in the readGPS() function is not useful as this is called as an interrupt and by default an interrupt cannot be interrupted.

But where you need them - if you are unlucky - is if you get interrupted while you are playing with the counter or the nema buffer in the main loop. that section when you write to the SD is critical. as you use the buffer. you should probably create a critical section with no interrupt, duplicate your nmea buffer into another buffer, set counter to 0 and gpsDone to false then re-enable interrupt. This way you can start collecting new data while you are saving that duplicated buffer into the SD card.

Also once you have got the '\n' you should store a '\0' in the nmea buffer to ensure it's properly terminated.

if you do that then the code in the main loop()

 for (int i = 0; i < 82; i++) {
      nmea[i] = {0};
    }

    counter = 0;

can become just

counter = 0;

(and by the way in your code you should not do nmea[i] = {0}; but nmea[i] = '\0';While the result is the same (stores a zero into the array at position i) the {} thingy there is not for array value assignment. you use that only when you declare your variables to have initial values.)

so a bit of work to get this to work.