Logging Data from GPS and Acc/gyr/mag Individually but not simultaneously.

I would really appreciate any help with this. I have a project due in a couple of weeks and I just need to get in a position where I can log some useful data...

Individually the sketch I use to log GPS data succesfully stores the passed information on a .csv file on my SD card using SdFat. Likewise, the sketch I use to log data from the acc,gyr,mag also stores the information successfully. Combined, there appears to be no data logged whatsoever.

My code is shown below:

#include <Adafruit_GPS.h> //Load the GPS Library. Make sure you have installed the library form the adafruit site above
#include <SoftwareSerial.h> //Load the Software Serial Library. This library in effect gives the arduino additional serial ports
#include <Wire.h>
#include <Adafruit_LSM9DS1.h>
#include <SdFat.h>

#define LSM9DS1_SCK A5    // a/g/m
#define LSM9DS1_MISO 12   // a/g/m
#define LSM9DS1_MOSI A4   // a/g/m
#define LSM9DS1_XGCS 6    // a/g/m
#define LSM9DS1_MCS 5     // a/g/m

SoftwareSerial mySerial(3, 2); //Initialize SoftwareSerial, and tell it you will be connecting through pins 2 and 3
Adafruit_GPS GPS(&mySerial); //Create GPS object

Adafruit_LSM9DS1 lsm = Adafruit_LSM9DS1();
SdFat sd;
SdFile mySensorData;

int chipSelect = 4; //File gpsData; //Variable for SD cards Object

String NMEA1;  //We will use this variable to hold our first NMEA sentence
String NMEA2;  //We will use this variable to hold our second NMEA sentence
char c;       //Used to read the characters spewing from the GPS module

void setup()  
      {

          Serial.begin(115200);
          GPS.begin(9600); //Turn GPS on at baud rate of 9600
          pinMode(10,OUTPUT);
          if (sd.begin(chipSelect, SPI_HALF_SPEED)) 
                  {
                Serial.print(F("Ok now what"));
                mySensorData.open("NMEA.CSV", O_WRITE);
                mySensorData.remove();
                mySensorData.open("GPSData.CSV", O_WRITE);
                mySensorData.remove();
                mySensorData.open("AGM.CSV", O_WRITE);
               mySensorData.remove();
                 }
          else    {
                Serial.print(F("Looks like an error"));
               }
              
                GPS.sendCommand("$PGCMD,33,0*6D"); // Turn Off GPS Antenna Update
                GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Tell GPS we want only $GPRMC and $GPGGA NMEA sentences
                GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
                delay(1000);  //Pause


        lsm.begin();
     
        setupSensor();

        
      }


void loop()                     
{
readGPS();
lsm.read();  /* ask it to read in the data */
sensors_event_t a, m, g, temp; /* Get a new sensor event */
lsm.getEvent(&a, &m, &g, &temp);

if (GPS.fix == 1){ //only log data after we have a fix
mySensorData.open("NMEA.CSV", O_WRITE | O_CREAT | O_APPEND);
  //mySensorData = SD.open("NMEA.txt", FILE_WRITE); //Open file on SD card for writing
  mySensorData.println(NMEA1); //Write first NMEA to SD card
  mySensorData.println(NMEA2); //Write Second NMEA to SD card
  mySensorData.close();  //Close the file
  mySensorData.open("GPSData.CSV", O_WRITE | O_CREAT | O_APPEND);
  //mySensorData = SD.open("GPSData.txt", FILE_WRITE);
  mySensorData.print(GPS.latitude,4); //Write measured latitude to file
  mySensorData.print(GPS.lat); //Which hemisphere N or S
  mySensorData.print(F(","));
  mySensorData.print(GPS.longitude,4); //Write measured longitude to file
  mySensorData.print(GPS.lon); //Which Hemisphere E or W
  mySensorData.print(F(","));
  mySensorData.print(GPS.altitude);
  mySensorData.print(F(","));
  mySensorData.print(GPS.speed);
  mySensorData.print(F(","));
  mySensorData.println(GPS.angle);
  mySensorData.close();
  mySensorData.open("AGM.CSV", O_WRITE | O_CREAT | O_APPEND); //Open file on SD card for writing
  mySensorData.print(a.acceleration.x);
  mySensorData.print(F(","));
  mySensorData.print(m.magnetic.x);
  mySensorData.print(F(","));
  mySensorData.println(g.gyro.x);
  mySensorData.print(a.acceleration.y); //Which hemisphere N or S
  mySensorData.print(F(","));
  mySensorData.print(m.magnetic.y);
  mySensorData.print(F(","));
  mySensorData.println(g.gyro.y);
  mySensorData.print(a.acceleration.z);
  mySensorData.print(F(","));
  mySensorData.print(m.magnetic.z);
  mySensorData.print(F(","));
  mySensorData.println(g.gyro.z);
  mySensorData.close();
  
  }
  
  
  
  
  }



