Go Down

Topic: understanding tinyGPS++ (Read 488 times) previous topic - next topic

aster94

hello,

I just started experimenting with GPS and i am using this library, I have a few questions for someone that had already explored the .h and .cpp files. I am using a neo-6m wired to the hardware serial of an arduino mega

is possible to have a flag set when there are data from the GPS? I don't want to use a "while" to wait for data to arrive

this kind of functions, for example: "gps.date.month()", exactly what do they do? do they ask to the gps for data and than process it or they just extract it from data that are been received previously?

i know that i could discover these info from a study into the .h and .cpp files but i am a hobbyist, i "play" with arduino when i stop working so if someone could help me it would be very appreciated

thanks :D

jremington

#1
Apr 17, 2017, 12:39 am Last Edit: Apr 17, 2017, 12:39 am by jremington
TinyGPS++ processes characters one at a time, and lets you know when a complete, valid GPS data sentence has been received and the data are available. You have to wait for that to happen, one way or another.

Functions like date.month() return previously received data.

aster94

Thanks for your answer but i am not sure if i understood:
"lets you know when a complete, valid GPS data sentence has been received and the data are available"
It looks like that there is a way to know if the data are available, isn t it? How does it works?

jremington

Quote
It looks like that there is a way to know if the data are available, isn t it?
It certainly does look like that! More here.

-dev

Here's a little overview to get you started:

NMEA GPS devices send "sentences" that contain various comma-separated fields.  Each sentence starts with a '$' character and ends with a newline (CR/LF).  Some sentences contain location and time, but not a date.  Others have speed, but not altitude.  So it usually takes several sentences before you have all the pieces that you want (see also this table).

These sentences are sent in a "batch", usually once per second.  Then the GPS device is quiet until the next second begins.  The GPS quiet time is a good time to do other time-consuming tasks in your sketch.

All GPS parsers convert these received characters into parsed values like ints (e.g., the current month) or floats (e.g., an altitude).  Because the characters arrive slowly (for a 16MHz Arduino), it is very inefficient to wait for all of them to arrive.  Some libraries do it anyway.  :-/

Regarding specific libraries:

Adafruit_GPS gradually accumulates one sentence at a time (with a TIMER interrupt that reads the GPS characters), and then parses it all at once, when the newline arrives.  This takes extra RAM for the sentence "buffer", and extra CPU time to copy and search through the buffer.  It does not validate the checksum, so it may provide invalid data.  It does not know anything about the entire batch of sentences or the GPS quiet time.

TinyGPS and TinyGPS++ "encode" one character at a time and let you know when a complete sentence has been parsed.  It is a little more efficient, because it only buffers one field at a time, not the entire sentence.  Unfortunately, the example programs are poorly structured and use a routine to wait for sentences to arrive.  It does not know anything about the entire batch of sentences or the GPS quiet time.

My NeoGPS is smaller, faster and more accurate than all other libraries.  It is the only library that merges multiple sentences (which contain various pieces) into one coherent fix structure.  That structure remembers which pieces were really received and parsed into a structure member.  There is one "valid" flag for each piece that you can test.

The typical NeoGPS program:

Code: [Select]
NMEAGPS  gps; // This parses the GPS characters
gps_fix  fix; // This holds on to the latest values

void setup()
{
  Serial.begin(9600);
  gpsPort.begin(9600);
}

void loop()
{
  while (gps.available( gpsPort )) {
    fix = gps.read();

    Serial.print( F("Location: ") );
    if (fix.valid.location) {
      Serial.print( fix.latitude(), 6 );
      Serial.print( ',' );
      Serial.print( fix.longitude(), 6 );
    }

    Serial.print( F(", Altitude: ") );
    if (fix.valid.altitude)
      Serial.print( fix.altitude() );

    Serial.println();
  }
}

This code does not "block" with a while loop or delay.  loop runs over and over, until multiple sentences have been received and parsed into a new fix.  NeoGPS is the only library that knows when a batch of sentences is complete and the GPS quiet time begins.

After "reading" the fix structure from the gps object, you can look at the valid flags and data members.  All of the fix members have been completely received; testing fix.valid.location confirms that the lat/lon was received, and calling fix.latitude() simply returns the value that is stored in the structure.

One final advantage of NeoGPS is that you can configure it to parse and save only the fields that you care about.  Everything else is quickly skipped, using no RAM and very little CPU time.  It is very common for a NeoGPS program size to be thousands of bytes smaller, and use hundreds of bytes less RAM.

If you want to try it, it is also available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.  The above code is from the example NMEAsimple.ino.  Even if you don't use the library, be sure to look at the examples for the proper program structure.  The Troubleshooting page describes many typical problems, especially when using other libraries.

Cheers,
/dev

aster94

