SlashDevin / NeoGPS

NMEA and ublox GPS parser for Arduino, configurable to use as few as 10 bytes of RAM
GNU General Public License v3.0
706 stars 195 forks source link

Ublox Config Example #69

Closed learmond closed 6 years ago

learmond commented 6 years ago

First off, this is by far one of the best documented libraries I've come across, so thank you very much! I wondering if you have any more examples illustrating how to configure the ublox neo chips? For instance, configuring the "Dynamic Platform Model" (to 'Pedestrian' or 'Automotive'), or performing an 'Aiding Sequence' on cold startup using the UBX-AID message class (supplying almanac or ephemeris data)? Even tips on how to use the library to send configuration messages would be excellent. Thanks again.

jamesmayes commented 6 years ago

I agree on the library quality! I just wanted to share that using the u-blox u-center application (Windows only unfortunately) has proven very valuable for me to configure my MAX-M8Q. It provides a nice pick list of commands with request/response capabilities. I use that and then apply the desired commands in my Arduino Sketch. Have you tried it out?

On Fri, Jan 26, 2018 at 12:35 lear notifications@github.com wrote:

First off, this is by far one of the best documented libraries I've come across, so thank you very much! I wondering if you have any more examples illustrating how to configure the ublox neo chips? For instance, configuring the "Dynamic Platform Model" (to 'Pedestrian' or 'Automotive'), or performing an 'Aiding Sequence' on cold startup using the UBX-AID message class (supplying almanac or ephemeris data)? Even tips on how to use the library to send configuration messages would be excellent. Thanks again.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/SlashDevin/NeoGPS/issues/69, or mute the thread https://github.com/notifications/unsubscribe-auth/ACEgL3kY1Fj706ZTY0wH3NvtWERjxIn8ks5tOhrUgaJpZM4Rus4j .

learmond commented 6 years ago

@jamesmayes Thanks for the reply! I haven't used the u-center app, however I'll check it out. Do you mean it generates ubx message code for you which you put into your sketch? As I dig into ubxmsg.h, comparing it with the protocol data sheet, I'm starting to see how it works, at least for polling the chip ;) ie:

ublox::cfg_nav5_t currNavCfg;

// m_ublox is an instance of ubloxGPS.
m_ublox.poll(currNavCfg); // The supplied msg struct is populated with the response payload.

Serial.printf("Dyn Model: %d\n", currNavCfg.dyn_model);
Serial.printf("DPGS Timeout: %d\n", currNavCfg.dgps_timeout);
//... etc

I do want to try implementing Differential GPS, so I'll report back with any tips.

SlashDevin commented 6 years ago

Thanks for the kind words.

The ubxmsg.h classes can be used to configure the device as well as query the current configuration. Here's an example I wrote for a developer that wanted confirmation of the configuration (i.e., ACK received):

  //  THIS COMMAND SETS FLIGHT MODE AND CONFIRMS IT 
  cfg_nav5_t setNav;
  setNav.apply_word         = 0xFFFF; // 0x0000 works, too
  setNav.dyn_model          = UBX_DYN_MODEL_AIR_1G;
  setNav.fix_mode           = UBX_POS_FIX_AUTO;
  setNav.fixed_alt          = 0;     // m
  setNav.fixed_alt_variance = 10000; // 10000 * m^2
  setNav.min_elev           = 5;     // degrees
  setNav.dr_limit           = 0;     // s
  setNav.pos_dop_mask       = 250;   // 10 * DOP
  setNav.time_dop_mask      = 250;   // 10 * DOP
  setNav.pos_acc_mask       = 100;   // m
  setNav.time_acc_mask      = 300;   // s (although spec says "m")
  setNav.static_hold_thr    = 0;     // cm/s
  setNav.dgps_timeout       = 0;     // s

  Serial.print( F("Setting uBlox nav mode") );
  while (!gps.send( setNav )) {
    Serial.print( '.' );
    delay( 500 );
  }
  Serial.println();

This was for a high-altitude balloon (HAB), so it selected the "air" model, lowest acceleration. You'll have to read the spec for the meaning of all fields.

learmond commented 6 years ago

Thanks for the help @SlashDevin Wondering if you could confirm a few more things... Looking at the protocol document for Nav 5 Config message (page 119-120), the bit mask can be used to only apply changes to a particular field. So, if I wanted to only change the dynamic model, would the apply_word field be set to 0x0001 since the dyn bit is position 0? ie:

