Issue with TinyGPS++ and SdFat

Hi,

I encountered a problem for a while, which I cannot solve.
I got an Arduino mega, an ethernet/microSD shield and a GPS.

I can easily get the GPS coordinates and have access to my SD card, write a file and add column labels on it.

However, this code is not working:

//Connect with pin 18 and 19
#include <TinyGPS++.h>
#include <SdFat.h>
#include <sdios.h>
//long   lat,lon; // create variable for latitude and longitude object
float lat,lng,alt;
TinyGPSPlus gps; // create gps object
#include "RTClib.h"
RTC_DS3231 rtc;
int32_t starttime;
const byte SDCARD_CS_PIN = 4;
SdFat sd;
SdFile file;
char FileDataname[12] = "GPS_dat1.csv";


void setup(){
Serial.begin(57600); // connect serial
Serial.println("The GPS Received Signal:");
Serial3.begin(9600); // connect gps sensor
if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }
    if (!sd.begin(SDCARD_CS_PIN, SPI_HALF_SPEED))
      {
        Serial.println("No SD");
      }
       if (!file.open(FileDataname,FILE_WRITE))
      {
        return;
      }
    file.close();
    if (sd.exists(FileDataname))
      {
        file.open(FileDataname,FILE_WRITE);   
        file.println("Year; Month; Day; Hour; Minutes; Second; Miliili; Lat; Lon; Alt");
        file.close();
      } 
starttime = millis();
}
 
void loop()
{
  if(Serial3.available())
    {
      getGPSdata();
    }
  file.open(FileDataname,  FILE_WRITE  );
  
} 

void getGPSdata() {
  if (millis()-starttime >= 1000)
    {   
      if(gps.encode(Serial3.read()))// encode gps data
        { 
          starttime = millis(); 
          Serial.print("Position: ");
          lat = gps.location.lat();
          lng = gps.location.lng();
          alt = gps.altitude.meters();
          //Latitude
          Serial.print("Latitude: ");
          Serial.print(lat,12);  
          Serial.print(",");  
          //Longitude
          Serial.print("Longitude: ");
          Serial.print(lng,12);
          Serial.print(","); 
          //Longitude
          Serial.print("Altitude: ");
          Serial.println(alt,2);
        }
      }
    else
      {
        gps.encode(Serial3.read());
        lat = 0;
        lng = 0;
        alt = 0;
      }
    DateTime now = rtc.now();
    int YY = now.year();
    int MO = now.month();
    int DD = now.day();
    int HH = now.hour();
    int MI = now.minute();
    int SS = now.second();
    file.print(YY);
    file.print("; ");
    file.print(MO);
    file.print("; ");
    file.print(DD);
    file.print("; ");
    file.print(HH);
    file.print("; ");
    file.print(MI);
    file.print("; ");
    file.print(SS);
    file.print("; ");
    file.print(millis());
    file.print("; ");
    file.print(lat,12);
    file.print("; ");
    file.print(lng,12);
    file.print("; ");
    file.println(alt,2);
    file.close();
}

When I comment file.close() at the end, the code is running (i.e. I got the GPS positions in the serial monitor). In this case, the data are written in the fileWhen I uncomment file.close(), nothing it running, unless I remove the SD: the position are then plotted in the serial monitor.

I'm a bit lost to solve this issue. Are there any compatibility issues between the librabries. Does any has a code runnign for this setup and those libraries?

Kind regards

Maybe there's a pin conflict - have you tried using a different serial port for the GPS?

HI,

Same behaviour with Serial 1 and Serial 2 instead of 3 ...

Kind regards

Here is your mistake:

Your file.close() is not paired with file.open within the getgpsdata(). So once the data label are written to file and the file closes, it never get opened again for data to write to and you start writing to an unopened file. Expect weird things to happen. You should open file in getgpsdata() and then write, close. Resources such as a file should be very carefully managed. Think about when you open it to write and then close right after. Make that your habit.

Hi,

I added the file.open at the begining of the getgpsdata function, not working either.

The file.close() at the end blocks everything ...
Maybe I should extract the coordinates in a function and write in anotehr function, but I have no idea how to generata a function that generates such outputs ...

Kind regards

There is no generic conflict between TinyGPS++ and the SD libraries, they work together just fine for me.

You are in your code, maybe making an (incorrect) assumption that every time a new sentence has encoded, then there is updated fix information to write and display. Normally this is not the case, there are around 10 different sentences output by a typical GPS every second, only 2 of them have fix information.

Read the GPS like this;

bool gpsWaitFix(uint16_t waitSecs)
{
  //waits a specified number of seconds for a fix, returns true for updated fix
  uint32_t startmS, waitmS;
  uint8_t GPSchar;

  Serial.print(F("Wait GPS Fix "));
  Serial.print(waitSecs);
  Serial.println(F(" seconds"));

  waitmS = waitSecs * 1000;                               //convert seconds wait into mS

  startmS = millis();

  while ( (uint32_t) (millis() - startmS) < waitmS)       //allows for millis() overflow
  {
    if (GPSserial.available() > 0)
    {
      GPSchar = GPSserial.read();
      gps.encode(GPSchar);
      Serial.write(GPSchar);
    }

    if (gps.location.isUpdated() && gps.altitude.isUpdated() && gps.date.isUpdated())
    {
      endFixmS = millis();                                //record the time when we got a GPS fix
      return true;
    }
  }
  return false;
}

Call the routine like this;

if (gpsWaitFix(5))
  {
    //we have a new GPS fix, so lets display the info and store it to SD etc
   Serial.print(F("We have a new GPS Fix "));
  }
  else
  {
   //ooops the GPS is not getting a fix in the 5 seconds we gave it, something is wrong
   //but at least the program has not locked up waiting for a fix  
  Serial.print(F("No GPS Fix !"));
  }

Add file.open() immediately before this line:

    file.print(YY);

Post your new code.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.