Thanks for your answer dev it was really usefull, i knew something but not so well,  but it leads me to more questions

Quote
So it usually takes several sentences before you have all the pieces that you want (see also this table).
Would it be possible to program the gps to send only "useful" sentences? I know that with the ublox utility is possible. I was only thinking to increment the baudrate, have you tested a "safe" maximum speed? 

 Your library looks like exactly what i need :) and the struct idea is smart
I didn t read all the documentation but in these days i will play with it for sure

-dev

Quote
Would it be possible to program the gps to send only "useful" sentences?
Yes.  This reduces the number of characters that have to be processed by the Arduino and allows the baud rate to remain low.  Because the Mega has extra HardwareSerial ports Serial1, Serial2 and Serial3, baud rates up to 115200 are no problem.

On Arduinos without extra serial ports (e.g., an UNO), you should keep software serial port baud rates at 38400 or less.  Use the AltSoftSerial or NeoSWSerial libraries.

Oddly enough, I just uploaded a NeoGPS example to send those configuration commands to a ublox NEO-6/7/8 device (see ubloxRate.ino).  That sketch configures the GPS device.  Of course, you have to make sure the Arduino is "configured" to receive those sentences, by editing NMEAGPS_cfg.h (ubloxRate.ino requires GLL).  You also need my NeoTee library.

Cheers,
/dev

aster94

Great tomorrow i will run some test :D

I have a curiosity that maybe you could resolve i am using a neo-6m took on aliexpress for 6euros a few people said me that it could be a fake, what do you think about?

Have you ever tried to upgrade the firmware of a ublox gps? Did you ever find notable better performances?

-dev

I am using a neo-6m took  I bought  on aliexpress for 6euros.  A few people said  told  me that it could be a fake, what do you think about [that]?
Maybe.

Quote
Have you ever tried to upgrade the firmware of a ublox gps?
No.

Be sure you are level-shifting 5V Arduino signals down to 3.3V for the GPS RX pin.  A resistor divider will work for that.

aster94

Great i will use your lib, increment the update rate to 10hz and the baudrate to 115200, in this way i hope i will have a enough fast gps :D

Thanks for all these precious suggestions and also for the grammar corrections ahahah

aster94

Hey dev, your ubloxRate sketch does change permanently baudrate, sentences and frequency?
Because i changed them with ublox center but when i disconnected the decice it returns to default values

Anyway i studied the nmea protocol and i m going to use only RMC and GGA. Do you suggest me to keep more sentences?

-dev

Quote from: aster94
Does the ubloxRate sketch permanently change the baudrate, sentences and frequency?
No.  If the GPS device is powered off, its settings return to the default values.  I always recommend putting the configuration commands in setup so they are sent when the Arduino restarts.  Assume that the GPS is running at 9600 and send the commands.  Then switch the Arduino to the desired baud rate.

If the GPS was using the default settings because it was powered off (or replaced), setup will re-configure it to the new baud rate.

If the GPS was using the previous settings because it was not powered off, the configuration commands will be sent at the default baud rate and will be ignored.

This works in both cases, so it's safest.  You can also use u-center to permanently save the configuration.  But if you ever replace the GPS and forget to configure it, it won't work unless you send the configuration commands in setup.  If someone else wants to try your sketch, it would be nice if the commands are in setup so they don't have to use u-center.

Quote
I studied the NMEA protocol and I'm going to use only RMC and GGA.  Do you suggest using more sentences?
Decide which pieces of a fix you need, then use this table to choose the minimum number of sentences.  Enable those pieces in GPSfix_cfg.h, enable those sentences in NMEAGPS_cfg.h, and enable those sentences in the GPS device by sending the configuration commands in setup.

Disabling other pieces makes the fix structure use less RAM.
Disabling other sentences makes the sketch use less program space and CPU time.
Disabling other sentences in the GPS device "reduces the number of characters that have to be processed by the Arduino and allows the baud rate to remain low", as I said above.

aster94

#12
Apr 21, 2017, 04:37 pm Last Edit: Apr 21, 2017, 04:56 pm by aster94
it looks like that in GPSfix_cfg.h you already enabled only the  most usefull

Code: [Select]

#define NMEAGPS_PARSE_GGA
//#define NMEAGPS_PARSE_GLL
//#define NMEAGPS_PARSE_GSA
//#define NMEAGPS_PARSE_GSV
//#define NMEAGPS_PARSE_GST
#define NMEAGPS_PARSE_RMC
//#define NMEAGPS_PARSE_VTG
//#define NMEAGPS_PARSE_ZDA


so i won't need to do nothing

anyway i don't understand if there is any difference in the position held by RMC and GLL, could you explain it?

EDIT: 60mseconds is the minumum the NEO6M could reach, is safe to use this value or is better to stay on the tipical 100ms (10Hz)?

Go Up