Adafruit GPS Shield & Uno - Rapid/Consistent Data retrieval needed for UAV

My university project includes the need for a flight computer/ data logger and auto-pilot system for a fixed wing UAV. Part of the project specification is that an only an Uno is allowed to be used.

I've coded an auto-pilot (gyro & accelerometer fed PID system) that works great on a program loop of a consistent time period. I've also got the Adafruit GPS shield working with NeoGPS (needed because of limited RAM), but the usual data retrieval function, a while() loop, is highly unstable. Which will likely botch the stabilization loop.

This Code;

#include <NMEAGPS.h>
#include <GPSport.h>

int gpstime;
unsigned long start;

NMEAGPS  gps;
gps_fix  fix;

void setup(){
  DEBUG_PORT.begin(9600);
  while (!DEBUG_PORT);
  delay(500);
  gpsPort.begin(9600);
}

void loop(){
  start = millis();
  while (!gps.available(gpsPort)){
  }
  if (gps.available(gpsPort)){
    fix = gps.read();
  }
  gpstime = millis() - start;

  if (fix.valid.location) {
    //DEBUG_PORT.print( F("Location: ") );          Don't want the world to know where I am!
    //DEBUG_PORT.print( fix.latitude(), 6 );
    //DEBUG_PORT.print( F(",") );
    //DEBUG_PORT.println( fix.longitude(), 6 );
  }
  else DEBUG_PORT.println(F("No Location Data available."));
  DEBUG_PORT.print(F("GPS Read Time: "));
  DEBUG_PORT.print(gpstime);
  DEBUG_PORT.print(F(",\tGPS Second: "));
  DEBUG_PORT.println( fix.dateTime.seconds );
}

Produces this:

GPS Read Time: 604, GPS Second: 34
GPS Read Time: 1202, GPS Second: 35
GPS Read Time: 832, GPS Second: 36
GPS Read Time: 974, GPS Second: 37
GPS Read Time: 996, GPS Second: 38
GPS Read Time: 1035, GPS Second: 39
GPS Read Time: 1159, GPS Second: 40
GPS Read Time: 754, GPS Second: 41
GPS Read Time: 1064, GPS Second: 42
GPS Read Time: 932, GPS Second: 43
GPS Read Time: 987, GPS Second: 44
GPS Read Time: 1273, GPS Second: 45
GPS Read Time: 727, GPS Second: 46
GPS Read Time: 1009, GPS Second: 47
GPS Read Time: 1062, GPS Second: 48
GPS Read Time: 946, GPS Second: 49
GPS Read Time: 1198, GPS Second: 50
GPS Read Time: 840, GPS Second: 51
GPS Read Time: 938, GPS Second: 52
GPS Read Time: 1008, GPS Second: 53
GPS Read Time: 1061, GPS Second: 54

My problem is that the "GPS Read Time" is inconsistent, if it was (at least within 10 milliseconds), I could run the stabilization code "n" times and then retrieve the GPS data.

