NeoGps MPU6050 AcX AcY Acz Logger

Premise


I am a Noob and self-taught.
I am studying on this book. I started studiyng seriously how to code on arduino some months ago.

I am also learning posting questions on the forum and Stack exchange.
Thanks to -dev, Patrick, and others i am making great improvements (but i am still far away from my goal “be more familiar with C and C++”)


The Question

With the code below i can log and geolocalize my accelerometers data at 1Hz frequency.

I need to improve the speed.

I understand that the GPS could not be faster than 1 second and all the system is constrained by this.

So i though that i can create an if/else statement that log on a SD the latest gps information from my accelerometers data:

if the gps is updated write this
else write this

The system will be mounted on a motorcycle so i need to read and write my accelerations faster.

I don’t know if my thoughs are correct, and how to code it, can you help me?
I have done only some Block Diagram, write and re-write the code to understand it, but no more improvements.
I started studying the documentation on GitHub

Is a little bit frustrating, maybe is normal, i am feeling very stupid :disappointed_relieved: :disappointed_relieved:

Thanks always for your time :slight_smile: :slight_smile: :slight_smile:

Here the code

#include <SPI.h>
#include <SdFat.h>
#include <NMEAGPS.h>
#include <Wire.h>
#define ARDUINO_USD_CS 10 // uSD card CS pin (pin 10 on SparkFun GPS Logger Shield)

/////////////////////////
// Log File Defintions //
/////////////////////////
// Keep in mind, the SD library has max file name lengths of 8.3 - 8 char prefix,
// and a 3 char suffix.
char logFileName[13] = "gpslogXX.csv";
// Our log files are called "gpslogXX.csv, so "gpslog99.csv" is our max file.
#define MAX_LOG_FILES 100 // Number of log files that can be made

// Data to be logged:
#define LOG_COLUMN_HEADER \
  "longitude," "latitude," "altitude," "speed," "course," "date," "time," \
  "satellites," "Acc.X," "Acc.Y," "Acc.Z," "Gy.X," "Gy.Y," "Gy.Z," "Temp"
  // printed at the top of the file.

SdFat SD;
File  logFile;

/////////////////////////
// NeoGPS Definitions //
/////////////////////////
NMEAGPS gps; // NeoGPS object to be used throughout
gps_fix fix; // The latest GPS information received from the gpsPort
#define GPS_BAUD 9600 // GPS module's default baud rate

/////////////////////////////////
// GPS Serial Port Definitions //
/////////////////////////////////
// If you're using a Mega, Leo or Due, use Serial1 for the GPS:
//#define gpsPort Serial1

// If you're using an Arduino Uno or other ATmega328 board that uses the
// 0/1 UART for programming/Serial monitor-ing, use AltSoftSerial:
#include <AltSoftSerial.h>
AltSoftSerial gpsPort; // Always on pins 8 & 9
//If you can't use pins 8 & 9, use this:
//#include <NeoSWSerial.h>
//NeoSWSerial gpsPort( 2, 3 ).

// Define the serial monitor port. On the Uno, Mega, and Leonardo this is 'Serial'
//  on other boards this may be 'SerialUSB'
#define SerialMonitor Serial

//#define USE_MPU
const int MPU=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;


void setup()
{
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  SerialMonitor.begin(9600);
  gpsPort.begin(GPS_BAUD);

  SerialMonitor.println( F("Setting up SD card.") );

  updateFileName(); // Each time we start, create a new file, increment the number
  // see if the card is present and can be initialized:
  if (!SD.begin(ARDUINO_USD_CS))
  {
    SerialMonitor.println( F("Error initializing SD card.") );
  } else {
    logFile = SD.open( logFileName, FILE_WRITE );
    // Print a header at the top of the new file
    logFile.println( F(LOG_COLUMN_HEADER) );
  }

}

void loop()
{
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  while (gps.available( gpsPort )) {
    fix = gps.read();  // get the entire fix structure, once per second

    if (logGPSData()) { // Log the GPS data
      SerialMonitor.println( F("GPS logged.") ); // Print a debug message
    } else {// If we failed to log GPS
      // Print an error, don't update lastLog
      SerialMonitor.println( F("Failed to log new GPS data.") );
    }
  }
}