void readGPS(){  //This function will read and remember two NMEA sentences from GPS
  clearGPS();    //Serial port probably has old or corrupt data, so begin by clearing it all out
  while(!GPS.newNMEAreceived()) { //Keep reading characters in this loop until a good NMEA sentence is received
  c=GPS.read(); //read a character from the GPS
  }
GPS.parse(GPS.lastNMEA());  //Once you get a good NMEA, parse it
NMEA1=GPS.lastNMEA();      //Once parsed, save NMEA sentence into NMEA1
while(!GPS.newNMEAreceived()) {  //Go out and get the second NMEA sentence, should be different type than the first one read above.
  c=GPS.read();
  }
GPS.parse(GPS.lastNMEA());
NMEA2=GPS.lastNMEA();
//  Serial.println(NMEA1);
//  Serial.println(NMEA2);
//  Serial.println("");
  
}
void clearGPS() {  //Since between GPS reads, we still have data streaming in, we need to clear the old data by reading a few sentences, and discarding these
while(!GPS.newNMEAreceived()) {
  c=GPS.read();
  }
GPS.parse(GPS.lastNMEA());
while(!GPS.newNMEAreceived()) {
  c=GPS.read();
  }
GPS.parse(GPS.lastNMEA());

}

void setupSensor()
{
  // 1.) Set the accelerometer range
  lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_2G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_4G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_8G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_16G);

  // 2.) Set the magnetometer sensitivity
  lsm.setupMag(lsm.LSM9DS1_MAGGAIN_4GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_8GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_12GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_16GAUSS);

  // 3.) Setup the gyroscope
  lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_245DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_500DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_2000DPS);
}

Upon compilation, it shows that I am occupying alot of memory space with these combined sketches.(86% PROGRAM STORAGE SPACE and 90% DYNAMIC MEMORY)

This is also troublesome as I would like to add my tft display to show information from the data on the display which I know would occupy a fair amount of memory in addition to this.

I was advised to use a char array instead of String for the NMEA sentences defined in my sketch. However, I am skeptical that this may be the root of this issue and I don't think this would significantly clear up memory space enough for me to add the tft sketch I have also written...

Despite my doubts about the char array being the saviour, I am also lost as to how I would go about incorporating it into my code.

Is someone able to identify why the data is not being logged?

Please..Any help would be appreciated.

I have also noticed that the code never makes it to the loop() section of the code.

It seems to loop over the setup() code evidenced by Serial.print("ok no what") which is being constantly printed to the serial monitor.

any suggestions?

If you're getting a warning about memory at compile time, you will have a serious problem opening files. IIRC, open allocates a 512 byte buffer, which, if you're using an Uno or the like will presumably fail and crash, as you observe.

Strings are bad too, but it doesn't look like you're getting far enough for them to do you any damage. I'll guess that the libraries you're using are just consuming too much memory for you to be able to open multiple files as well.

Your easiest solution may well be to buy your way out of trouble by getting an Arduino (or Teensy) with more RAM.

Unless i missed it.. what hardware are you using? Uno? Probably a memory problem.

Some feedback for ya:

  • Your initialization of the LSM9DS1 sensor isnt clear. you are using the I2C so why are you defining #LSM9DS1_SCK?
  • Remove the STRINGS, they are bloaty. Instead grab the UART byte to a new variable, write to SD, then write to the library. Since you are trying to log the NEMA and the actual variables write your GPSData.CSV after every new line received.
  • Switch to TinyGPS or TinyGPS++. its tiny and handles the data better :wink: TinyGPS++ | Arduiniana
  • Why are you using SoftwareSerial? Just pump the GPS into Serial (pins 0 and 1) or try to use another UART hardware port (board dependent). I find SoftwareSerial touchy and ram intensive.

Also fully support a Teensy 3.2 here, its kick ass. Good luck!

LaurenceR:
Upon compilation, it shows that I am occupying alot of memory space with these combined sketches.(86% PROGRAM STORAGE SPACE and 90% DYNAMIC MEMORY)
This is also troublesome as I would like to add my tft display to show information from the data on the display which I know would occupy a fair amount of memory in addition to this.

So 90% of memory used already and you need to add in the memory to hold the NMEA strings.

However since the important detail of which Arduino you are using has been redacted, so the forum cannot advice specifically, but at 90% for whats allready loaded, it looks like a UNO.

Forget it, you need a Arduino with more memory, your chances of adding in the dispaly library are close to zero.

jacky4566:
Unless i missed it.. what hardware are you using? Uno? Probably a memory problem.

Some feedback for ya:

  • Your initialization of the LSM9DS1 sensor isnt clear. you are using the I2C so why are you defining #LSM9DS1_SCK?
  • Remove the STRINGS, they are bloaty. Instead grab the UART byte to a new variable, write to SD, then write to the library. Since you are trying to log the NEMA and the actual variables write your GPSData.CSV after every new line received.
  • Switch to TinyGPS or TinyGPS++. its tiny and handles the data better :wink: http://arduiniana.org/libraries/tinygpsplus/
  • Why are you using SoftwareSerial? Just pump the GPS into Serial (pins 0 and 1) or try to use another UART hardware port (board dependent). I find SoftwareSerial touchy and ram intensive.

Also fully support a Teensy 3.2 here, its kick ass. Good luck!

Jack, thank you very much for your detailed feedback!

I was using a sketch for the accelerometer which was using SPI while I hooked mine up in I2C. Although it still sent across data correctly strangely. But I have moved the _SCK in the initializations so thank you!

I am now trying to use the TX and RX pins but it sends data so fast that some sentences are being printed too quickly and are not separated by a new line in monitor. They just add onto a sentence! so trying to fix that now!

I will look into TinyGPS and see if it will help me out in any way!

I am slightly confused as to how to write the UART variable to the SD card and library...