Closed learmond closed 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 .
@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.
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.
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?
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:
loop
? You should see continuous '.' characters printed by the poll while loop. Or...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
true
response from send
. You said, "the send command returns true", so the GPS device really obeyed your request. There's no reason to poll
for confirmation.poll
for a message, you should implement a state machine like that in ublox.ino
. It disables all messages at the beginning so that the protocol handling is simpler. In your case, disabling everything first will probably allow a poll
to work for one specific message. After you have configured (and polled, if you really need to) everything, you can enable the periodic messages of interest. Then NeoGPS will be in the "mode" of providing fixes from the received messages. This prevents the periodic messages from interfering with the protocol timing of ACKed/polled messages.::send
and ::wait_for_ack
that can give you additional information on why the send
failed.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.
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.
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!
Glad to help.
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
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.