byte logGPSData()
{
  if (logFile.isOpen())
  { // Print longitude, latitude, altitude (in feet), speed (in mph), course
    // in (degrees), date, time, and number of satellites.

    if (fix.valid.location)
      logFile.print(fix.longitude(), 6);
    logFile.print(',');
    if (fix.valid.location)
      logFile.print(fix.latitude(), 6);
    logFile.print(',');
    if (fix.valid.altitude)
      logFile.print(fix.altitude() * 3.2808, 1);
    logFile.print(',');
    if (fix.valid.speed)
      logFile.print(fix.speed_mph(), 1);
    logFile.print(',');
    if (fix.valid.heading)
      logFile.print(fix.heading(), 1);
    logFile.print(',');

    if (fix.valid.date) {
      logFile.print( fix.dateTime.full_year() );
      if (fix.dateTime.month < 10)
        logFile.print( '0' );
      logFile.print( fix.dateTime.month );
      if (fix.dateTime.date < 10)
        logFile.print( '0' );
      logFile.print( fix.dateTime.date );
    }
    logFile.print(',');

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

    if (fix.valid.satellites)
      logFile.print(fix.satellites);
    logFile.print(',');
    logFile.print(AcX);
    logFile.print(',');
    logFile.print(AcY);
    logFile.print(',');
    logFile.print(AcZ);
    logFile.print(',');
    logFile.print(GyX);
    logFile.print(',');
    logFile.print(GyY);
    logFile.print(',');
    logFile.print(GyZ);
    logFile.print(',');
    logFile.print(Tmp);
    logFile.println();
    logFile.flush(); // make sure the file contains at least this much

    return 1; // Return success
  }

  return 0; // If we failed to open the file, return fail
}

// updateFileName() - Looks through the log files already present on a card,
// and creates a new file with an incremented file index.
void updateFileName()
{
  for (uint8_t i; i < MAX_LOG_FILES; i++)
  {
    // Set logFileName to "gpslogXX.csv":
    logFileName[6] = (i/10) + '0';
    logFileName[7] = (i%10) + '0';

    if (!SD.exists(logFileName))
      break; // We found our index

    SerialMonitor.print(logFileName);
    SerialMonitor.println( F(" exists") );
  }
  SerialMonitor.print( F("File name: ") );
  SerialMonitor.println(logFileName);
}

I need to improve the speed.

I understand that the GPS could not be faster than 1 second and all the system is constrained by this.

If you had 100 MPU readings and 1 GPS reading each second, what would you like to see in the SD file?

Another user, powergravity, had a similar problem and a similar application. He wrote 100 MPU records in the file, then he wrote 1 GPS record (actually 5 and 1, but you get the idea).

To use the file, he had to treat the records differently, based on the first field. Here is some sample data from his SD file:

    I,37678432,-2,1,2,-15,-18,5085,0,0,-7,3380,37678524
    I,37688432,-2,-4,1,-15,-18,5085,0,1,-5,3312,37688524
    I,37698432,-3,-2,1,-15,-18,5085,-2,0,-6,3520,37698552
    I,37708432,-3,-3,-2,-15,-18,5085,0,0,-6,3624,37708544
    G,37674952,13:00:18.05,0,0,0,0

‘I’ stands for an IMU reading, and ‘G’ stands for a GPS reading. There are many more ‘I’ records than ‘G’ records. The latest version of his sketch is attached to this post.

Cheers,
/dev

-dev:
If you had 100 MPU readings and 1 GPS reading each second, what would you like to see in the SD file?

Another user, powergravity, had a similar problem and a similar application. He wrote 100 MPU records in the file, then he wrote 1 GPS record (actually 5 and 1, but you get the idea).

To use the file, he had to treat the records differently, based on the first field. Here is some sample data from his SD file:

    I,37678432,-2,1,2,-15,-18,5085,0,0,-7,3380,37678524

I,37688432,-2,-4,1,-15,-18,5085,0,1,-5,3312,37688524
    I,37698432,-3,-2,1,-15,-18,5085,-2,0,-6,3520,37698552
    I,37708432,-3,-3,-2,-15,-18,5085,0,0,-6,3624,37708544
    G,37674952,13:00:18.05,0,0,0,0



