GPS logger fail... Help? [SOLVED]

Hi I have an arduino mega which is meant to log data from a gps (EM406A) and write it to a SD-card (Sandisk 2GB SD)
And also if possible dump the files on the sdcard trough the usb cable if connected to a Computer/phone with a serial terminal open. 8)

For now I have only made the part that logs from GPS to SD-card.

And im using a program that reads from the sdcard onto the pc (SD Dumpfile in arduino examples)

But…

Its not working :’(

Its nothing wrong with the GPS because i get a nice clean NMEA output when i use my DIRECT
GPS-ARDUINIO-PC program.

Can you figure out what I am doing wrong?
Thanks :smiley:

DIRECT tranfer program:

/*
  Example 17.1
 Display any data coming out of the GPS receiver in the serial monitor box
 tronixstuff.com/tutorials > Chapter 17
 */

// as the GPS module sends data out serially, we just pick it up character by
// character and repeat it to the serial output

void setup()
{
  Serial.begin(9600);
  Serial1.begin(4800);
}
void loop()
{
  byte a;
    if ( Serial1.available() > 0 )
  {
    a = Serial1.read(); // get the byte of data from the GPS
    Serial.write(a);
  }
}

DIRECT transfer output:

Via SD-card write program:

#include <SPI.h>                                                    //Made for Arduino Mega 2560
#include <SD.h>
File myFile;
const int chipSelect = 53;
void setup() {
  Serial1.begin(4800);                                              // Setting up baud for GPS
  
  if (SD.exists("DATALOG.txt")) {                                   // If there is a log on the SD-card:
    SD.remove("DATALOG.txt");                                       // Remove any previous logs on SD-card
    myFile = SD.open("DATALOG.txt", FILE_WRITE);                    // Create new log on SD-card
    myFile.close();                                                 // Close log on SD-card
    
  } else {                                                          // If the SD-card is empty:
    myFile = SD.open("DATALOG.txt", FILE_WRITE);                    // Creating new file on SD-card
    myFile.close();                                                 // Closing file on SD-card
  }
}

void loop() {
  byte a;
    if ( Serial1.available() > 0 ) {                                // If GPS has sent data:
      File dataFile = SD.open("DATALOG.txt", FILE_WRITE);           // Open Log file on SD-card
      a = Serial1.read(); // get the byte of data from the GPS      // Read byte from Serial port
      dataFile.write(a);                                            // Write into SD-card
      dataFile.close();                                             // Close log file on SD-card
   }
}

VIA SD-card read program:

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

const int chipSelect = 53;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt");

  // if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      Serial.write(dataFile.read());
    }
    dataFile.close();
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

void loop() {
}

VIA SD-card output:

This. Be sure to read the following sections. It's a very common problem, and one of the reasons I wrote NeoGPS.

Cheers, /dev

ok... I have installed NeoGPS... From my point of view;¨ in the doSomeWork loop You print out the gps data with:

trace_all( gps, fix_data );

And then clear the data again with:

  gps.data_init();
  fix_data.init();

So i tried this:

static void doSomeWork()
{
  // Print all the things!

  trace_all( gps, fix_data );
  File dataFile = SD.open("DATALOG.txt", FILE_WRITE);    // Open Log file on SD-card
  dataFile.write(fix_data);                              // Write into SD-card
  dataFile.close();                                      // Close log file on SD-card
  // Clear out what we just printed.  If you need this data elsewhere,
  //   don't do this.

  gps.data_init();
  fix_data.init();

} // doSomeWork