ublox::cfg_nav5_t navCfg;
navCfg.apply_word = 0x0001;
navCfg.dyn_model = ublox::UBX_DYN_MODEL_PEDESTRIAN;
while( !gps.send(navCfg) )
{
   ...
}

This seems to work, as the send command returns true, however when I go to poll the config, it fails:

ublox::cfg_nav5_t navCfg;
while(!gps.poll(navCfg))
{
  Serial.print('.');
  delay(500);
}

This never returns, and eventually the watchdog triggers (i'm using an esp32 and ublox NEO M8N).

If I just poll it once, then it returns as failed:

ublox::cfg_nav5_t navCfg;
bool success = m_ublox.poll(navCfg);
Serial.printf("Poll [%s]. Dyn Model: [%d]\n", success?"succeeded":"failed", navCfg.dyn_model);

prints: Poll [failed]. Dyn Model: [0]

Is this not how to use the poll API?

SlashDevin commented 6 years ago

the bit mask can be used to only apply changes to a particular field.

Oh, yes, that's the correct way to change just one field from the default.

This never returns, and eventually the watchdog triggers

Usually, this means you are not using INTERRUPT processing style when you should. NeoGPS should not "hang" in poll, so I have to ask:

Calling send/poll is less reliable when there are a lot of messages coming back from the GPS device.

i'm using an esp32

Ah.

I do not know of a serial library (hardware or software) that allows attachInterrupt on this platform. None of the NeoXXSerial libraries are ported to the ESP32.

The UBX protocol is much more complicated than NMEA, and it is far easier to deal with the protocol when the processing style is INTERRUPT. In your case, I suspect that subtle timing differences prevent the POLLING style from correctly receiving the ACK packets from the M8N.

For now, I would suggest

If these suggestions don't get you going, the next step would be to derive a class from ubloxGPS and override the storage_for method. This would allow you to "receive" poll responses that are outside the normal message processing (fixes from NAV-POSLLH et al). I don't think you'll have to do this.

SlashDevin commented 6 years ago

One more thing:

if I wanted to only change the dynamic model, would the apply_word field be set to 0x0001 since the dyn bit is position 0?

You could do that, but it would be better to use the bitfields I set up for you:

ublox::cfg_nav5_t navCfg;
navCfg.apply.dyn_model = true;  <--  much easier to read!
navCfg.dyn_model = ublox::UBX_DYN_MODEL_PEDESTRIAN;
while( !gps.send(navCfg) )
{
   ...
}

The union of the bool struct apply and the 16-bit int apply_word are just to make sure they take up the correct amount of space in the message packet.

learmond commented 6 years ago

Thanks for the detailed reply!

You could do that, but it would be better to use the bitfields I set up for you:

Ah, I see, that is much better. Thanks for the clarification.

Currently, I'm not using INTERRUPT driven logic. The gps polling is in its own task on its own core of the ESP32 with the gps serial port running at 9600 baud. The task loop runs flat out with a small vTaskDelay before checking and reading any gps serial data, so I figured this would be sufficient for any timing issues (whose effect I'm a little fuzzy on) that exists wrt to reading bytes at a sufficient rate. The config settings are applied at a "task init" time which occurs before the main task loop, so maybe I can disable the watchdog until the initialization has completed.

My end goal with all of this is to set a particular dynamic model, receive gps updates at around 2-5 Hz, and implement aided startup as well as differential GPS... though that is a totally different beast. Really, the polling for config was mostly there to help understand how I can talk to the chip with your lib.

... several hours later...

I've now managed to disable all PUBX messages at startup, which has allowed me to carefully manage polling and setting of config, similar to your ubloxRate.ino example. This includes getting the Firmware versions, setting the Dynamic Model NAV5 config, as well as the MSG Rate config. Then enabling the messages again before entering the main task loop.

All that's left is looking into the Differential GPS protocol. Thanks again for your help!

SlashDevin commented 6 years ago

Glad to help.

CF20852 commented 6 years ago

I would like to echo some of the commenters who have praised this library. I have found the comments and replies under this issue particularly helpful, because I wanted to change the default configuration of the NEO-6M to tailor it to a hiking environment (NAV5: Pedestrian dynamic model), in which there are occasional obstructions (NAV5: Ded(uced) Reckoning Limit = 20 seconds... yeah, I know that's risky). I also wanted to reduce the default messages my Arduino has to deal with to just GPGGA and GPGSA.

Thanks, /Dev! CF20852