'I' stands for an IMU reading, and 'G' stands for a GPS reading. There are many more 'I' records than 'G' records. The latest version of his sketch is attached to [this post](https://forum.arduino.cc/index.php?topic=438840.msg3228285#msg3228285).

Cheers,
/dev

Thanks for your patience! I am grateful to you for your help here and on Stack! :slight_smile:

-dev:
Another user, powergravity, had a similar problem and a similar application. He wrote 100 MPU records in the file, then he wrote 1 GPS record (actually 5 and 1, but you get the idea).

I am still too Noob to understand the code of powergravity :sob: :sob: :sob: :sob: , but i tried to write the code of my own without brutally copying and pasting :neutral_face: :neutral_face: :neutral_face: .

I spent maybe 6 hours trying to code it *(and some additional weeks studiyng all your suggestions and the others from arduino forum and arduino exchange, the first, and the second).

It was very very hard for a beginner like me, but even if the code doesn’t work i am a lot happy because i learned a lot of stuff.

I tried to implement the first explanation of Edgar Bonet to print my data together with your on NeoGPS, but the code attached doesn’t work.

My idea to get over the problem of 1Hz log rate was the following (but i wrong coded it).

Create the fix object
Create last_fix object 
Read the gps information
If fix!0=last_fix
Write the new information with the new information from the accelerometer
if fix==last_fix
Write the old information with the new information from the accelerometer

Another idea that i want to try in the following days is to define a counter or a timer and write the gps information only every second and leaving a blank space for the GPS information, while the accelerometer is still reading and writing.

The error that the code gaves me are the following:

#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
[…]Documents\Arduino\NeoGPS_ver01\NeoGPS_ver01.ino:73:22: note: in expansion of macro ‘F’

  • dataFile.println( F(LOG_COLUMN_HEADER) );*
    NeoGPS_ver01:100: error: expected initializer before ‘fix’
  • fix = gps.read(); // get the entire fix structure, once per second*
  • ^*
    NeoGPS_ver01:102: error: ‘last_fix’ was not declared in this scope
    if (fix != last_fix)
  • ^*
    NeoGPS_ver01:149: error: ‘last_fix’ was not declared in this scope
  • last_fix=fix*
  • ^*
    C:\Users\Andrea Ciufo\Documents\Arduino\NeoGPS_ver01\NeoGPS_ver01.ino: In function ‘void printHeader()’:
    NeoGPS_ver01:191: error: ‘dataFileName’ was not declared in this scope
    File dataFile = SD.open(dataFileName, FILE_WRITE); // Open the log file

Here a part of the code that i wrote:

if ((lastLog + LOG_RATE) <= millis()) {
      if (gps.available( gpsPort )) {
      
      SerialMonitor.println( F("GPS logged.") ); // Print a debug message
      //Define a temporary fix object to control if new data are recived from the gps 
      //if there are new data write the new gps information else write the old with the new
      //accelerometer information
    
      static gps_fix last_fix 
      fix = gps.read();  // get the entire fix structure, once per second

        if (fix != last_fix)
          if (fix.valid.location)
            longitude=fix.longitude(), 6;
          if (fix.valid.location)
            latitude=fix.latitude(), 6;
          if (fix.valid.altitude)
            altitude=fix.altitude() * 3.2808, 1;
          if (fix.valid.speed)
            speed=fix.speed_mph(), 1;
          if (fix.valid.heading)
            heading=fix.heading(), 1;
          if (fix.valid.date) {
          //I don't know how to handle dateTime, i am sure that my code is wrong

         
         dateTime=fix.dateTime.full_year();
      //  I don't know how to manage in this case this information :/  I think my code will not work 
      //  if (fix.dateTime.month < 10)
      //      dateTime+= 0;
      //    dateTime+=fix.dateTime.month;
      //    if (fix.dateTime.date < 10)
      //      dateTime+=0;
      //    dateTime+=fix.dateTime.date ;
      //    }
      //       if (fix.valid.time) {
      //      if (fix.dateTime.hours < 10)
      //        dataFile.print( '0' );
      //      dataFile.print( fix.dateTime.hours );
      //      if (fix.dateTime.minutes < 10)
      //        dataFile.print( '0' );
      //      dataFile.print( fix.dateTime.minutes );
      //      if (fix.dateTime.seconds < 10)
      //        dataFile.print( '0' );
      //      dataFile.print( fix.dateTime.seconds );
      //    }
      //   dataFile.print(',');

          if (fix.valid.satellites)
            satellites= fix.satellites;



    printImuData(dataFile, longitude, latitude, altitude, speed, heading, dateTime, satellites, AcX, AcY, AcZ, GyX, GyY, GyZ);
    
    
    
    
    last_fix=fix
    
  
  if fix == last_fix

  printImuData(dataFile, longitude, latitude, altitude, speed, heading, 
    dateTime, satellites, AcX, AcY, AcZ, GyX, GyY, GyZ);
  lastLog=millis();   
  } else {// If we failed to log GPS
      // Print an error, don't update lastLog
      SerialMonitor.println( F("Failed to log new GPS data.") );
    }
  }
}
}
static void printImuData(Print &printer, int16_t longitude, int16_t latitude, int16_t altitude, int16_t speed, int16_t heading, 
    int16_t dateTime, int16_t satellites, 
    
        int16_t AcX, int16_t AcY, int16_t AcZ,
        int16_t GyX, int16_t GyY, int16_t GyZ)
{
//Printing the GPS Information 
   printer.print(longitude);   printer.print(",");
    printer.print(latitude);   printer.print(",");
    printer.print(altitude);   printer.print(",");
    printer.print(speed);      printer.print(",");
  printer.print(heading);    printer.print(",");   
  printer.print(dateTime);   printer.print(",");
    printer.print(satellites); printer.print(",");
//Printing the mpu6050 information 
    printer.print(AcX);   printer.print(",");
    printer.print(AcY);   printer.print(",");
    printer.print(AcZ);   printer.print(",");
    printer.print(GyX);   printer.print(",");
    printer.print(GyY);   printer.print(",");
 printer.print(GyZ);   printer.print(",");
  
}

