Skip to content

Read data from UBX-NAV-ORB #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JMyrng opened this issue Jul 13, 2021 · 6 comments · Fixed by #55
Closed

Read data from UBX-NAV-ORB #52

JMyrng opened this issue Jul 13, 2021 · 6 comments · Fixed by #55

Comments

@JMyrng
Copy link

JMyrng commented Jul 13, 2021

Trying to read data from NAV-ORB

I´m using the M9N breakout board and want to know if enough ephemeris data is downloaded for a fast startup after a power down. UBX-NAV-ORB is described in the M9N Interface description in 3.15.7.

image

My workbench

  • Sparkfun 15712 M9N
  • I2C connection to Arduino MKR1310
  • External Battery on 5V pin

Expected behavior

At the end, I want to be able to evaluate whether enough data has been downloaded to achieve a quick fix (after a power cut). To do this, I need to read the data from UBX-NAV-ORB. Or is there a better way?

Actual behavior

At the moment it is not possible to read out whether enough data has been downloaded for a hot/warm start or not.

@PaulZC
Copy link
Collaborator

PaulZC commented Jul 13, 2021

Hi @JMyrng ,
I haven't tried this, but using UBX-NAV-ORB sounds like a sensible approach. The library does not currently support UBX-NAV-ORB directly and there is no data struct defined for it. However, you will be able to read the UBX-NAV-ORB data using a custom packet.
Please see Example21. Example21 uses a custom packet to read the version information from the module. You will need to create a custom packet with a payload size of at least 8 + (the maximum numSv's being tracked * 6) bytes. Set customCfg.cls = UBX_CLASS_NAV; . Set customCfg.id = UBX_NAV_ORB; .
You will need to manually parse the data yourself and - I guess - look at how many sv's have 'good' ephUsability?
Best wishes,
Paul

@JMyrng
Copy link
Author

JMyrng commented Jul 14, 2021

Hi @PaulZC ,
thanks for your great hint! I´ve followed that path and used this code:

#include <Arduino.h>

/*
  Module Info - extracts and prints the full module information from UBX_MON_VER
  using a custom command.
  By: @mayopan
  Date: May 9th, 2020
  Based on:
  Send Custom Command
  By: Paul Clark (PaulZC)
  Date: April 20th, 2020
  License: MIT. See license file for more information but you can
  basically do whatever you want with this code.
  Previously it was possible to create and send a custom packet
  through the library but it would always appear to timeout as
  some of the internal functions referred to the internal private
  struct packetCfg.
  The most recent version of the library allows sendCommand to
  use a custom packet as if it were packetCfg and so:
  - sendCommand will return a sfe_ublox_status_e enum as if
    it had been called from within the library
  - the custom packet will be updated with data returned by the module
    (previously this was not possible from outside the library)
  Feel like supporting open source hardware?
  Buy a board from SparkFun!
  ZED-F9P RTK2: https://www.sparkfun.com/products/15136
  NEO-M8P RTK: https://www.sparkfun.com/products/15005
  SAM-M8Q: https://www.sparkfun.com/products/15106
  Hardware Connections:
  Plug a Qwiic cable into the GNSS and a BlackBoard
  If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
  Open the serial monitor at 115200 baud to see the output
*/

#include <Wire.h> //Needed for I2C to GNSS

// 10 + 106 * 6 = 646
#define MAX_PAYLOAD_SIZE 646 // Override MAX_PAYLOAD_SIZE for getModuleInfo which can return up to 348 bytes

#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS

// Extend the class for getModuleInfo
class SFE_UBLOX_GPS_ADD : public SFE_UBLOX_GNSS
{
public:
    boolean getOrbitInfo(uint16_t maxWait = 1100); //Queries module, texts

    struct oinfoStructure // Structure to hold the module info (uses 341 bytes of RAM)
    {
        char timestamp[6];
        uint8_t numSv = 0;
        char satellites[106][6];
    } oinfo;
};

SFE_UBLOX_GPS_ADD myGNSS;

void setup()
{
    Serial.begin(115200); // You may need to increase this for high navigation rates!
    while (!Serial)
        ; //Wait for user to open terminal
    Serial.println(F("SparkFun u-blox Example"));

    Wire.begin();
    Wire.setClock(400000); //Increase I2C clock speed to 400kHz

    myGNSS.enableDebugging(); // Uncomment this line to enable debug messages

    if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port
    {
        Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
        while (1);
    }

    myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)

    Serial.println(F("Polling orbit info "));
    if (myGNSS.getOrbitInfo(2200) == false) // Try to get the module info
    {
        Serial.print(F("getOrbitInfo failed! Freezing..."));
        while (1);
    }

    Serial.println(F("getOrbitInfo successfull ..."));    
}

