Go Down

Topic: GPS U-Blox Neo M8N parser (Read 17523 times) previous topic - next topic

rockeronline00

Mar 04, 2015, 08:39 pm Last Edit: Mar 04, 2015, 10:19 pm by rockeronline00
Hi,
does anyone have a NMEA parser for this GPS?
Thank you
MS in Computer Science
Drones addicted
Musician and composer

rockeronline00

MS in Computer Science
Drones addicted
Musician and composer

riodda

There are several NMEA parsers like tiny gps, the ublox gps have also a very handy binary mode you can see a video on youtube, just search for "10Hz U-blox binary GPS data in 66 lines of code (arduino) "  from the user iforce2d



rockeronline00

#3
Mar 05, 2015, 05:34 pm Last Edit: Mar 05, 2015, 09:24 pm by rockeronline00
It works only with Neo 6M, he says that in the first 30sec . Same thing TinyGPS
MS in Computer Science
Drones addicted
Musician and composer

-dev

does anyone have a NMEA parser for this GPS?
As others have said, TinyGPS will work with this device.

You're asking about an NMEA parser -- almost all GPS devices output NMEA "sentences", which can be parsed by many different NMEA parser libraries.  But because the NMEA format is fairly inefficient, many GPS manufacturers also support a binary format that is unique to their devices (i.e., not "standard").  Few parser libraries can also support the binary format of specific GPS brands.

The ublox NEO-M8 can output NMEA, UBX and RTCM messages (spec here).  It outputs NMEA by default, which can be parsed by TinyGPS.

The YouTube video referenced above links to some very simple code for parsing one UBX message.  It expects the device to be configured to output only that message... you must use the U-Center application to turn all the other messages off (including the default NMEA messages), enable just the POSLLH message, and set the message rate.

While it does verify the checksum on the message, it does not configure the device during setup, and it does not verify that it is receiving the expected POSLLH message.  If you only need Lat/Long, not Speed/Heading, it could work for you.

First, you have to decide at what update rate you need the information.  If you just need it once per second (or less frequently, say once per minute, hour or day), NMEA would be fine, and you could use TinyGPS.  If you need updates 10 times per second, you have to use the binary messages (UBX) because they're quicker to transmit (fewer bytes) and quicker to parse (no char-to-int conversion).  TinyGPS will not work.

Next, you have to decide what kinds of information you want: Lat/Long, Speed, Heading, Altitude, Time, Date, etc.  From those elements, you can choose which messages contain those pieces.  That will allow you to select the configuration commands you need to send during setup.  For example, to receive Speed/Heading, you will need to enable (and parse) the NMEA GPRMC message, or the UBX VELNED message, depending on which protocol you selected in the first step.

Next you should decide if you need coherency: if you care that a speed reading is correlated with the lat/long reading at the same time, you must group the received information from a batch of messages in the same time interval.  Easier said than done... :)

And finally, you should decide what to do with status information.  What should you do when there is no satellite fix?  You may have some pieces, but not others: you may have Time and Date, but not Lat/Long.

You haven't told us what you're doing with the GPS device, though... If you're using it in a quadcopter, you'll need to parse several messages at a high data rate (i.e., binary messages), and coherency (and more... :) ).  My library, NeoGPS, would work for that.    It is fully configurable to minimize RAM and program space, based on which pieces you need.  NeoGPS is more robust than the iforce2d code, and it uses even less RAM.  NeoGPS is longer than his 66 lines, though, and will add at least 800 bytes of program space instead of his 200 bytes.  TinyGPS adds about 2400 bytes of program space.

If you're just making something like a reverse geocache, you'll only need one NMEA message at a low data rate, and no coherency.  Again, TinyGPS would work for that.

Cheers,
/dev

-dev

Hey!  I just realized you asked about the Neo-6M over here.  Did you end up buying the M8?

FWIW, the M8 appears to be backward-compatible.  That is, it appears to support all the messages that the 6M has, plus a few new ones.  NeoGPS implements most of the NMEA messages (GGA, GLL, GSA, GST, GSV, RMC, VTG, ZDA, PUBX00, PUBX04) and UBX messages (STATUS, TIMEGPS, TIMEUTC, POSLLH, VELNED, SVINFO) that you would probably need.

Cheers,
/dev

rockeronline00