I'm guessing this will be possible with PPS syncing? But I've struggled to find enough information to know if this will fix my problem (I'm not a programmer).

Thanks in advance! Also any tips on reducing RAM/ memory would also be greatly appreciated, I still need to add in the SD card writer and receiver code :o .

Here, "slash-dev" mentioned the NeoGPS acquires a fix every 1 second: https://stackoverflow.com/questions/43006844/want-to-get-gps-data-at-every-5-sec-using-arduino/43013240[/url]

GPS Datasheet if you need it:

I'm limited to using an Uno!

Why?

Here, "slash-dev" mentioned the NeoGPS acquires a fix every 1 second: https://stackoverflow.com/questions/43006844/want-to-get-gps-data-at-every-5-sec-using-arduino/43013240[/url]

The GPS acquires a new fix every second IF is has a clear view of the sky AND has achieved a fix already.

What you are currently measuring is how long you need to wait for the next sentence to start coming in plus the time it takes to read the complete sentence. I can't see how that measurement is useful.

I can't imagine why you would want to sit around with your thumb up your a** waiting for a fix.

Way more details on your project are needed.

PalmerEng4:
Also any tips on reducing RAM/ memory would also be greatly appreciated, I still need to add in the SD card writer and receiver code :o .

Yes, dont use the SD or the receiver or remove some other functions.

Or just upgrade to an Arduino with more memory.

The SD alone will add around 37% to Flash and 35% to program memory.

can i interface my gps module with arduino, will it supports, to display latitude and longitude.

can anyone send me steps and coding that how can i interface my gps module. will there be any voltage differences i.e., whether i need to apply 3.3v or 5v.

here is the website from where i bought my neo 6m gps module.

http://uitechies.co.in/BBBcircuits/product.php?product=waves-gps-module-neo-6m-gps-u-blox-neo-6m-gps-module-eprom-mwc-small-ceramic-antenna

It looks like you don't have a valid fix when you are printing out your read time. Basically, it seems like you are just measuring the time the GPS spits out data. The GPS will output data via sentences and the sentences are different lengths. I don't think you are accurately measuring what you are trying to measure.

can i interface my gps module with arduino

Yes.

will it supports, to display latitude and longitude.

The GPS will report latitude and longitude. How you "display" that is up to you.

can anyone send me steps and coding that how can i interface my gps module.

No. You haven't said how you are connecting the GPS to the Arduino, or what you want the code to do.

will there be any voltage differences i.e., whether i need to apply 3.3v or 5v.

Without knowing which GPS and which Arduino, the answer is a definite maybe.

here is the website from where i bought my neo 6m gps module.

Finally, we know what GPS you are talking about. Mr Google knows quite a bit about that GPS connected to Arduinos.

PaulS:
Why?
The GPS acquires a new fix every second IF is has a clear view of the sky AND has achieved a fix already.

What you are currently measuring is how long you need to wait for the next sentence to start coming in plus the time it takes to read the complete sentence. I can't see how that measurement is useful.

I can't imagine why you would want to sit around with your thumb up your a** waiting for a fix.

Way more details on your project are needed.

I'm limited to an Uno in the specification of the University design project. It's meant to be a challenge.

The code above is not what I would implement into my final code, but merely to show that the time between retrieving the complete sentences varies a lot. My hope is someone could help me get this time to be more consistent or, failing that, predictable.

If I do not have a set time period between getting GPS data, my auto-pilot code will become useless as it is based on integration of gyro data (needs a fixed time period). E.g. If the "GPS Read Time" was always 1000, I could run a 20 millisecond stabilization loop 50 times then retrieve the data.

I put the while(!No Data) in so that later (once I figure out how to stabilize the wait time), I can put the auto-pilot code into that loop. The code isn't going to sit around with it's thumb up it's a** once I've figured out how to predict the GPS.

Any details I'm short on I will try to update you with, please be specific, I'm not a programmer. Thanks.

srnet:
Yes, dont use the SD or the receiver or remove some other functions.

Or just upgrade to an Arduino with more memory.

The SD alone will add around 37% to Flash and 35% to program memory.

Many other groups doing the same project have left out the GPS to deal with the high flash/ memory problem. I know it's difficult but I'd like to try and include it.

Part of the project specification is to only use an Uno, the challenge is to make efficient code.

Is it a waste of my time to attempt? Or is it possible?

Thanks.

freaklabs:
It looks like you don't have a valid fix when you are printing out your read time. Basically, it seems like you are just measuring the time the GPS spits out data. The GPS will output data via sentences and the sentences are different lengths. I don't think you are accurately measuring what you are trying to measure.

Before I commented out the section printing the lat and long, the code was outputting valid coordinates. Correct me if I'm wrong, but if the GPS has no fix, shouldn't it print "No Location Data available.".

Here:

slash-dev mentions "coherent fixes vs individual sentences". I've guessed so far that the variable fix has all of the sentences built in, again, I'm not a programmer so correct me if I'm wrong.

I made the code print the GPS's time (in seconds) to make sure it was updating, so the fix variable does definitely hold time and location at least, which is all I need.

PalmerEng4:
Many other groups doing the same project have left out the GPS to deal with the high flash/ memory problem.

Is it a waste of my time to attempt? Or is it possible?

Well you tell us, if lots of people have tried before, how close did they and you get ?

The SD in particular uses a lot of memory, not a lot you can do about that, although there are regular requests on here for a 'smaller' SD library.

PalmerEng4:
Correct me if I'm wrong, but if the GPS has no fix, shouldn't it print "No Location Data available.".

Not sure it depends how the library treats aging of the fix.

If the location data is read from the GPS one second, does the 'Location data' become invalid the next second when the GPS looses its fix ?

It is possible to use an ATMega1284P based board (16 kB RAM, 128 kB flash)? If so, then it would make things a lot easier. The main issue is the ATMega328P on the Uno is very limited at 2kB RAM and 32kB flash.

srnet:
Well you tell us, if lots of people have tried before, how close did they and you get ?

The SD in particular uses a lot of memory, not a lot you can do about that, although there are regular requests on here for a 'smaller' SD library.

So far a sketch of roughly the same size including all the library's uses around 80% RAM, and similar memory. It's tight but I'm not done optimizing everything yet. I think previous groups have managed it, but not with data logging every second.

The SD library is one of the things I've been trying to reduce (I'm using SDfat), but I was going to put that in another thread. Calling GPS data at a consistent time period is my current hurdle.

