|  | 
|  | 1 | +/* | 
|  | 2 | + Send UBX binary commands to enable RTCM sentences on Ublox ZED-F9P module | 
|  | 3 | + By: Nathan Seidle | 
|  | 4 | + SparkFun Electronics | 
|  | 5 | + Date: January 9th, 2019 | 
|  | 6 | + License: MIT. See license file for more information but you can | 
|  | 7 | + basically do whatever you want with this code. | 
|  | 8 | +
 | 
|  | 9 | + This example does all steps to configure and enable a ZED-F9P as a base station: | 
|  | 10 | + Begin Survey-In | 
|  | 11 | + Once we've achieved 2m accuracy and 300s have passed, survey is complete | 
|  | 12 | + Enable six RTCM messages | 
|  | 13 | + Begin outputting RTCM bytes | 
|  | 14 | +
 | 
|  | 15 | + Feel like supporting open source hardware? | 
|  | 16 | + Buy a board from SparkFun! | 
|  | 17 | + ZED-F9P RTK2: https://www.sparkfun.com/products/15136 | 
|  | 18 | + NEO-M8P RTK: https://www.sparkfun.com/products/15005 | 
|  | 19 | + SAM-M8Q: https://www.sparkfun.com/products/15106 | 
|  | 20 | +
 | 
|  | 21 | + Hardware Connections: | 
|  | 22 | + Plug a Qwiic cable into the GPS and a BlackBoard | 
|  | 23 | + If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425) | 
|  | 24 | + Open the serial monitor at 115200 baud to see the output | 
|  | 25 | +*/ | 
|  | 26 | + | 
|  | 27 | +#include <Wire.h> //Needed for I2C to GPS | 
|  | 28 | + | 
|  | 29 | +#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS | 
|  | 30 | +SFE_UBLOX_GPS myGPS; | 
|  | 31 | + | 
|  | 32 | +void setup() | 
|  | 33 | +{ | 
|  | 34 | + Serial.begin(115200); | 
|  | 35 | + while (!Serial); //Wait for user to open terminal | 
|  | 36 | + Serial.println("Ublox NEO-M8P-2 base station example"); | 
|  | 37 | + | 
|  | 38 | + Wire.begin(); | 
|  | 39 | + Wire.setClock(400000); //Increase I2C clock speed to 400kHz | 
|  | 40 | + | 
|  | 41 | + if (myGPS.begin() == false) //Connect to the Ublox module using Wire port | 
|  | 42 | + { | 
|  | 43 | + Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing.")); | 
|  | 44 | + while (1); | 
|  | 45 | + } | 
|  | 46 | + | 
|  | 47 | + myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise) | 
|  | 48 | + myGPS.saveConfiguration(); //Save the current settings to flash and BBR | 
|  | 49 | + | 
|  | 50 | + while (Serial.available()) Serial.read(); //Clear any latent chars in serial buffer | 
|  | 51 | + Serial.println("Press any key to send commands to begin Survey-In"); | 
|  | 52 | + while (Serial.available() == 0) ; //Wait for user to press a key | 
|  | 53 | + | 
|  | 54 | + boolean response = true; | 
|  | 55 | + response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second | 
|  | 56 | + response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_I2C, 1); | 
|  | 57 | + response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_I2C, 1); | 
|  | 58 | + response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_I2C, 1); | 
|  | 59 | + response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_I2C, 1); | 
|  | 60 | + response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds | 
|  | 61 | + | 
|  | 62 | + if (response == true) | 
|  | 63 | + { | 
|  | 64 | + Serial.println("RTCM messages enabled"); | 
|  | 65 | + } | 
|  | 66 | + else | 
|  | 67 | + { | 
|  | 68 | + Serial.println("RTCM failed to enable. Are you sure you have an NEO-M8P?"); | 
|  | 69 | + while (1); //Freeze | 
|  | 70 | + } | 
|  | 71 | + | 
|  | 72 | + //Check if Survey is in Progress before initiating one | 
|  | 73 | + response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (request can take a long time) | 
|  | 74 | + if (response == false) | 
|  | 75 | + { | 
|  | 76 | + Serial.println("Failed to get Survey In status"); | 
|  | 77 | + while (1); //Freeze | 
|  | 78 | + } | 
|  | 79 | + | 
|  | 80 | + if (myGPS.svin.active == true) | 
|  | 81 | + { | 
|  | 82 | + Serial.print("Survey already in progress."); | 
|  | 83 | + } | 
|  | 84 | + else | 
|  | 85 | + { | 
|  | 86 | + //Start survey | 
|  | 87 | + //The ZED-F9P is slightly different than the NEO-M8P. See the Integration manual 3.5.8 for more info. | 
|  | 88 | + //response = myGPS.enableSurveyMode(300, 2.000); //Enable Survey in on NEO-M8P, 300 seconds, 2.0m | 
|  | 89 | + response = myGPS.enableSurveyMode(60, 5.000); //Enable Survey in, 60 seconds, 5.0m | 
|  | 90 | + if (response == false) | 
|  | 91 | + { | 
|  | 92 | + Serial.println("Survey start failed"); | 
|  | 93 | + while (1); | 
|  | 94 | + } | 
|  | 95 | + Serial.println("Survey started. This will run until 60s has passed and less than 5m accuracy is achieved."); | 
|  | 96 | + } | 
|  | 97 | + | 
|  | 98 | + while(Serial.available()) Serial.read(); //Clear buffer | 
|  | 99 | +  | 
|  | 100 | + //Begin waiting for survey to complete | 
|  | 101 | + while (myGPS.svin.valid == false) | 
|  | 102 | + { | 
|  | 103 | + if(Serial.available()) | 
|  | 104 | + { | 
|  | 105 | + byte incoming = Serial.read(); | 
|  | 106 | + if(incoming == 'x') | 
|  | 107 | + { | 
|  | 108 | + //Stop survey mode | 
|  | 109 | + response = myGPS.disableSurveyMode(); //Disable survey | 
|  | 110 | + Serial.println("Survey stopped"); | 
|  | 111 | + break; | 
|  | 112 | + } | 
|  | 113 | + } | 
|  | 114 | +  | 
|  | 115 | + response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (req can take a long time) | 
|  | 116 | + if (response == true) | 
|  | 117 | + { | 
|  | 118 | + Serial.print("Press x to end survey - "); | 
|  | 119 | + Serial.print("Time elapsed: "); | 
|  | 120 | + Serial.print((String)myGPS.svin.observationTime); | 
|  | 121 | + | 
|  | 122 | + Serial.print(" Accuracy: "); | 
|  | 123 | + Serial.print((String)myGPS.svin.meanAccuracy); | 
|  | 124 | + Serial.println(); | 
|  | 125 | + } | 
|  | 126 | + else | 
|  | 127 | + { | 
|  | 128 | + Serial.println("SVIN request failed"); | 
|  | 129 | + } | 
|  | 130 | + | 
|  | 131 | + delay(1000); | 
|  | 132 | + } | 
|  | 133 | + Serial.println("Survey valid!"); | 
|  | 134 | + | 
|  | 135 | + Serial.println("Base survey complete! RTCM now broadcasting."); | 
|  | 136 | +} | 
|  | 137 | + | 
|  | 138 | +void loop() | 
|  | 139 | +{ | 
|  | 140 | + myGPS.checkUblox(); //See if new data is available. Process bytes as they come in. | 
|  | 141 | + | 
|  | 142 | + delay(250); //Don't pound too hard on the I2C bus | 
|  | 143 | +} | 
|  | 144 | + | 
|  | 145 | +//This function gets called from the SparkFun Ublox Arduino Library. | 
|  | 146 | +//As each RTCM byte comes in you can specify what to do with it | 
|  | 147 | +//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc. | 
|  | 148 | +void SFE_UBLOX_GPS::processRTCM(uint8_t incoming) | 
|  | 149 | +{ | 
|  | 150 | + //Let's just pretty-print the HEX values for now | 
|  | 151 | + if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println(); | 
|  | 152 | + Serial.print(" "); | 
|  | 153 | + if (incoming < 0x10) Serial.print("0"); | 
|  | 154 | + Serial.print(incoming, HEX); | 
|  | 155 | +} | 
0 commit comments