Hi dev, 
yes I asked info about 6M but then I compared it to the M8 and there were no chances.. The last one is better.
Since it uses GLONASS I needed to write a custom parser for these messages : GNRMC ,  GNGGA
Now it works,  if you need it I can post the code.
MS in Computer Science
Drones addicted
Musician and composer

-dev

#7
Mar 07, 2015, 06:43 pm Last Edit: Mar 08, 2015, 07:49 pm by /dev
Quote
Since it uses GLONASS I needed to write a custom parser for these messages : GNRMC ,  GNGGA
Ah, I see.  After a little research, I see that this is the same as the GPRMC, except the "talker ID" is "Mixed GNSS", not GPS alone.  It's also one of the things that the Linux gpsd watches for, and basically ignores (discussion here).  I'll investigate incorporating different talker IDs into NeoGPS.  This explains (to me) why TinyGPS doesn't work with this device.

For anyone else using this device, there is a way to make it always send GPxxx instead of choosing GPxxx / GNxxx / GBxxx / GLxxx / GAxxx messages (e.g., GPRMC, not GNRMC).  These all contain the same information, they just have different talker IDs.

The ublox M8 device family has a configuration command called CFG_NMEA (see section 21.11.13.4, Extended NMEA protocol configuration V1).  This command allows you to set the mainTalkerID to "GP" (value 1).  If you also use the GPGSV message, you would also want to force the gsvTalkerID to use the mainTalkerID.  I suspect you would also have to set the Beidou talker ID to "GP" (two characters).

I think the bytes to send during setup would be:

Code: [Select]
const char cfg_nmea[] __PROGMEM =
  {
    0xB5,     // sync 1
    0x62      // sync 2
    0x06,     // CFG class ID
    0x17,     // CFG_NMEA msg id
    20, 0,    // bytes to follow
    0,        // filters disabled
    0x40,     // NMEA version 4.0
    0,        // Number of satellites reported in GSV = unlimited
    0x02,     // compatibility disabled, consideration mode enabled, limit to 82 char maximum disabled
    0, 0, 0, 0, // no GNSS satellites filtered
    0,        // strict satellite numbering
    1,        // main talker ID = GP
    1,        // GSV talker ID = main talker ID
    1,        // CFG_NMEA message version
    'G', 'P', // Beidou talker ID = GP
    0,0,0,0,0,0,  // fill
    0x0D      // CK_A
    0xC1      // CK_B
  };

This would allow GPS-only NMEA parsers like TinyGPS to work with this device.

BTW, the UBX parser in NeoGPS (like any binary parser) is not affected by the talker ID; this is an NMEA-only "feature".

Quote
if you need it I can post the code.
Of course!  We all like code!  :)

Cheers,
/dev

-dev

#8
Mar 08, 2015, 03:37 pm Last Edit: Mar 08, 2015, 07:50 pm by /dev
Oopsies!  The "bytes to follow" is a word length.  I added a zero byte above and updated CK_B.  Still untested, as I do not have that hardware, but it is more likely to work now.  ;)

Cheers,
/dev

P.S.  After coding it up and sending it to the Neo 6M, I found that the version 4.0 field should have been 0x40, not 4.  updated above...

rockeronline00

#9
Mar 10, 2015, 02:39 pm Last Edit: Apr 12, 2015, 10:44 pm by rockeronline00 Reason: bug fixed
I found a nice parser online which I modified in order to get data from the U-Blox Neo M8N
Create a file .ino and include the files attached in this post
EXAMPLE:
Code: [Select]

// Use this code with UBLOX NEO M8N
#include "Ublox.h"
#define SERIAL_BAUD 115200
#define GPS_BAUD 115200
#define N_GPS_DATA 4

Ublox M8_Gps;
// Altitude - Latitude - Longitude - N Satellites
float gpsArray[N_GPS_DATA] = {0, 0, 0, 0};

void setup() {
   Serial.begin(SERIAL_BAUD);
   Serial1.begin(GPS_BAUD);

}

void loop() {
   if(!Serial1.available())
return;

  while(Serial1.available()){
        char c = Serial1.read();
        M8_Gps.encode(c);          
        gpsArray[0] = M8_Gps.altitude;
        gpsArray[1] = M8_Gps.latitude;
        gpsArray[2] = M8_Gps.longitude;
        gpsArray[3] = M8_Gps.sats_in_use;
}
}

MS in Computer Science
Drones addicted
Musician and composer

-dev

Great, thanks for that!  One thing I noticed... I would suggest changing your while loop from this

Code: [Select]
  while(Serial1.available()){
        char c = Serial1.read();
        M8_Gps.encode(c);           
        gpsArray[0] = M8_Gps.altitude;
        gpsArray[1] = M8_Gps.latitude;
        gpsArray[2] = M8_Gps.longitude;
        gpsArray[3] = M8_Gps.sats_in_use;
}

to this:

Code: [Select]
  while(Serial1.available()) {
        char c = Serial1.read();
        if (M8_Gps.encode(c)) {
          gpsArray[0] = M8_Gps.altitude;
          gpsArray[1] = M8_Gps.latitude;
          gpsArray[2] = M8_Gps.longitude;
          gpsArray[3] = M8_Gps.sats_in_use;
        }
  }

Like many libraries, Gps.encode(c) will return true when a sentence has been completely received.  There's no reason to copy the values when any character is received.  Not a big deal, unless you're trying to do other things at the same time.

For anyone else landing here, you could also modify TinyGPS.cpp to accept these messages by changing these lines:

Code: [Select]
#define _GPRMC_TERM   "GNRMC"
#define _GPGGA_TERM   "GNGGA"

Other libraries have similar literals that could also be modified.

The Bad News: they will then ignore the normal GPRMC and GPGGA sentences.  If the receiver is not tracking any GLONASS satellites, it would emit GPRMC instead.  Adding a check for "GNRMC" or "GPRMC" is not very difficult.

Also, I have just finished implementing the NMEA Talker ID concept in NeoGPS, and it will now accept the "GNRMC" et al.  This actually improved the performance by about 10%!  Ah, skipping bytes is good...  :)

Cheers,
/dev

rockeronline00

#11
Mar 10, 2015, 10:59 pm Last Edit: Mar 10, 2015, 11:04 pm by rockeronline00
You're right! thank you for the tip.
I forgot do say that there are more GPS info you can read with the library I attached.
e.g.  HDOP, PDOP, satellites in view, time .
bye
MS in Computer Science
Drones addicted
Musician and composer

jferg

After the usual convulsions, i figured out how to set the talker on my NEO M8N to GP instead of GN so that TinyGPS++ could read the sentences.  Since Tiny reads only GPRMC and GPGGA, I also configured the M8N to emit only those sentences.  I'm reading lat, lon, and time just fine but not altitude.  I want altitude as well and I suppose now I'll have to get into Tiny and see where it went.  It does read using another chip, so this must be an anomaly of using the M8N.  if it reads altitude ok on another chip but not on the M8N, the re must be some difference in the sentence words.

While I'm at it, it looks as though the frequency of sentence output is controllable but so far I haven't been able to get it to do this.  I also suspect that the usable navigation data rate may be affected negatively by using fewer sentences. it'd doesn't look like the update rate is improved at all byu using just GPGGA and GPRMC instead of all of them.

Is that correct?

I'd like 10 Hz usable nav data rate.  Is that nuts?


-dev

#13
Jan 03, 2016, 02:43 am Last Edit: Jan 03, 2016, 02:44 am by /dev
Quote
it'd doesn't look like the update rate is improved at all by using just GPGGA and GPRMC instead of all of them.
I think that's right.  It seems like the update rate can't be changed to 10Hz for NMEA, only 5Hz.  Have you changed the baud rate, too?  u-center is a good way to test that setting.

The NeoGPS library I wrote can parse all talkers, not just GP, and it's a much smaller and faster NMEA parser than TinyGPS/TinyGPS++.  It also implements the UBX binary protocol, so you could use it to send the configuration commands.

Depending on what else you're doing, 10Hz is possible.  NeoGPS and/or NeoHWSerial could help.

Cheers,
/dev

jferg

/dev

Thanks for the note.  I reset the M8N to default, loaded up your code and have been having a pretty good time with it.  I'm running the M8N at 9600, but will now go back to U-Center and try it at 57600 with serial output at 115200. And try to see if I can get the update rate higher. I can see I'll need to fuss with this a bit, but now that I'm getting reliable output I've got a good place to start. 

This system will run on a nano and be part of a datalogging system which will go for rides in a small fixed-wing r/c aircraft to collect information the better to design very small autonomous aircraft sometime next year.

I have to say I like /dev.  I wonder if /etc or /bin is taken yet

And cheers yourself.  thanks for some vary capable code,

John

Go Up