But it did not work :(

exit status 1 no matching function for call to 'SDLib::File::write(gps_fix&)'

And What format is the output?

3,2016-04-02 20:37:14.00,591110567,59575533,20468,270,,,,335,0,21639,
3,2016-04-02 20:37:15.00,591110533,59575517,21444,790,,,,338,0,21836,
3,2016-04-02 20:37:16.00,591110500,59575500,20924,410,,,,341,0,22033,
3,2016-04-02 20:37:17.00,591110483,59575483,21051,640,,,,347,0,22419,
3,2016-04-02 20:37:18.00,591110467,59575483,21141,670,,,,350,0,22616,
3,2016-04-02 20:37:19.00,591110450,59575467,21317,840,,,,353,0,22813,
3,2016-04-02 20:37:20.00,591110433,59575450,20954,580,,,,356,0,23010,
3,2016-04-02 20:37:21.00,591110433,59575467,20397,510,,,,359,0,23207,
3,2016-04-02 20:37:22.00,591110417,59575467,20291,510,,,,365,0,23591,
3,2016-04-02 20:37:23.00,591110400,59575450,20421,530,,,,368,0,23786,
3,2016-04-02 20:37:24.00,591110383,59575450,20375,480,,,,371,0,23981,
3,2016-04-02 20:37:25.00,591110367,59575467,20161,530,,,,374,0,24176,
3,2016-04-02 20:37:26.00,591110367,59575467,19822,510,,,,377,0,24371,
3,2016-04-02 20:37:27.00,591110350,59575467,20267,490,,,,383,0,24755,
3,2016-04-02 20:37:28.00,591110333,59575483,20320,510,,,,386,0,24950,
3,2016-04-02 20:37:29.00,591110317,59575483,19754,500,,,,389,0,25145,
3,2016-04-02 20:37:30.00,591110317,59575500,20397,500,,,,392,0,25340,
3,2016-04-02 20:37:31.00,591110300,59575500,20284,520,,,,395,0,25535,
3,2016-04-02 20:37:32.00,591110300,59575517,19974,500,,,,401,0,25919,
3,2016-04-02 20:37:33.00,591110283,59575533,20235,450,,,,404,0,26114,
3,2016-04-02 20:37:34.00,591110283,59575533,19870,470,,,,407,0,26309,
3,2016-04-02 20:37:35.00,591110267,59575550,20145,470,,,,410,0,26504,
3,2016-04-02 20:37:36.00,591110267,59575567,20349,460,,,,413,0,26699,
3,2016-04-02 20:37:37.00,591110267,59575567,20044,430,,,,419,0,27083,
3,2016-04-02 20:37:38.00,591110250,59575583,20010,410,,,,422,0,27278,
3,2016-04-02 20:37:39.00,591110250,59575600,19969,420,,,,425,0,27473,
3,2016-04-02 20:37:40.00,591110250,59575600,20442,410,,,,428,0,27668,

So i tried this… But it did not work

LOL, welcome to the world of example programs.

One thing you’ll need to be able to do is find where things are implemented in the code. If your editor supports multiple windows and searching in all open files, you could find the routine trace_all. If not, then you might want to get a file-searching utility. I use WinGrep, but I don’t think you’re on Windoze. linux has a command line grep, but if you’re on a Mac, I don’t know what to suggest. Learning how to use these kind of tools will pay off anytime you want to know “what does that routine do?” or “how does it do that?” Believe it or not, there are bugs in those routines, just waiting for you to find. :slight_smile:

TL;DR - Streamers.CPP has these routines. They are intended to be examples of how to access various pieces of the Data Model. They show one way to print them in a human-readable format. You can do something different.

Inside trace_all line 302, it does this to write the fix information:

  trace << fix;

This is a C++ convention for “streaming” data to an output device called “trace”. Above this, at line 100, you’ll see the definition of the “<<” operator that takes a fix structure as the 2nd argument. This routine writes all the pieces of fix. There are two sections: one for floating-point output and one for integer output. The default is to write the integer values, but you can uncomment this line

    //#define USE_FLOAT

…to see what the floating-point output looks like.

You can also copy portions of these routines into your sketch. Then you can pick which pieces you want and what order you want them in the output stream (i.e., SD file).

If you want to try using this exact example to write into your SD file, do this:

static void doSomeWork()
{
  File dataFile = SD.open("DATALOG.txt", FILE_WRITE);  // Open Log file on SD-card
  dataFile << fix_data;                                // Write into SD-card
  dataFile.close();                                    // Close log file on SD-card

  gps.data_init();
  fix_data.init();

} // doSomeWork

If you’re not doing anything else in your sketch, this will work, but it’s fairly slow to open and close the file every time you write one line. You could open the file once, write several times (e.g., 10 times = 10 seconds), then flush it or close/reopen it. If you only flush it, it’s safest to implement some way to close it, like with a button press or Serial command. This will also reduce “wear” on the SD card.

There are many subtle ways that GPS logging can go wrong. Writing too much or doing something else at the wrong time are just two of them. Fortunately, there are several ways to solve those problems.

Cheers,
/dev

Oh… :stuck_out_tongue:

Is the scentences your using now convertable? (gpsvisualizer.com)
I thought they were not not so i wrote this but i got no clue how to extract the info from your code…
I tried things like: gps.fix().dateTime but it didnt work :frowning:
The attached code will dump the sd log in the serial monitor when i connected it to a pc,
But as you can see i dont know how to extract that info so i only tried to make a $GPGGA

logger.ino (12.6 KB)

I tried things like “gps.fix().dateTime” but it didnt work .

Does that mean you tried

datafile.write( gps.fix().dateTime );

Yeah, that won’t work…

When the thing you want to write is a structure, you can either use the example streaming I provide:

datafile << gps.fix().dateTime;

Or you can write the pieces in whatever order you want. Here’s the hhmmss I think you are trying to write from your sketch:

if (gps.fix().valid.time) {
  if (gps.fix().dateTime.hours < 10)
    datafile.print( '0' );
  datafile.print( gps.fix().dateTime.hours );
  if (gps.fix().dateTime.minutes < 10)
    datafile.print( '0' );
  if (gps.fix().dateTime.minutes < 10)
    datafile.print( '0' );
  datafile.print( gps.fix().dateTime.minutes );
}
datafile.print( ',' );

Those are all individual integers, not a structure or class. Note how it prints the leading zeroes if necessary, and how it only writes the comma if there is no valid time, just like a real GPS device.

I do not recommend writing the lat/lon in the funky NMEA ddmm.mmmm format. You could write the signed floating-point values like this:

if (gps.fix().valid.location) {
  datafile.print( gps.fix().latitude(), 6 );
  datafile.print( ',' );
  datafile.print( gps.fix().longitude(), 6 );
}

That is how Streamers.CPP does it when USE_FLOAT is uncommented. Negative latitude is S, negative longitude is W. You lose a little precision when you use floating-point. You could write the integer values like this:

if (gps.fix().valid.location) {
  datafile.print( gps.fix().latitudeL() );
  datafile.print( ',' );
  datafile.print( gps.fix().longitudeL() );
}

They are degrees x 10^7. Whatever reads those integers (a spreadsheet program? a python script?) would simply divide by 10000000 to get the actual degrees.

So, do you just need the raw $GPGGA sentences written to the card? If that’s all you need, there’s no reason to parse it with NeoGPS. There are simpler ways to do this.

If you need the values to compare or analyze in the sketch, then you do need to parse it with a GPS library. For example, are you watching the lat/lon to see if it gets close to some position? Or checking the date/time for some alarm? Or displaying some fields on a LCD?

Cheers,
/dev

yes… i need the raw data from the gps onto the card.
but as the first post says, reading from gps onto sd doesnt work…
So what do you mean:
[/quote]
If that’s all you need, there’s no reason to parse it with NeoGPS. There are simpler ways to do this.
[/quote]

Eirikki211299:
But…

Its not working :’(

Via SD-card write program:

#include <SPI.h>                                                    //Made for Arduino Mega 2560

#include <SD.h>
File myFile;
const int chipSelect = 53;
void setup() {
  Serial1.begin(4800);                                              // Setting up baud for GPS
 
  if (SD.exists(“DATALOG.txt”)) {                                  // If there is a log on the SD-card:
    SD.remove(“DATALOG.txt”);                                      // Remove any previous logs on SD-card
    myFile = SD.open(“DATALOG.txt”, FILE_WRITE);                    // Create new log on SD-card
    myFile.close();                                                // Close log on SD-card
   
  } else {                                                          // If the SD-card is empty:
    myFile = SD.open(“DATALOG.txt”, FILE_WRITE);                    // Creating new file on SD-card
    myFile.close();                                                // Closing file on SD-card
  }
}

void loop() {
  byte a;
    if ( Serial1.available() > 0 ) {                                // If GPS has sent data:
      File dataFile = SD.open(“DATALOG.txt”, FILE_WRITE);          // Open Log file on SD-card
      a = Serial1.read(); // get the byte of data from the GPS      // Read byte from Serial port
      dataFile.write(a);                                            // Write into SD-card
      dataFile.close();                                            // Close log file on SD-card
  }
}




VIA SD-card read program:



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

const int chipSelect = 53;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

Serial.print(“Initializing SD card…”);

// see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println(“Card failed, or not present”);
    // don’t do anything more:
    return;
  }
  Serial.println(“card initialized.”);

// open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open(“datalog.txt”);

// if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      Serial.write(dataFile.read());
    }
    dataFile.close();
  }
  // if the file isn’t open, pop up an error:
  else {
    Serial.println(“error opening datalog.txt”);
  }
}