void loop()
{
}

boolean SFE_UBLOX_GPS_ADD::getOrbitInfo(uint16_t maxWait)
{
    // Let's create our custom packet
    uint8_t customPayload[MAX_PAYLOAD_SIZE]; // This array holds the payload data bytes

    // The next line creates and initialises the packet information which wraps around the payload
    ubxPacket customCfg = {0, 0, 0, 0, 0, customPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};

    // The structure of ubxPacket is:
    // uint8_t cls           : The message Class
    // uint8_t id            : The message ID
    // uint16_t len          : Length of the payload. Does not include cls, id, or checksum bytes
    // uint16_t counter      : Keeps track of number of overall bytes received. Some responses are larger than 255 bytes.
    // uint16_t startingSpot : The counter value needed to go past before we begin recording into payload array
    // uint8_t *payload      : The payload
    // uint8_t checksumA     : Given to us by the module. Checked against the rolling calculated A/B checksums.
    // uint8_t checksumB
    // sfe_ublox_packet_validity_e valid            : Goes from NOT_DEFINED to VALID or NOT_VALID when checksum is checked
    // sfe_ublox_packet_validity_e classAndIDmatch  : Goes from NOT_DEFINED to VALID or NOT_VALID when the Class and ID match the requestedClass and requestedID

    // sendCommand will return:
    // SFE_UBLOX_STATUS_DATA_RECEIVED if the data we requested was read / polled successfully
    // SFE_UBLOX_STATUS_DATA_SENT     if the data we sent was writted successfully (ACK'd)
    // Other values indicate errors. Please see the sfe_ublox_status_e enum for further details.

    // Referring to the u-blox M8 Receiver Description and Protocol Specification we see that
    // the module information can be read using the UBX-MON-VER message. So let's load our
    // custom packet with the correct information so we can read (poll / get) the module information.

    customCfg.cls = UBX_CLASS_NAV; // This is the message Class
    customCfg.id = UBX_NAV_ORB;    // This is the message ID
    customCfg.len = 0;             // Setting the len (length) to zero let's us poll the current settings
    customCfg.startingSpot = 0;    // Always set the startingSpot to zero (unless you really know what you are doing)

    // Now let's send the command. The module info is returned in customPayload

    if (sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED)
        return (false); //If command send fails then bail

    // Now let's extract the module info from customPayload

    return (true); //Success!
}

Running this leads me to this error with debugging enabled:

checkUbloxI2C: Large packet of 652 bytes received
processUBX: buffer overrun detected! activePacketBuffer: 0 maximum_payload_size: 256

The payload size is correct:

  • Header, Class, ID: 6 bytes
  • Payload: 8 + 106 * 6 bytes
  • Checksum: 2 bytes

How can I increase the maximum buffer size?

@JMyrng
Copy link
Author

JMyrng commented Jul 14, 2021

How can I increase the maximum buffer size?

Hope nobody has read my wall of text.

Inserting
myGNSS.setPacketCfgPayloadSize(768);
has solved my issue. But shouldn't that then also be in example 21?

And a big +1 for such a great debugging tool!!

@PaulZC
Copy link
Collaborator

PaulZC commented Jul 14, 2021

Hi @JMyrng ,
Glad that's working for you!
There is a 'weakness' in the code which I know about but haven't yet got around to fixing:

//If incomingUBX is a user-defined custom packet, then the payload size could be different to packetCfgPayloadSize.
//TO DO: update this to prevent an overrun when receiving an automatic message
// and the incomingUBX payload size is smaller than packetCfgPayloadSize.

The work-around is indeed to increase the packetCfg payload size to the same size as your custom packet. But this is wasteful in terms of RAM use because packetCfg is not actually being used, the incoming data is being written directly into the custom packet as it arrives.
Please leave this issue open - it is a good reminder for me to fix the weakness!
Very best wishes,
Paul

@PaulZC
Copy link
Collaborator

PaulZC commented Jul 14, 2021

Indeed, yes, Example21 will throw the same error if the module returns more than 256 bytes of version information.
Thanks!
Paul

@PaulZC
Copy link
Collaborator

PaulZC commented Aug 7, 2021

Corrected in v2.0.10 - #55

@PaulZC PaulZC linked a pull request Aug 7, 2021 that will close this issue
@PaulZC PaulZC closed this as completed in #55 Aug 7, 2021
@PaulZC PaulZC mentioned this issue Dec 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants