Gps logger

Hi my name is Leonardo and I was wondering if anyone can help with my gps logger. I have made a sketch but I only get to log the first line of data to my sd card and I can`t find the problem.
The sketch is the problem, both the gps and the sd shield are ok.

#include <SD.h>

#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(6, 5); // RX, TX (TX not used)
const int sentenceSize = 80;

char sentence[sentenceSize];

#define LOG_INTERVAL 100

const int chipSelect = 10;
File logfile;
long idd = 0;
long ids = 0;
long idm = 0;
long idh = 0;

void error(char *str)
{
Serial.print("error: ");
Serial.println(str);

while(1);
}

void setup()
{
Serial.begin(9600);
gpsSerial.begin(9600);

Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);

// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card Failed or not present");
return;
}
Serial.println("card initialized.");

// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}

if (! logfile) {
error("couldnt create file");
}

Serial.print("Logging to: ");
Serial.println(filename);
}

void loop()
{
static int i = 0;
if (gpsSerial.available())
{
char ch = gpsSerial.read();
if (ch != '\n' && i < sentenceSize)
{
sentence = ch;

  • i++;*
  • }*
  • else*
  • {*
    _ sentence = '\0';_
    * i = 0;*
    * displayGPS();*
    * }*
    * }*

}
void displayGPS()
{
* char field[20];*
* getField(field, 0);*
* if (strcmp(field, "$GPRMC") == 0)*
* {*
* Serial.print("Tiempo: ");*
* getField(field, 1);*
* logfile.print(field);*
* logfile.print("\t");*
* Serial.println(field);*
* Serial.print("Lat: ");*
* getField(field, 3); // number*
* logfile.print(field);*
* logfile.print("\t");*
* Serial.print(field);*
* getField(field, 4); // N/S*
* logfile.print(field);*
* logfile.print("\t");*
* Serial.println(field);*
* Serial.print("Long: ");*
* getField(field, 5); // number*
* logfile.print(field);*
* logfile.print("\t");*
* Serial.print(field);*
* getField(field, 6); // E/W*
* logfile.print(field);*
* logfile.print("\t");*
* Serial.println(field);*
* Serial.print("Velocidad: ");*
* getField(field, 7);*
* logfile.println(field);*
* logfile.close();*
_ Serial.println(field) * 1.854;_

* }*
}
void getField(char* buffer, int index)
{
* int sentencePos = 0;*
* int fieldPos = 0;*
* int commaCount = 0;*
* while (sentencePos < sentenceSize)*
* {*
* if (sentence[sentencePos] == ',')*
* {*
* commaCount ++;*
* sentencePos ++;*
* }*
* if (commaCount == index)*
* {*
* buffer[fieldPos] = sentence[sentencePos];*
* fieldPos ++;*
* }*
* sentencePos ++;*
* }*
* buffer[fieldPos] = '\0';*
}

First, you need to modify your post. Select the code and press the # icon. That puts your code between tags that tell the forum software that [ i ] is not an italics tag, for instance.

You open the file in setup() and close it as soon as you write the first line to it. I don't see that you open it again. It's pretty hard to write to a closed file.

Exactly thats the problem, but if I remove the logfile.close(); command it doesn`t log anything at all, any clue why this is?

here is the code

#include <SD.h>

#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(6, 5); // RX, TX (TX not used)
const int sentenceSize = 80;

char sentence[sentenceSize];

#define LOG_INTERVAL 100

const int chipSelect = 10;
File logfile;
long idd = 0;
long ids = 0;
long idm = 0;
long idh = 0;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  while(1);
}

void setup()
{
  Serial.begin(9600);
  gpsSerial.begin(9600);
  
 
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card Failed or not present");
    return;
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);
}

void loop()
{
  static int i = 0;
  if (gpsSerial.available())
  {
    char ch = gpsSerial.read();
    if (ch != '\n' && i < sentenceSize)
    {
      sentence[i] = ch;
      i++;
    }
    else
    {
     sentence[i] = '\0';
     i = 0;
     displayGPS();
    }
  }
  
}

