Go Down

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

jferg

/bin
further to the above.  It looks like I might be able to skip nmea altogether, use the UBX messages pollh and one for time and i'd have what I need and might be able to get it at 10 Hz.  And yes U-center looks like the place to play with this.

I could log this output as is, no transformations before recording and then convert it to something I'm used to looking at when i analyze it.  the airborne logger won't having a display, but i'll plug a little oled terminal into a port on it when I fire it up to make sure it's recording reasonable data before I launch.

have you tried running only on UBX sentences?

john

-dev

Quote
I have to say I like /dev.
Everybody likes /dev!  Except String-lovers.  They've got no stars upon thars.  ;)

The reason I asked about the baud rate is because the ublox knows when there's too much data to send at a particular baud rate.  It will throw "frames" away if they can't get transmitted before the next update.  If you're running at 9600, an 80-character NMEA sentence will take ~80ms.  That's most of the update interval right there.  A second sentence can't get sent before the next update interval has started.  So to be sure the baud rate isn't the bottleneck, you must increase it.

Regarding polling for fixes instead of letting it send them at a fixed interval, I hope you realize it will increase the Nano CPU load, both in the number of interrupts it has to handle (TX), and in the time it takes to queue up the the request.  I'm not sure what else the Nano is doing, but 10Hz updates with logging is a significant load for this processor.  If you're careful, it's easily doable.  Logging and printing is usually what trips people up, though.

Which brings me to this last suggestion.    Many projects have trouble because so many libraries take too much time away from loop().  Even logging or printing takes time to execute, sometimes blocking until all the data gets logged or printed.  GPS data keeps rolling in, and if you don't do the Serial.read() often enough (64ms @ 9600), you will miss receiving some characters (aka input buffer overflow).  And if you increase the baud rate to 115200, that window gets even shorter: 6.1ms!  That means that no single operation you perform can take longer than 6ms, or you will lose some GPS data.

The only solution is to use an interrupt-driven approach like in NMEAfused_isr.ino (which requires NeoHWSerial).  Letting the characters be handled in an interrupt allows you to do your data logging without worrying about getting back to loop.  The fixes are "magically" updated by the interrupts, and you never have to do Serial.available() and Serial.read().

Quote
have you tried running only on UBX sentences?
Yes.  The ublox example turns off the NMEA sentences and runs in pure UBX binary protocol.  BTW, if you switch back to one of the NMEA examples, they won't work until you power off the ublox.

Everything is more complicated because it's a two-way protocol: configuration commands have acknowledgements.  And starting up takes a few seconds because you must request and receive the current GPS leap seconds and the current UTC time.  You need both before you can convert the GPS time-of-week value (ms since midnight Sunday) to a UTC time (leap seconds + time-of-week + UTC midnight Sunday).  There's a state machine in ublox.ino that shows how to do that.

I haven't seen an application yet where it's worth it to use the UBX protocol.  It does save about 120 RX interrupts per update (only 40 characters instead of 160), and the binary numbers don't have to get parsed from ASCII decimal.  It is more efficient, but unless you're trying to squeeze every last cycle out of the Nano, it may not be worth the effort.  Are you planning on using an IMU?  That does require frequent sampling and computation.

Cheers,
/dev
Really, I used to be /dev.  :(

jferg

Hi /dev
I was using a nano to sneak up on it, mostly because i have a bunch of them.  i quickly realized that when i get to the imu and controlling fixed wing flight, a nano won't do the job, so I was going to try a teensy 3.2.  I may use two of them.  ultimately, I'll build a custom board with the chips I need and nothing i don't but that is still two years away.  This is not a commercial project so time is not of the essence.



Thanks for your thoughts.  I need to think about what to try next.

best,

john

jferg

and don't worry if you see anything stupid in what i write.  i don't know what I'm doing -- yet. 


john  maybe /tmp

clemeilio

#19
May 13, 2016, 11:38 pm Last Edit: May 14, 2016, 12:14 am by clemeilio
Hi Dev,

Great work with NEOgps

I would like to use the ublox binary protocol using NEOgps and was wondering if it possible to parse an already aquired sentance.

My setup is a 4d systems screen and a spi connection to the arduino. The 4d systems screen receives the GPS data on a hardware serial port and does that job very well without any impact on the screen. I then send and receive an SPI packet where the GPS data is transferred to the arduino as byte arrays.

The reason for this, is the Arduino hardware serial is in use by a bluetooth adapter and all works well. The 4d systems screen display rate is very fluid.

Any Serial read on the arduino messes things up.

If I could pass the whole byte array to the parser as ublox binary I could maintain this very fast framerate.

If this function already exist's in the library, could you please point me in the right direction.

Thanks

-dev

Quote
My setup is a 4d systems screen and a spi connection to the arduino.
Ok, Arduino uses SPI to talk to the 4D Systems display shield...

Quote
Arduino hardware serial is in use by a bluetooth adapter and all works well.
Ok...

Quote
Any Serial read on the arduino messes things up.
Whut?  You just said all works well.

Quote
The 4d systems screen receives the GPS data on a hardware serial port and does that job very well without any impact on the screen. I then send and receive an SPI packet where the GPS data is transferred to the arduino as byte arrays.
...and this makes no sense to me.  You send and receive an SPI packet?  The screen receives the GPS data without any impact on the screen?

Quote
If I could pass the whole byte array to the parser as ublox binary...
I do not understand the description of your system, so I'll give you an answer to a question you probably did not ask:

If you have the entire message in a byte array, including the SYNC bytes, you should verify the checksum.  It's just the Fletcher checksum over everything except the first two bytes (SYNC 1 and 2) and the last two bytes (CS A and B).  If that passes, you can simply "map" the buffer onto a struct you define that matches the UBX message:

   ubxMgaGPSephMessageStruct *mgaGPSeph = &buffer[2];
   if (mgaGPSeph->uraIndex == 7) ...

If you don't have the SYNC bytes, map it starting at 0:

   ubxMgaGPSephMessageStruct *mgaGPSeph = &buffer[0]; // no SYNC bytes at the beginning
   if (mgaGPSeph->uraIndex == 7) ...

If the message is one of the messages supported by NeoGPS (NAV POSLLH, NAV VELNED, NAV STATUS, NAV TIMEGPS, NAV TIMEUTC or NAV SVINFO), you can use ubxGPS.h to get the message structure definitions:

Code: [Select]
#include "ubxGPS.h"
    .
    :

    ublox::nav_posllh_t *posllh = &buffer[2]; // map the bytes onto a struct

    // just access the posllh structure members
    display.print( posllh->lat ); // integer latitude * 10000000
    display.print( posllh->lon ); // integer longitude * 10000000

There is no parsing required if you already have all the bytes.  Just map it onto C data types in a struct.  ubxGPS.h is a C++ way to declare the struct so that it matches the ublox message spec.

Did that help?

Cheers,
/dev
Really, I used to be /dev.  :(

clemeilio

Hi /Dev,

Yes that helped a lot. I will give it a try later and let you know.

Sorry I didn't explain my system all that well.

The arduino (atmega1284P) is used for I2c sensor data collection because of it's floating point ability. The 4d screen can't handle that easily.

The 4d screen is an SPI master and will send SPI data and also retreive the sensor data in one function. If I have read GPS via the 4d serial port, it will send that at the same time. This is giving me about 18 frames per second on the screen.

The hardware Serial on the arduino is used for the bluetooth adapter and after receiving a 1 byte request for data, the arduino sends all available data to my phone via bluetooth. All very smoothly.

The second serial port on the 1248P is also int0 and int1 and I have a rotary encoder using int0/int1 so Software serial was the only option to connect the GPS to and that pauses data flow when a message is received. Reading the GPS on the 4d screen had no impact on screen framerate at all.

I am needing location and speed only from the GPS.

Many thanks

Paul

clemeilio

Hi /dev,

Managed to solve it. Using the 4d systems screen to take in data from the GPS was a bad idea, so abandoned that.

I connected the NEO6 to U center and switched off everything apart from speed and heading message and set my baud rate to 115200, at 4hz rate. At the moment I only really want the groundspeed.

I moved 1 encoder pin from int0 to int2 (the 1284p has 3 interrupt pins) and left the other encoder pin on int1 which is Serial1 TX.

I connected the GPS TX to Serial1 RX (int0) and wrote a routine to get speed from Serial1 GPS message.

Works a treat and I have a fast update rate. the converted to mph speed is then passed to 4d screen during it's spi data transfer.

I might do an interpolation to smooth out the 4hz rate so the needle on the screen moves smoothly between speed updates.

Very impressed with the NEO6 being able to get a fix indoors.

Thanks for your help.

Paul


greenonline

#23
Sep 21, 2016, 11:38 pm Last Edit: Sep 21, 2016, 11:43 pm by greenonline
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.
In order to accept BOTH GPS and GLONASS mesages, I think that the two fixes to TinyGPS.cpp are as follows:

Code: [Select]

#include "TinyGPS.h"

#define _GPRMC_TERM   "GPRMC"
#define _GPGGA_TERM   "GPGGA"

#define _GNRMC_TERM   "GNRMC" // *** added
#define _GNGGA_TERM   "GNGGA" // *** added

TinyGPS::TinyGPS()


and

Code: [Select]

  // the first term determines the sentence type
  if (_term_number == 0)
  {
    if (!gpsstrcmp(_term, _GPRMC_TERM) || !gpsstrcmp(_term, _GNRMC_TERM))      //modified
      _sentence_type = _GPS_SENTENCE_GPRMC; // *** modified
    else if (!gpsstrcmp(_term, _GPGGA_TERM) || !gpsstrcmp(_term, _GNGGA_TERM)) //modified
      _sentence_type = _GPS_SENTENCE_GPGGA; // *** modified
    else
      _sentence_type = _GPS_SENTENCE_OTHER;
    return false;
  }

beryindo

In order to accept BOTH GPS and GLONASS mesages, I think that the two fixes to TinyGPS.cpp are as follows:

Code: [Select]

#include "TinyGPS.h"

#define _GPRMC_TERM   "GPRMC"
#define _GPGGA_TERM   "GPGGA"

#define _GNRMC_TERM   "GNRMC" // *** added
#define _GNGGA_TERM   "GNGGA" // *** added

TinyGPS::TinyGPS()


and

Code: [Select]

  // the first term determines the sentence type
  if (_term_number == 0)
  {
    if (!gpsstrcmp(_term, _GPRMC_TERM) || !gpsstrcmp(_term, _GNRMC_TERM))      //modified
      _sentence_type = _GPS_SENTENCE_GPRMC; // *** modified
    else if (!gpsstrcmp(_term, _GPGGA_TERM) || !gpsstrcmp(_term, _GNGGA_TERM)) //modified
      _sentence_type = _GPS_SENTENCE_GPGGA; // *** modified
    else
      _sentence_type = _GPS_SENTENCE_OTHER;
    return false;
  }


I try not work bro

toro

i got this one in youtube
https://youtu.be/XN9PbmnRtW8

srnet

i got this one in youtube
https://youtu.be/XN9PbmnRtW8
Congratulations.
$50SAT is now Silent (but probably still running)
http://www.50dollarsat.info/
http://www.loratracker.uk/

indologic

I make this guys. maybe it will help you
https://youtu.be/XN9PbmnRtW8

TegwynTwmffat

#28
Dec 03, 2017, 06:53 pm Last Edit: Dec 03, 2017, 07:05 pm by TegwynTwmffat
Thank you SlashDev for the NeoGPS software - it works really nicely on Ublox M8M!

I've managed to get headings and distances to guide my machine but would like to see if I can sueeze out more info from the Ublox, for example number of satelites and whether there is a RTK fix between Base and Rover.

I'm probably just being stupid, but PUBX.ino won't compile:

Any suggestions? @-dev @/dev @TegwynTwmffat

TegwynTwmffat

@-dev @/dev @TegwynTwmffat

Go Up