Thanks for all your support, is invaluable** <3 <3 <3

  • I am a self taught and this is my first experience with coding, i am studying a lot of theory not only “learning by doing”
    ** I hope one day to have the knowledge to give back :slight_smile:

NeoGPS_ver01.ino (7.55 KB)

I put on git hub the new code, but i still not resolved my problem.
I moved outside the if statement the while (here you can see the whole code)

By now i can log the gps information but i am stucked at 1 second log rate even if i put a timer.

I think the reason is related on how gps.available() works , but as a noob i am not sure about it.

 while (gps.available( gpsPort )) {
    fix = gps.read();  // get the entire fix structure, once per second

   
    if ((lastLogGPS + LOG_RATE_GPS) <= micros()) {
        if (logGPSData()) { // Log the GPS data
    SerialMonitor.println( F("GPS logged.") ); // Print a debug message
    } else {// If we failed to log GPS
    // Print an error, don't update lastLog
    SerialMonitor.println( F("Failed to log new GPS data.") );
        }
    lastLogGPS=micros();
  }

    else{ 
    if ((lastLog + LOG_RATE) <= micros()) {
    
      printImuData(dataFile,lastLog, AcX, AcY, AcZ, GyX, GyY, GyZ);
      dataFile.flush(); 
      }
      lastLog=micros(); 
     }
   } 
  }

Over the past few months i studied how the gps works(like here on Quora), going deep with the C learning, thanks for your support :slight_smile:

1) If you really want to learn how to code, you MUST learn to indent. Readability is the most important attribute, because:

  • If you can’t read your code, you can’t understand it.
  • If you can’t understand it, you can’t debug it.

If your space key is broken, just press control-T in the IDE editor to auto-format your code.

2) To measure elapsed time, you MUST subtract a timestamp from the current time and compare it to an interval. This is NOT the way to measure time:

        if ((lastLog + LOG_RATE) <= micros()) {  // NO!

It will not work when micros() rolls over to 0 and starts counting up again. Instead, do this:

        if ((micros() - lastLog) >= LOG_RATE) {

3) There is no reason to “track” when the GPS updates have come. They come when the GPS device is ready to send them. They arrive at 1-second intervals, and they are spaced very accurately. The GPS device sends updates based on the GPS atomic clocks, which are much more accurate than the Arduino crystal. That is, micros() and millis() are not very accurate. Just log the GPS data when it arrives.

4) If you do not want two different records types, ‘I’ and ‘G’, you can write one big record that has empty GPS data when no fix is available yet. You can “initialize” the fix to empty it, after it is written. When gps.read() fills it out again, logGPSData will have valid fields to write.

Here is your sketch with those suggestions:

//Codice scrittura dati accelerometro e gps
//il file logga purtroppo alla frequenza di un campionamento al secondo

#include <SPI.h>
#include <SdFat.h>
#include <Wire.h>
#include <NMEAGPS.h>

#define ARDUINO_USD_CS 10 // uSD card CS pin (pin 10 on SparkFun GPS Logger Shield)


//Definizione delle librerie e oggetti necessarie all'acquisizione dei dati da GPS


NMEAGPS gps;          // NeoGPS object to be used throughout
gps_fix fix;          // The latest GPS information received from the gpsPort
bool    newGPSdata;   // true when a new GPS fix needs to be logged
#define GPS_BAUD 9600 // GPS module's default baud rate

#include <AltSoftSerial.h>
AltSoftSerial gpsPort; // Always on pins 8 & 9

#define SerialMonitor Serial

#define MAX_LOG_FILES 100 // Number of log files that can be made
char logFileName[] = "gpslogXX.csv";


#define LOG_COLUMN_HEADER \
  "longitude," "latitude," "altitude," "speed," "course," "date," "time," \
  "satellites," "LastLog," "Acc.X," "Acc.Y," "Acc.Z," "Gy.X," "Gy.Y," "Gy.Z,"

#define LOG_RATE 1000         // Log every 1 milliseconds
unsigned long lastLog = 0;      // Global var to keep of last time we logged
const int MPU=0x68;         // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;


// SD definition
SdFat SD;
File  dataFile;

void setup()
{
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  gpsPort.begin(GPS_BAUD);

  SerialMonitor.begin(9600);
  SerialMonitor.println( F("Setting up SD card.") );

  // see if the card is present and can be initialized:
  if (!SD.begin(ARDUINO_USD_CS)) {
    SerialMonitor.println( F("Error initializing SD card.") );
  } else {
    updateFileName(); // Each time we start, create a new file, increment the number
    dataFile = SD.open( logFileName, FILE_WRITE );
    // Print a header at the top of the new file
    dataFile.println( F(LOG_COLUMN_HEADER) );
    if (!dataFile.isOpen())
      SerialMonitor.println( F("Failed to open GPS dataFile") );
  }

} // setup


void loop()
{
  //  Check for new GPS data
  if (gps.available( gpsPort )) {
    fix        = gps.read();  // get the entire fix structure, once per second
    newGPSdata = true;
  }

  // Is it time to take an MPU sample?
  if ((micros() - lastLog) > LOG_RATE) {
    lastLog = micros();

    // Yes, read the registers
    Wire.beginTransmission( MPU );
    Wire.write( 0x3B );  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom( MPU, 14, true );   // request a total of 14 registers

    AcX = Wire.read()<<8;
    AcX|= Wire.read();     // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    AcY = Wire.read()<<8;
    AcY|= Wire.read();     // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    AcZ = Wire.read()<<8;
    AcZ|= Wire.read();     // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
    GyX = Wire.read()<<8;
    GyX|= Wire.read();     // 0x43 (GYRO_XOUT_H)  & 0x44 (GYRO_XOUT_L)
    GyY = Wire.read()<<8;
    GyY|= Wire.read();     // 0x45 (GYRO_YOUT_H)  & 0x46 (GYRO_YOUT_L)
    GyZ = Wire.read()<<8;
    GyZ|= Wire.read();     // 0x47 (GYRO_ZOUT_H)  & 0x48 (GYRO_ZOUT_L)

    logGPSData();  //  Write out GPS data first...
    logMPUdata();  //  ...then write the MPU data.

    //  If we had new GPS data, clear the flag and flush the file
    if (newGPSdata) {
      newGPSdata = false;
      fix     .init (); // empty out the fix structure
      dataFile.flush(); // checkpoint the SD file once per second
    }
  }

} // loop


static void logGPSData()
{
  // Print longitude, latitude, altitude (in feet), speed (in mph), course
  // in (degrees), date, time, and number of satellites.
  //  NOTE:  This only prints commas if the fix is empty (initialized).

  if (fix.valid.location)
    dataFile.print(fix.longitude(), 6);
  dataFile.print(',');
  if (fix.valid.location)
    dataFile.print(fix.latitude(), 6);
  dataFile.print(',');
  if (fix.valid.altitude)
    dataFile.print(fix.altitude() * 3.2808, 1);
  dataFile.print(',');
  if (fix.valid.speed)
    dataFile.print(fix.speed_mph(), 1);
  dataFile.print(',');
  if (fix.valid.heading)
    dataFile.print(fix.heading(), 1);
  dataFile.print(',');

  if (fix.valid.date) {
    dataFile.print( fix.dateTime.full_year() );
    if (fix.dateTime.month < 10)
      dataFile.print( '0' );
    dataFile.print( fix.dateTime.month );
    if (fix.dateTime.date < 10)
      dataFile.print( '0' );
    dataFile.print( fix.dateTime.date );
  }
  dataFile.print(',');

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

  if (fix.valid.satellites)
    dataFile.print(fix.satellites);

  dataFile.print(',');

} // logGPSData


static void logMPUdata()
{
  //Printing the mpu6050 information
  dataFile.print  (lastLog); dataFile.print(',');
  dataFile.print  (AcX);     dataFile.print(',');
  dataFile.print  (AcY);     dataFile.print(',');
  dataFile.print  (AcZ);     dataFile.print(',');
  dataFile.print  (GyX);     dataFile.print(',');
  dataFile.print  (GyY);     dataFile.print(',');
  dataFile.println(GyZ);

} // logMPUdata


// updateFileName() - Looks through the log files already present on a card,
// and creates a new file with an incremented file index.
void updateFileName()
{
  for (uint8_t i; i < MAX_LOG_FILES; i++)
  {
    // Set logFileName to "gpslogXX.csv":
    logFileName[6] = (i/10) + '0';
    logFileName[7] = (i%10) + '0';
    if (!SD.exists(logFileName))
      break; // We found our index

    SerialMonitor.print(logFileName);
    SerialMonitor.println( F(" exists") );
  }
  SerialMonitor.print( F("File name: ") );
  SerialMonitor.println(logFileName);

} // updateFileName

Cheers,
/dev

-dev:
1) If you really want to learn how to code, you MUST learn to indent. Readability is the most important attribute, because:

  • If you can’t read your code, you can’t understand it.
  • If you can’t understand it, you can’t debug it.

If your space key is broken, just press control-T in the IDE editor to auto-format your code.

Thanks for your harsh feedback, i really appreciated (i am serious :slight_smile: ) and sorry for my error, it will never happen, i will improve

-dev:
2) To measure elapsed time, you MUST subtract a timestamp from the current time and compare it to an interval. This is NOT the way to measure time:
if ((lastLog + LOG_RATE) <= micros()) { // NO!

It will not work when micros() rolls over to 0 and starts counting up again. Instead, do this:

if ((micros() - lastLog) >= LOG_RATE) {

Thanks for this suggestions i will change my code

-dev:
3) There is no reason to “track” when the GPS updates have come. They come when the GPS device is ready to send them. They arrive at 1-second intervals, and they are spaced very accurately. The GPS device sends updates based on the GPS atomic clocks, which are much more accurate than the Arduino crystal. That is, micros() and millis() are not very accurate. Just log the GPS data when it arrives.

Yes i’ve undestood this fact in theory since your first answer, but i made a huge mistake in practice. (i hope to be clear beacuase i am not very good to explain something).

My intentions was to record the gps information when available and if not continue with the accelerometers information (i dont’ knwo how to put the old value, so i solved this weaknes putting 0), this way i could have more acc log while i was waiting for the updated gps information (but only in my immaginary world, not with my code).

To simplify the following analysis on Matlab i decided to put all the information on a string.

-dev:
4) If you do not want two different records types, ‘I’ and ‘G’, you can write one big record that has empty GPS data when no fix is available yet. You can “initialize” the fix to empty it, after it is written. When gps.read() fills it out again, logGPSData will have valid fields to write.

I will study your suggestions and going deep with your documentation on Git Hub

I know that my questions could be silly and annoying but this is my first experience with electonics and programming.

Thanks :slight_smile: