I have tested my sparkfun ZED-F9P fundamentals. I can, through U-Center on a PC, setting teh commands and successfully log RAWX and SBRFX data. Subsequently, I can convert using RTKCONV the .ubx to an .obs file and derive a solution throug TrimbleRTX. I am quite happy with the results.
I would like to log the same (just the RAWX and SBRFX data) to an SD card using an Arduino (e.g. MKR 1010). I would then post-process on a PC using OPUS, TrimbleRTX or RTKLIB. Using the Sparkfun library for the F9P how would I read these two data streams from I2C and direct to an SD card? Is there a C function to do so? (I could find no reference to either RAWX or SBRFX commands in the library.)
I don’t believe the library has functions for those data types. You’re probably going to need to either setup your own functions to do that or setup the GPS in U-Center to spit that data out on I2C (or serial and I2C) and then write those to a file on SD from an attached Arduino.
Thanks for the response. I might be missing something here. I can easily write data to the SD received from the objects and members currently in the library (e.g. the lat, long, altitude, etc.). However, the RAWX and SBRFX data are in hex. I don’t need to interpret them. I just need to take incoming record/string and write to the SD. It seems like there should be a class in the library that reprsents a incoming record/string. ???
This is something that I’m actively working on and I’m happy to share what I’ve learned.
First, I would highly recommend taking a look at the code in Paul Clark’s [F9P_RAWX_Logger and [ZED-F9P FeatherWing USB GitHub repositories. Paul’s [Ubx.md documentation in the F9P_RAWX_Logger repo is slightly outdated, but it gives you a good idea of how the code works, provides some insights to the problems with an insufficient size Serial buffer and how to go about solving this problem.
For my application, I’ve been working on a creating a ZED-F9P raw data logger specifically for use with Natural Resource Canada’s Precise Point Positioning (PPP) tool. I used Paul’s ZED-F9P FeatherWing USB code as a starting point but have greatly simplified it and also added an external RTC. My code is a work in progress, but you can find it on my GitHub here:
Also to note, Paul is a contributor to the SparkFun Ublox Arduino Library, who helped add functionality to allow for multiple UBX configuration messages (see ZED-F9P > Example10_multiSetVal).
Wow, thank you Adam! You and Paul have done a lot of work! I briefly looked at your sketch and the other two from Paul and this seems to be exactly (even more so) what I need. I will try later tonight and utilize.
On the related comment with Canada’s PPP, why not use the TrimbleRTX with the L1/L2 of the ZED-F9P? Its also free and would require much shorter static occupation times. Incidentally, I tried taking the log file (after converting with RTKCONV) from an Alpha L1 receiver this summer and uploading to Canada’s PPP and always received an error message. I was never successful and do not know if the logged data I sent was good or if Canada’s PPP is picky.
Glad to hear that the code will be helpful! If you have any questions, please feel free to ask. I’ve been neck deep in the u-blox ZED-F9P Interface Description for weeks now, and would be happy to assist.
Regarding NRCan’s PPP tool, it’s been a free tool I’ve used for a number of years now. I’m located in Canada and the geodetic engineers at NRCan are always willing to help with my questions. I wasn’t aware Trimble also had a free tool. Does it support both GPS and GLONASS?
A quick note that if you’d like to use NRCAN’s PPP tool to process data that’s been converted with RTKCONV, you’ll need to manually rename the GPS (G) signals from “C2L L2L D2L S2L” to “C2C L2C D2C S2C” in your RINEX 3.03 file. For whatever reason, the NRCan PPP tool doesn’t support the L modulation at the moment. I contact Tim about this and he advised that he also renames the signals when using their tool.
I’m curious, what is your application for the logger?
Thank you again. You are way ahead of me. I can use some help as I am trying to get away from using my old and soon to be deprecated Topcon GRS-1. Thus, the rationale for a ZED-F9P approach. I use both GNSS-supported and total station supported collections in the field. Mostly for either validation of remote sensing data streams in my research (e.g. LiDAR) or ground control for drone-based aerial mapping collections. For now, I really only need 1) static GNSS occupations for total station control when collecting in complicated environments where GNSS is not productive and 2) RTK GNSS for open areas.
I am in the USA for most of the year but Europe for several months so I have two different continents with solutions. My experience with OPUS is good if the environment is free of obstrucdtions (in the US) but TrimbleRTX will provide solutions in more problematic environs… where I only need accuracies of 3 to 5cm (not 1-2). Here is the location for Trimbles RTX (free after a 60’ delay in collection): https://www.trimblertx.com/ Yes, they support all constellations now.
Thank you for the notice of the new RTKLIB version. I was not aware. I was using a version I downloaded this summer… I will update.
And thank you for the note about the NRCAN PPP tool.
I looked at your code and Paul’s code. Let me say I have programmed in C and C++ but am rusty. So, interpreting the large set of code is a bit daunting at the moment. I like the way you set up the flow control with the case statements. Very modular.
The big challenge for me is the magnitude of code. I am currently working with an Arduino MKR 1010 (although I have a mega and due also when I was testing TFTs), and a Sparkfun MicroSD. I was hoping to use the MKR for the master and control the writing to the SD. The MKR would also provide wifi and BLE capabilities to download the data without removing the SD card each time. The code you and Paul assembled seems to be written for the Feather MO datalogger. Without attempting some modifications would you suggest I procure a Feather datalogger as the master?
I did try compiling the codes after obtaining the relevant libraries and ran into the error message the A7 was not declared … seems the MKR board only has a range from 0 to A6.
// Read battery voltage voltage = analogRead(A7) * (2.0 * 3.3 / 1023.0);
I definitely understand how daunting the code can be at first glance. It took me some time to make my way through all of Paul’s code, which is almost 2000 lines. I agree that having the switch statements do help to compartmentalize things somewhat.
I don’t envision there being any issues with using an Arduino MKR 1010 and a SparkFun SD breakout, especially since the MKR 1010 is also based on the SAMD21 Cortex M0. I’ve had a similar setup working without issue (Adafruit M0 Express + SparkFun microSD breakout). I also noticed the MKR 1010 has a NeoPixel onboard, which is handy for visual indicators. l plan to add this functionality to my code at a later point.
Regarding the code below, this is a battery voltage divider specifically for the Adalogger M0. They’ve tied the resistor divider to A7, which requires the Adafruit board definitions to be used.
// Read battery voltage
voltage = analogRead(A7) * (2.0 * 3.3 / 1023.0);
The MKR 1010 also has a 1MΩ/300 kΩ voltage divider onboard, which looks to be directly accessible using ADC_BATTERY. You’ll have to confirm the code, but I think it looks as so:
int sensorValue = analogRead(ADC_BATTERY);
float voltage = sensorValue * (4.3 / 1023.0);
I’d suggest replacing the battery voltage code with what’s above and removing all references to A7.
I have developed a phone-based interface to control the Arduino-based ZED-F9P through BLE but not tested with your code just yet. I am happy to share app with you. I used MIT App Inventor as I needed to wifi is often unavailable in the field. (Blynk would have been easier I think). Once I sort out the RTC I can test.
I also tested again (using a laptop connected to ZED-F9P) a 20 minute static occupation compared to a CHC X900S GNSS; using OPUS post-processing. The X900S has a calibrated ground-plane antenna. I used a Topcon PG-A1 antenna with the ZED-F9P. The reported positions from both units are with 1-cm of each other in all three dimensions (X-Y-Z). The sigmas were also between 1 and 3-cm for both units in each dimension.
your code makes use a a separate RTC (i.e. a Feather board). Paul’s code refers to an RTC but he does not list one in the comments. I am not sure why a separate RTC is needed rather than using the time-stamp from the ZED-F9P board. Can you help?
Very interesting to hear about your cellular-based interface. I’d been keen to learn more! Also, thanks for sharing the results you were able to obtain. Does the Topcon antenna support all of the frequencies of the ZED-F9P? Those are some pretty good numbers for only a 20-minute occupation.
Regarding the use of real-time clocks (RTCs), Paul’s code utilizes the internal RTC of the Atmel SAMD21. While handy, it has no temperature compensation and is wildly inaccurate when exposed to temperature swings. Because my research is conducted in the Canadian Arctic, I use the Maxim DS3231SN (industrial rated) RTC, which has a drift of ~3 ppm over a temperature range of -40 to +85°C.
The PG-A1 antennae I have includes a ground plane and supports L1 and L2. I honestly do not know if it supports L5 (not listed in the documentation and I didn’t try to log L5 data.) Its a good question I will check on. With the PG-A1 antennae I can receive L1/L2 signals from GLONASS, GPS, Galileo, and Beidou.
Regarding the similarity in X-Y-Z values from the two receivers. I collected data on Saturday morning using the X900S and data with the ZED-F9P on Sunday afternoon. So, the constellation of sats were different and I expected some differences (greater than 1cm) in the results. I wouldn’t necessarily associate the similarity results with 1-cm accuracies. The state geodetic survey agency established the monument on top of the parking garage where I collected the data; I will obtain their data and compare for a more reliable estimation of accuracy. Still the similarties in results with different configuration of satellites is quite good. My own experience with many uses of the X900S demonstrates it produces repetitive results at the same location within about 2-cm and 20 to 30-min occupations. We likely have many more base stations (i.e. shorter baselines) where I am in South Carolina than in the Arctic.
Which brings me to the Arctic. I understand now the need for the RTC/temperature sensor. Your Maxim sensor sensor is incredibly precise. Are you flying a drone in the Arctic?