sparkfun / SparkFun_u-blox_GNSS_Arduino_Library

An Arduino library which allows you to communicate seamlessly with the full range of u-blox GNSS modules
Other
227 stars 100 forks source link

data processing time #187

Closed Nocentinia closed 1 year ago

Nocentinia commented 1 year ago

Hello everyone. I'm trying to create a data logger that saves me GPS and IMU data. I'm using Arduino MKR1010 and Arduino MKRGPS Shield as hardware (I know it's not your product, but I hope you can help me). I'm having some problems with the processing speed of the new gps data, basically I need the gps data to be saved on an SD card every 200mS(5Hz) and between one gps fix and another I would like them to be entered IMU data. the only problem is in the timing, I am attaching a part of the code

void setup() {

  Serial.begin(115200);
  while (!Serial); //Wait for user to open terminal

  Serial.println("SparkFun u-blox Example");

  do {
    Serial.println("GNSS: trying 38400 baud");
    mySerial.begin(38400);
    if (myGNSS.begin(mySerial) == true) break;

    delay(100);
    Serial.println("GNSS: trying 9600 baud");
    mySerial.begin(9600);
    if (myGNSS.begin(mySerial) == true) {
      Serial.println("GNSS: connected at 9600 baud, switching to 38400");
      myGNSS.setSerialRate(38400);
      delay(100);
    } else {
      //myGNSS.factoryReset();
      delay(2000);  //Wait a bit before trying again to limit the Serial output
    }
  } while (1);
  Serial.println("GNSS serial connected");

  myGNSS.setUART1Output(COM_TYPE_UBX);  //Set the UART port to output UBX only
  myGNSS.setI2COutput(COM_TYPE_UBX);    //Set the I2C port to output UBX only (turn off NMEA noise)
  myGNSS.setNavigationFrequency(5);
  myGNSS.saveConfiguration();  //Save the current settings to flash and BBR
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");

    while (1)
      ;
  }
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    //while (1);
    sd = false;
  }

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  File dataFile = SD.open("MyData.CSV", FILE_WRITE);
  if (dataFile) {
    dataFile.println("ISODateTimeUTC,Lat,Lon,BoatSpeed,TWA,TWS,ax,ay,az,gx,gy,gz,mx,my,mz,Heading,rollio,beccheggio,");
    dataFile.close();
  }
}

void loop() {
  WriteGpsData = false;
  currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    WriteGpsData = true;
    latitudine = myGNSS.getLatitude();
    longitudine = myGNSS.getLongitude();
    altitudine = myGNSS.getAltitude();
    velocita = myGNSS.getGroundSpeed();
    anno = myGNSS.getYear();
    mese = myGNSS.getMonth();
    giorno = myGNSS.getDay();
    ore = myGNSS.getHour();
    minuti = myGNSS.getMinute();
    secondi = myGNSS.getSecond();
    milli = myGNSS.getMillisecond();
    SIV = myGNSS.getSIV();
    latitudine1 = latitudine * 0.0000001;
    longitudine1 = longitudine * 0.0000001;
    velocita = velocita / 1000;
    fixType = myGNSS.getFixType();
    if (fixType != 0) {
      digitalWrite(LED_BUILTIN, en);
      GpsData();

    } else {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }

  if (WriteGpsData != 1) {
    if (fixType != 0) {
      if (IMU.accelerationAvailable()) {
        IMU.readAcceleration(ax, ay, az);
        acc = true;
      } else acc = false;
      delayMicroseconds(100);
      if (IMU.gyroscopeAvailable()) {
        IMU.readGyroscope(gx, gy, gz);
        giro = true;
      } else giro = false;
      delayMicroseconds(100);
      if (IMU.eulerAnglesAvailable()) {
        IMU.readEulerAngles(heading, roll, pitch);
        eur = true;
      } else eur = false;
      delayMicroseconds(100);
      if (IMU.magneticFieldAvailable()) {
        IMU.readMagneticField(mx, my, mz);
        compass = true;
      } else compass = false;

      if (acc || giro || eur) {
        IMUData();
      }

    }
  }
}