void displayGPS()
{
  char field[20];
  getField(field, 0);
  if (strcmp(field, "$GPRMC") == 0)
  {
    Serial.print("Tiempo: ");
    getField(field, 1);
    Serial.println(field);
    logfile.print(field);
    logfile.print("\t");   
    
    Serial.print("Lat: ");
    getField(field, 3);  // number
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");
    getField(field, 4); // N/S
    Serial.println(field);
    logfile.print(field);
    logfile.print("\t");
    
    Serial.print("Long: ");
    getField(field, 5);  // number
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");
    getField(field, 6);  // E/W
    Serial.println(field);
    logfile.print(field);
    logfile.print("\t");
    
    Serial.print("Velocidad: ");
    getField(field, 7);
    Serial.println(field) * 1.854;
    logfile.println(field);
    logfile.close();
  }
}

void getField(char* buffer, int index)
{
  int sentencePos = 0;
  int fieldPos = 0;
  int commaCount = 0;
  while (sentencePos < sentenceSize)
  {
    if (sentence[sentencePos] == ',')
    {
      commaCount ++;
      sentencePos ++;
    }
    if (commaCount == index)
    {
      buffer[fieldPos] = sentence[sentencePos];
      fieldPos ++;
    }
    sentencePos ++;
  }
  buffer[fieldPos] = '\0';
}

Is there some part of IN THE SAME FUNCTION that is beyond your understanding? Quit opening the file in setup(). Open it in displayGPS instead. And pick a better name for that function.

If I do that, it will log several files with diferent names with only one line of data, I have allready tryed.

If I do that, it will log several files with diferent names with only one line of data, I have allready tryed.

Then you did it wrong. Determining the file name in setup makes sense. Actually open the file in the displayGPS() function. Then, write to it, and close it.

I have solved the problem, I just moved the function void gpsdisplay into the void loop and replace the logfile.close() with the function logfile.flush().
Now it works just fine, thank to all for the help.

Here is the code for anyone to use it

#include <SD.h>

#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(6, 5); // RX, TX (TX not used)
const int sentenceSize = 80;

char sentence[sentenceSize];

#define LOG_INTERVAL 100

const int chipSelect = 10;
File logfile;
long idd = 0;
long ids = 0;
long idm = 0;
long idh = 0;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  while(1);
}

void setup()
{
  Serial.begin(9600);
  gpsSerial.begin(9600);
  
 
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card Failed or not present");
    return;
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);
}

void loop()
{
  static int i = 0;
  if (gpsSerial.available())
  {
    char ch = gpsSerial.read();
    if (ch != '\n' && i < sentenceSize)
    {
      sentence[i] = ch;
      i++;
    }
    else
    {
     sentence[i] = '\0';
     i = 0;
     char field[20];
      getField(field, 0);
  if (strcmp(field, "$GPRMC") == 0)
  {
    
    Serial.print("Tiempo: ");
    getField(field, 1);
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");   
    
    Serial.print("Lat: ");
    getField(field, 3);  // number
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");
    getField(field, 4); // N/S
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");
    
    Serial.print("Long: ");
    getField(field, 5);  // number
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");
    getField(field, 6);  // E/W
    Serial.print(field);
    logfile.print(field);
    logfile.print("\t");
    
    Serial.print("Velocidad: ");
    getField(field, 7);
    Serial.println(field) * 1.854;
    logfile.println(field);
    logfile.flush();   
  }
    }
  }
  
}

void getField(char* buffer, int index)
{
  int sentencePos = 0;
  int fieldPos = 0;
  int commaCount = 0;
  while (sentencePos < sentenceSize)
  {
    if (sentence[sentencePos] == ',')
    {
      commaCount ++;
      sentencePos ++;
    }
    if (commaCount == index)
    {
      buffer[fieldPos] = sentence[sentencePos];
      fieldPos ++;
    }
    sentencePos ++;
  }
  buffer[fieldPos] = '\0';
}

Now it works just fine, thank to all for the help.

Except that you never actually close the file, so it is not safe to ever power down the Arduino or remove the SD card.

And why is that?

b/c you didn't close the file. It's similar to the same problem one has when removing an SD card without ejecting it. Data is transferring between the microcontroller and the card. you run the risk of corrupting the data on the card.

Doing what you are doing is fine so long as reliability is irrelevant