srnet:
Not sure it depends how the library treats aging of the fix.

If the location data is read from the GPS one second, does the 'Location data' become invalid the next second when the GPS looses its fix ?

Good spot. I think so, but it does pick up valid data once it re-gains a signal. I'll get an active antenna to go on the GPS for the flight, but there isn't much else I can do to help the signal.

freaklabs:
It is possible to use an ATMega1284P based board (16 kB RAM, 128 kB flash)? If so, then it would make things a lot easier. The main issue is the ATMega328P on the Uno is very limited at 2kB RAM and 32kB flash.

I have asked my staff if I could invest in a higher capacity computer, but we aren't allowed. They want us to optimize our code, thanks though.

PalmerEng4:
I have asked my staff if I could invest in a higher capacity computer, but we aren't allowed. They want us to optimize our code, thanks though.

I can see the point of a learning exersize where you are limited in processing power and memory, but pushing the limits is perhaps not a good choice where there are safety implications, such as in a UAV.

It seems to me that the main problem is more of processing efficiency and not necessarily memory (although that may be a separate issue).

The biggest inefficiency I see is here:

while (!gps.available(gpsPort)){
  }

This is a blocking delay and is BAD JUJU. This will block your code for at least a whole second waiting for the next fix. The best thing to do is the following:

if (gps.available(gpsPort)){
  //do gps logging here
}

This way you only tie up processing power for the GPS when you get actual GPS data - the rest of the time the Arduino can process anything such as sensor polling from the IMU, printing debugging messages, datalogging, whatever else there is to be done.

I hope this helps.

Also, you will want to jack up the baud of both serial ports to around 115200. Depending on the GPS model, you can change the baud settings through certain configuration packets. There is also a chance you can change the refresh rate of the GPS with configuration packets. I know for certain you can make both of these changes for a NEO-6M GPS, but I don't know about the Adafruit one.

Power_Broker:
It seems to me that the main problem is more of processing efficiency and not necessarily memory (although that may be a separate issue).

The biggest inefficiency I see is here:

while (!gps.available(gpsPort)){

}




This is a blocking delay and is **BAD JUJU**. This will block your code for at least a whole second waiting for the next fix. The best thing to do is the following:



if (gps.available(gpsPort)){
  //do gps logging here
}




This way you only tie up processing power for the GPS when you get actual GPS data - the rest of the time the Arduino can process anything such as sensor polling from the IMU, printing debugging messages, datalogging, whatever else there is to be done.

I hope this helps.

Also, you will want to jack up the baud of both serial ports to around 115200. Depending on the GPS model, you can change the baud settings through certain configuration packets. There is also a chance you can change the refresh rate of the GPS with configuration packets. I know for certain you can make both of these changes for a NEO-6M GPS, but I don't know about the Adafruit one.

I'm planning on putting most of the code within the while loop, but I guess that's effectively the same? I'll give it a go.

I didn't know anything about the baud rates so that's really helpful cheers.

PalmerEng4:
I'm planning on putting most of the code within the while loop, but I guess that's effectively the same?

Yes.

Your code will work best if you test for "if" there is data, not "while" there isn't data - this is the most efficient and responsive way to handle GPS data.