Both I and my friend have been working with the uBlox ZED-F9P GNSS devices.
We both have followed the code in: SparkFun_Ublox_Arduino_Library/examples/ZED-F9P/Example3_StartRTCMBase as a starting point.
In my friend’s case, he has followed the tutorial GPS-RTK2 Hookup Guide pretty slavishly, using a Redboard and the LCD. Because my goal has been to use LoRa to transmit correction data from a base instance to a rover instance, I have instead used the SparkFun Pro RF - LoRa, 915MHz (SAMD21), which has required minor changes to the example code, basically changing occurrences Serial.println() to SerialUSB.println(). I am viewing the output on Linux using minicom via the SerialUSB device on the PfoRF board.
Both my friend and I have arrived at the same point of frustration. In my case, I was able to (after many iterations) get an acceptable survey-in. I was using a uBlox dual frequency antenna with only fair view of the sky. But neither of us are seeing RTCM output in UBX mode (the mode used in the example).
Setting the output to NEMA produces tons of NEMA output. and using RTCM3 produces HEX output that I cannot understand. But the example, once surveyed in produces exactly the output in the attached capture, and will sit in this state for days. To whence are the RTCM Messages being sent?
Perhaps I should have posted this under SparkFun Products > Wireless > Global Positioning Systems (GPS). Somehow I just don’t think of GNSS/GPS sensing as a subset of ‘Wireless’.
That’s strange. You should be seeing both NMEA and the raw hex RTCM data over serial after running through that example and getting that “Base survey complete! RTCM now broadcasting.” printout. Are you sure you adjusted this loop to print over USB on the LoRa Pro RF:
//This function gets called from the SparkFun Ublox Arduino Library.
//As each RTCM byte comes in you can specify what to do with it
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
{
//Let's just pretty-print the HEX values for now
if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println();
Serial.print(" ");
if (incoming < 0x10) Serial.print("0");
Serial.print(incoming, HEX);
}
//--------------------------------------------------------------
// This function gets called from the SparkFun Ublox Arduino Library.
// As each RTCM byte comes in you can specify what to do with it
// Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
//--------------------------------------------------------------
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
{
// Let's just pretty-print the HEX values for now
if(oGNSS.rtcmFrameCounter % 16 == 0)
{
SerialUSB.println();
}
SerialUSB.print(" ");
if(incoming < 0x10)
{
SerialUSB.print("0");
}
SerialUSB.print(incoming, HEX);
}
I believe that the only differences are cosmetic.
If I change COM_TYPE_UBX to one of the other COM_TYPE specifiers (NEMA or RTCM3) I do get a deluge of stuff. But that is not what the example code says to do.
oGNSS.setI2COutput(COM_TYPE_UBX); // Set the I2C port to output UBX only (turn off NMEA noise)
// oGNSS.setI2COutput(COM_TYPE_NMEA);
// oGNSS.setI2COutput(COM_TYPE_RTCM3);
I believe that I may have to also use this line:
// This will pipe all NMEA sentences to the serial port so we can see them
oGNSS.setNMEAOutputPort(SerialUSB);
though it has no effect when used with COM_TYPE_UBX.
The tutorials mention that SparkFun has experimented with LoRa for this purpose. Is any of that code available?
It seems, for my purposes at least, the code in SparkFun_Ublox_Arduino_Library/examples/ZED-F9P/Example3_StartRTCMBase/Example3_StartRTCMBase.ino is not correct. After much agonizing and experimentation, it seems that the key issue is that once the survey-in is complete, the library does not automatically switch from COM_MODE_UBX to COM_MODE_RTCP3. By inserting the line:
oGNSS.setI2COutput(COM_TYPE_RTCM3);
at the bottom of the setup() function, I was able to make it work, sort of.
An additional confuser is the fact that the ‘pretty-printing’ function in the example is nonsense.
It appears that this function (just an example, I know) tries to use the occurrence of (myGPS.rtcmFrameCounter % 16 == 0) to print the output in rows. Unfortunately rtcmFrameCounter does not seem to count frames of any kind at all. Instead, it “Tracks the type of incoming byte inside RTCM frame”, according to the library .h file. I cannot see how this is useful in any way for formatting.
And by the way, someone needs to look at the code snippets on the tutorial: GPS-RTK Hookup Guide >Setting Up A Base Station. They use constants no longer found in the current library such as ‘UBX_RTCM_I2C_PORT’ (now seemingly COM_PORT_I2C). That is guaranteed to aggravate somebody.
I will attach my version of what I think the demo code was supposed to do. No guarantees, and remember that I am running this with a SparkFun Pro RF - LoRa, 915MHz (SAMD21) attached to a SparkFun GPS-RTK2 Board - ZED-F9P via a Qwiic interconnect and I am pushing the output to the SerialUSB port on the Pro RF.
Great catch here! I spoke with the engineer who wrote the library and designed our RTK GPS boards and he agrees there is an error here since the “myGPS.setI2COutput(COM_TYPE_UBX);” function turns off RTCM data. We will work on getting that issue fixed and pushing a new version of the library as soon as possible. We will also look into the issue with the “pretty printing” loop as well.
One quick note, the guide you are pointing to regarding the “UBX_RTCM_I2C_PORT” issue is for the NEO-M8P, not the ZED-F9P so the RTCM output messages are slightly different but the call to enable them should be the same for both modules. The code in that guide does match the [current example for the NEO-M8P but we are also going to clean that up and make it uniform for both modules.
As for a LoRa example, we do not currently have one available and there are some throughput limitations that we are looking into. This note in the Hookup Guide explains the issue a bit more thoroughly: “We’ve been experimenting with various LoRa solutions and the bandwidth needed for the best RTCM (~500 bytes per second) is right at the usable byte limit for many LoRa setups. It’s possible but you may need to adjust your LoRa settings to reach the throughput necessary for RTK.”
One quick note, the guide you are pointing to regarding the “UBX_RTCM_I2C_PORT” issue is for the NEO-M8P, not the ZED-F9P so the RTCM output messages are slightly different but the call to enable them should be the same for both modules. The code in that guide does match the current example for the NEO-M8P but we are also going to clean that up and make it uniform for both modules.
I was aware that this was the code for the NEO-M8P, but I compared a lot of stuff to find out what was going on and those constants no longer occur in the library, just on the "GPS-RTK Hookup Guide". They don't appear on the "GPS-RTK2 Hookup Guide".
So much to keep straight. But it is just the sort of thing that may mess someone up sooner or later.
As for a LoRa example, we do not currently have one available and there are some throughput limitations that we are looking into…
Thanks for checking. I suspect that a lot of people would be interested if you did.
I do understand the way LoRa trades off data rate for signal range. And the fact that the usable rate is bumping up against the limits of what is required for enhanced precision applications. That is why I have been really wanting to get to the point where we can test this in the field.
Additionally, as you pointed out (thank you!) the setI2COutput() was set to only UBX. I’ve added a myGPS.setI2COutput(COM_TYPE_UBX | COM_TYPE_RTCM3); to the end of setup(). This will enable UBX+RTCM+NMEA (I don’t want the NMEA but Ublox doesn’t offer just UBX+RTCM) and allow processRTCMframe to get called correctly once an RTCM incoming message is detected.