void loop() {
}




VIA SD-card output:

![|500x267](http://s18.postimg.org/xxvaunpmx/SD_logger_output.png)

So what do you mean,

      "If that's all you need, there's no reason to parse it
       with NeoGPS.  There are simpler ways to do this."

I mean that if your sketch doesn't really care what the bytes represent, it could just save the bytes on the SD card. They will be parsed by something else that reads the SD card.

First, you should identify which sentences you want to keep. GPS devices can spit out a lot of stuff, but I doubt you need the entire satellite constellation (GSA and GSVs). Look here to see which sentences provide which pieces of information. Do you just need lat/lon and time? Then you only need the RMC sentence (not the GGA). What sentences do you need?

This will determine approximately how may bytes you need to save each second, about 100 bytes per sentence. This will also determine how you configure the device (if possible), or what sentences you should ignore (if not possible). The simplest program can save about 500 characters per second (5 sentences). So be stingy, or be prepared to work harder on the program.

The structure of a simple logging program will be something like this:

void setup()
{
  gps serial.begin( baud rate )
  gps serial.print( configuration commands )
  check SD card
  open sdFile
  recordsWritten = 0;
  lastRx = millis();
  LED off
}

void loop()
{
  if (gps serial available) {
    sdFile.write( gps serial.read() ); // save one character
    lastRx = millis();
    LED on;

  } else if (millis() - lastRx > 10) { // ms

    // GPS has been quiet for a while, flush what we have so far.
    // This will keep the above 'write' from taking too long
    // and causing us to lose characters.

    sdFile.flush();

    LED off

    // See if the user wants to take the card.
    if (console serial.available  or  button pressed  or what?) {
      // user wants to stop
      close sdFile;
      while (true)
        ; // hang here.  Card is safe to remove.  Reset to restart.
    }

    // Still logging.  Close/reopen file every so often.
    recordsWritten++;
    if (recordsWritten > 10) {
      close sdFile;
      open sdFile;
      recordsWritten = 0;
    }
  }
}

This is fairly safe, as far as keeping the SD card clean. You can also see an LED flash when the GPS sends something, and when it's safe to remove the card. No GPS library required.

Cheers, /dev

That code you put in the end of the code worked perfectly, modded it a little too:

#include <TinyGPS.h>
#include <SD.h>
#define PC Serial
#define PC_Baud 9600
#define GPS Serial1
#define GPS_Baud 4800
#define SDFILE "datalog.txt"
TinyGPS gps;
File dataFile;
int ChipSelect = 53;
int recordsWritten = 0;
int ButtonPin = 49;
int ledPin = 13;
int lastRx;

void setup() {
  PC.begin(PC_Baud);                                             // Setting up baud for PC
  GPS.begin(GPS_Baud);                                              // Setting up baud for GPS
  pinMode(ledPin, OUTPUT);                                              // Activating status LED pin
  pinMode(ButtonPin, INPUT_PULLUP);
  digitalWrite(13, LOW);
  PC.println("Initializing SD card...");

  SD.begin(ChipSelect);                                             // Initializing SD-card
  if (SD.exists(SDFILE)) {                                   // If there is a log on the SD-card:
    PC.println("Found " SDFILE "!");
   } else {                                                          // If the SD-card is empty:
    PC.print(SDFILE " missing!");
    PC.print("Creating " SDFILE "...  ");
    dataFile = SD.open(SDFILE, FILE_WRITE);                    // Creating new file on SD-card
    dataFile.close();                                                 // Closing file on SD-card
    PC.println("Done!");
   }
  PC.println("Card Intitialized!" "\n");
  SD.remove(SDFILE);
  dataFile = SD.open(SDFILE);
  lastRx = millis();
}

void loop() {
  if (GPS.available()) {
    dataFile.write(GPS.read()); // save one character
    lastRx = millis();
    digitalWrite(ledPin, HIGH);
  } else if (millis() - lastRx > 10) { // ms
    // GPS has been quiet for a while, flush what we have so far.
    // This will keep the above 'write' from taking too long
    // and causing us to lose characters.
    dataFile.flush();
    digitalWrite(ledPin, LOW);

    // See if the user wants to take the card.
    if (digitalRead(ButtonPin) == LOW) {
        // user wants to stop
        dataFile.close();
        while (true) {  // hang here.  Card is safe to remove.  Reset to restart.
            // fade in from min to max in increments of 5 points:
            for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
            // sets the value (range from 0 to 255):
            analogWrite(ledPin, fadeValue);
            // wait for 30 milliseconds to see the dimming effect
            delay(30);
            }

            // fade out from max to min in increments of 5 points:
            for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
            // sets the value (range from 0 to 255):
            analogWrite(ledPin, fadeValue);
            // wait for 30 milliseconds to see the dimming effect
            delay(30);
            }
        }
    }
    
    // Still logging.  Close/reopen file every so often.
    recordsWritten++;
    if (recordsWritten > 10) {
      dataFile.close();
      dataFile = SD.open(SDFILE);
      recordsWritten = 0;
    }
  }
}

Now i can have this setup as a standalone tracker or a stationary gps which averages out the data to get exact coordinates
THANKS! :smiley: :smiley: :smiley:

You don't need TinyGPS. You can just delete those two lines: the include and the variable.

Glad it worked, /dev

Well… shit :astonished:

Eirikki211299:
That code you put in the end of the code worked perfectly

It didnt work after all (No offence)
It ran but created no file at all :’(
Slightly updated version: (still doesent work)

#include <TinyGPS.h>
#include <SD.h>
#include <SPI.h>
#define PC Serial
#define PC_Baud 9600
#define GPS Serial1
#define GPS_Baud 4800
#define SDFILE "datalog.txt"
TinyGPS gps;
File dataFile;
int ChipSelect = 53;
int recordsWritten = 0;
int ButtonPin = 49;
int ledPin = 13;
int lastRx;

void setup() {
  PC.begin(PC_Baud);                                             // Setting up baud for PC
  GPS.begin(GPS_Baud);                                              // Setting up baud for GPS
  pinMode(ledPin, OUTPUT);                                              // Activating status LED pin
  pinMode(ButtonPin, INPUT_PULLUP);
  digitalWrite(13, LOW);
  PC.println("Initializing SD card...");

  SD.begin(ChipSelect);                                             // Initializing SD-card
  if (SD.exists(SDFILE)) {                                   // If there is a log on the SD-card:
    PC.println("Found " SDFILE "!");
   } else {                                                          // If the SD-card is empty:
    PC.print(SDFILE " missing!");
    PC.print("Creating " SDFILE "...  ");
    dataFile = SD.open(SDFILE, FILE_WRITE);                    // Creating new file on SD-card
    dataFile.close();                                                 // Closing file on SD-card
    PC.println("Done!");
   }
  PC.println("Card Intitialized!" "\n");
  SD.remove(SDFILE);
  dataFile = SD.open(SDFILE);
  lastRx = millis();
}

void loop() {
  if (GPS.available()) {
    dataFile.write(GPS.read()); // save one character
    lastRx = millis();
    digitalWrite(ledPin, HIGH);
  } else if (millis() - lastRx > 10) { // ms
    // GPS has been quiet for a while, flush what we have so far.
    // This will keep the above 'write' from taking too long
    // and causing us to lose characters.
    dataFile.flush();
    digitalWrite(ledPin, LOW);

    // See if the user wants to take the card.
    if (digitalRead(ButtonPin) == LOW) {
        // user wants to stop
        dataFile.close();
        while (true) {  // hang here.  Card is safe to remove.  Reset to restart.
            // fade in from min to max in increments of 5 points:
            for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
            // sets the value (range from 0 to 255):
            analogWrite(ledPin, fadeValue);
            // wait for 30 milliseconds to see the dimming effect
            delay(30);
            }

            // fade out from max to min in increments of 5 points:
            for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
            // sets the value (range from 0 to 255):
            analogWrite(ledPin, fadeValue);
            // wait for 30 milliseconds to see the dimming effect
            delay(30);
            }
        }
    }
    
    // Still logging.  Close/reopen file every so often.
    recordsWritten++;
    if (recordsWritten > 10) {
      dataFile.close();
      dataFile = SD.open(SDFILE);
      recordsWritten = 0;
    }
  }
}

1) Change line 38 in setup():

  dataFile = SD.open(SDFILE, FILE_WRITE);

This opens the file for writing, not reading (the default).

2) Change line 81 in loop():

      dataFile = SD.open( SDFILE, O_WRITE | O_APPEND | O_CREAT );

This opens the already-created file for "appending", not replacing.

3) DELETE THE TINYGPS STUFF ON LINES 2 and 10.

This removes a bunch of code and RAM, and would confuse someone who reads your code later. "Why is that there?" Lots of people use (or try to use) TinyGPS, but it just isn't structured for this kind of application. It's not needed at all for simple logging.

Cheers, /dev

Thanks! now i have coded it and put it in a case and even tested it, it works perfectly: :smiley:

#include <SD.h> 
#include <SPI.h>
#define PC Serial
#define PC_Baud 9600
#define GPS Serial1
#define GPS_Baud 4800
#define SDFILE "datalog.txt"
File dataFile;
int ChipSelect = 53;
int recordsWritten = 0;
int ButtonPin = 49;
int ledPin = 13;
int lastRx;

void setup() {
  PC.begin(PC_Baud);                                             // Setting up baud for PC
  GPS.begin(GPS_Baud);                                              // Setting up baud for GPS
  pinMode(ledPin, OUTPUT);                                              // Activating status LED pin
  pinMode(ButtonPin, INPUT_PULLUP);
  digitalWrite(13, LOW);
  PC.println("Initializing SD card...");

  SD.begin(ChipSelect);                                             // Initializing SD-card
  if (SD.exists(SDFILE)) {                                   // If there is a log on the SD-card:
    PC.println("Found " SDFILE "!");
   } else {                                                          // If the SD-card is empty:
    PC.print(SDFILE " missing!");
    PC.print("Creating " SDFILE "...  ");
    dataFile = SD.open(SDFILE, FILE_WRITE);                    // Creating new file on SD-card
    dataFile.close();                                                 // Closing file on SD-card
      PC.println("Done!");
   }
  PC.println("Card Intitialized!" "\n");
  SD.remove(SDFILE);
  dataFile = SD.open(SDFILE, FILE_WRITE);
  lastRx = millis();
}

void loop() {
  if (GPS.available()) {
    dataFile.write(GPS.read()); // save one character
    lastRx = millis();
    digitalWrite(ledPin, HIGH);
  } else if (millis() - lastRx > 10) { // ms
    // GPS has been quiet for a while, flush what we have so far.
    // This will keep the above 'write' from taking too long
    // and causing us to lose characters.
    dataFile.flush();
    digitalWrite(ledPin, LOW);

    // See if the user wants to take the card.
    if (digitalRead(ButtonPin) == LOW) {
        // user wants to stop
        dataFile.close();
        while (true) {  // hang here.  Card is safe to remove.  Reset to restart.
            // fade in from min to max in increments of 5 points:
            for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
            // sets the value (range from 0 to 255):
            analogWrite(ledPin, fadeValue);
            // wait for 30 milliseconds to see the dimming effect
            delay(30);
            }

            // fade out from max to min in increments of 5 points:
            for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
            // sets the value (range from 0 to 255):
            analogWrite(ledPin, fadeValue);
            // wait for 30 milliseconds to see the dimming effect
            delay(30);
            }
        }
    }
    
    // Still logging.  Close/reopen file every so often.
    recordsWritten++;
    if (recordsWritten > 10) {
      dataFile.close();
      dataFile = SD.open( SDFILE, O_WRITE | O_APPEND | O_CREAT );
      recordsWritten = 0;
    }
  }
}

I logged as a test:

Outside:

Inside:

THX! :smiley: :smiley: :smiley:

You’re welcome. And there’s still room for your lunch!

But, dangit, you still have TinyGPS in there:

#include <TinyGPS.h>
TinyGPS gps;

Ugh. Please modify your post (under the More button in the lower right), and delete those two lines.

Thanks,
/dev

#include <SD.h> 
#include <SPI.h>
#define PC Serial
#define PC_Baud 9600
#define GPS Serial1
#define GPS_Baud 4800
#define SDFILE "datalog.txt"
File dataFile;
int ChipSelect = 53;
int recordsWritten = 0;
int ButtonPin = 22;
int ledPin = 13;
int lastRx;
Sd2Card card;

void setup() {
  PC.begin(PC_Baud);                                             // Setting up baud for PC
  GPS.begin(GPS_Baud);                                           // Setting up baud for GPS
  pinMode(ledPin, OUTPUT);                                              // Activating status LED pin
  pinMode(ButtonPin, INPUT_PULLUP);
  digitalWrite(ledPin, LOW);
  PC.println("Initializing SD card...");
  //if (!SD.begin(ChipSelect)) {
  //  HALT();
  if (SD.exists(SDFILE)) {                                   // If there is a log on the SD-card:
    PC.println("Found " SDFILE "!");
  } else {                                                          // If the SD-card is empty:
    PC.print(SDFILE " missing!");
    PC.print("Creating " SDFILE "...  ");
    dataFile = SD.open(SDFILE, FILE_WRITE);                    // Creating new file on SD-card
    dataFile.close();                                                 // Closing file on SD-card
    }
    PC.println("Card Intitialized!" "\n");
    Serial.print("Card type: ");
    switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }
  SD.remove(SDFILE);
  dataFile = SD.open(SDFILE, FILE_WRITE);
  lastRx = millis();
}


void loop() {
  if (GPS.available()) {
    dataFile.write(GPS.read()); // save one character
    lastRx = millis();
    digitalWrite(ledPin, HIGH);
  } else if (millis() - lastRx > 10) { // ms
    // GPS has been quiet for a while, flush what we have so far.
    // This will keep the above 'write' from taking too long
    // and causing us to lose characters.
    dataFile.flush();
    digitalWrite(ledPin, LOW);

    // See if the user wants to take the card.
    if (digitalRead(ButtonPin) == LOW) {
        // user wants to stop
        dataFile.close();
        HALT();
        }
    }
    
    // Still logging.  Close/reopen file every so often.
    recordsWritten++;
    if (recordsWritten > 10) {
      dataFile.close();
      dataFile = SD.open( SDFILE, O_WRITE | O_APPEND | O_CREAT );
      recordsWritten = 0;
    }
}

void HALT(){
  while (true) {  // hang here.  Card is safe to remove.  Reset to restart.
    // fade in from min to max in increments of 5 points:
    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
    }

    // fade out from max to min in increments of 5 points:
    for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
    }
  }
}

The program looses bytes very often, resulting to overlapping scentences and looses commas which in return the info that i have been all the way down to ghana, africa :stuck_out_tongue:
cant belief im saying this again…
but…
Help?
:stuck_out_tongue:

My approach would be to just connect TX on the GPS to RX on the tiny SparkFun OpenLog (connect the grounds, of course). Record up to 64 gigabytes of text without loss of characters! I use these all the time in various data loggers and they are extremely reliable. OpenLog can easily be reprogrammed with the Arduino environment.

One oversight by the Sparkfun folks is that RX on the OpenLog is unprotected, 3.3V only, so I put a 4.7K resistor in the lead when connecting it to 5V TX lines.

the info that i have been all the way down to ghana, africa

Post a photo and we will believe you!

Since you have a Mega, it’s probably easiest to increase the rx buffer in HardwareSerial.h or .cpp (depends on IDE version). While the SD card is busy writing, the input buffer overflows. Again, it’s a common problem, and it’s very dependent on your card’s performance.

Those files are in the distribution directory, something like

   <Arduino.exe directory>/hardware/arduino/avr/cores/arduino

Just change SERIAL_BUFFER_SIZE (older IDE versions do not separate TX/RX sizes) or SERIAL_RX_BUFFER_SIZE (latest IDE versions) from 64 to another power of 2, like 128 or 256. This eats up your RAM in multiples, because Serial and Serial1 both get the larger buffers.

You should save the original versions to restore in case something gets messed up. Or you can reinstall the IDE, or get the specific files from github.

Cheers,
/dev

Bonjour a tous et toute.

J'ai un probleme qui me freine depuis un bon bout.en fait je programme sur arduino UNO et mon projet pour l'ecole concerne la localisation GSM ET GPS.j'ai deja un code pour le GSM juste que je n'arrive pas a convertir la latitude (float) recu par exemple en un char

svp aidez moi...merci d'avance

Mon code:

//variable globale

char msg[30]; //define the message variable

//dans le loop

if (gsmloc_success) {

Serial.print(F("GSMLoc lat:"));

Serial.println(latitude, 6);

sprintf (msg,"%f",latitude);

Serial.println(msg); //msg ici m'achiffe un point d'eterrogation dans le moniteur serie