void GpsData() {
 //print data on SD
}

void IMUData() {
 //print data on SD
}

at the beginning of the code in the imposed variables interval =200;

but it happens that initially the IMU data is written correctly, after 200mS it enters

     if (currentMillis - previousMillis >= interval) {
     }

and being that Arduino takes about 200mS to execute the instructions:

latitudine = myGNSS.getLatitude();
    longitudine = myGNSS.getLongitude();
    altitudine = myGNSS.getAltitude();
    velocita = myGNSS.getGroundSpeed();
    anno = myGNSS.getYear();
    mese = myGNSS.getMonth();
    giorno = myGNSS.getDay();
    ore = myGNSS.getHour();
    minuti = myGNSS.getMinute();
    secondi = myGNSS.getSecond();
    milli = myGNSS.getMillisecond();
    SIV = myGNSS.getSIV();
    latitudine1 = latitudine * 0.0000001;
    longitudine1 = longitudine * 0.0000001;
    velocita = velocita / 1000;
    fixType = myGNSS.getFixType();

it happens that the only data saved in the end are those of the gps, because when the cycle restarts 200mS have passed and therefore it returns to the gps data reading block. I hope you can help me, I still have very little experience with this library and I still haven't managed to find all its features (a file with the description of the functions would be very useful). sorry for my english, i'm italian!

PaulZC commented 1 year ago

Hello @Nocentinia ,

By default, myGNSS.getLatitude(); will poll (request) the Position Velocity Time data from the SAM-M8 GNSS. For your application, you need to tell the GNSS to output the data periodically every 200ms.

Please have a look at this example:

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/main/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino

The critical pieces of code are:

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/3416a3140fb74c3b80fc680140d029182fcd03ad/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino#L49-L50

Change the 2 to 5 for your application.

Then structure your loop, so that you call myGNSS.getPVT() first. If it returns true then read the latitude, longitude etc..:

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/3416a3140fb74c3b80fc680140d029182fcd03ad/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino#L58

In bocca al lupo! ;-) Paul

Nocentinia commented 1 year ago

I was initially using the function if (myGNSS.getPVT()) { but I encountered the exact same problem. I sense that this function returns true even when it doesn't actually have any new data and just hangs around like it's frozen in: latitudine = myGNSS.getLatitude(); waiting for new data to arrive (then wait 200mS(5Hz)). instead using setting: myGNSS.setAutoPVT(true); goes to manage the parameter: myGNSS.getInvalidLlh() which becomes false whenever there is actually new data, is this correct? thanks for your immediate reply :)

PaulZC commented 1 year ago

Normally, getPVT requests (polls) the Position Velocity Time data. It waits for the data to arrive - or for a timeout to happen. In your case, it could take up to 200ms for the data to arrive. The code will stall for up to 200ms.

myGNSS.setAutoPVT(true); changes the way getPVT works. It also tells the GNSS to output PVT periodically.

Afterwards, getPVT will check if any data has arrived from the GNSS. It will return true if new PVT data has arrived. If no data has arrived, it returns false - ~immediately. It does not wait for the data to arrive.

You can ignore myGNSS.getInvalidLlh(). That returns true if the Latitude Longitude Height is invalid. false indicates the GNSS has a good fix and that latitude, longitude and height are valid. It comes from the invalidLlh flag inside the PVT message.

Nocentinia commented 1 year ago

thank you very much for your support, I have performed various tests with your advice obtaining excellent results. I still have some doubts about how some things work, can I ask here?

PaulZC commented 1 year ago

Hi,

We use GitHub Issues to report and correct actual issues (bugs and other problems) with the library. For general advice, the best place to ask is the SparkFun GPS Forum. I watch that forum and will help if I can.

https://forum.sparkfun.com/viewforum.php?f=116

Best wishes, Paul