Skip to content

Commit 4b4ed43

Browse files
committed
Convert to polymorphic class
This enables virtual functions to be applied as instance overwrite instead of the weak references. Keep the weak references as backward compatibility. Signed-off-by: Alon Bar-Lev <[email protected]>
1 parent 8a33fb9 commit 4b4ed43

File tree

3 files changed

+190
-4
lines changed

3 files changed

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

Diff for: src/SparkFun_u-blox_GNSS_Arduino_Library.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -2288,13 +2288,18 @@ bool SFE_UBLOX_GNSS::processThisNMEA()
22882288
// This is the default or generic NMEA processor. We're only going to pipe the data to serial port so we can see it.
22892289
// User could overwrite this function to pipe characters to nmea.process(c) of tinyGPS or MicroNMEA
22902290
// Or user could pipe each character to a buffer, radio, etc.
2291-
void SFE_UBLOX_GNSS::processNMEA(char incoming)
2291+
void SFE_UBLOX_GNSS::processNMEA_v(char incoming)
22922292
{
22932293
// If user has assigned an output port then pipe the characters there
22942294
if (_nmeaOutputPort != NULL)
22952295
_nmeaOutputPort->write(incoming); // Echo this byte to the serial port
22962296
}
22972297

2298+
void SFE_UBLOX_GNSS::processNMEA(char incoming)
2299+
{
2300+
processNMEA_v(incoming);
2301+
}
2302+
22982303
#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA
22992304
// Check if the NMEA message (in nmeaAddressField) is "auto" (i.e. has RAM allocated for it)
23002305
bool SFE_UBLOX_GNSS::isThisNMEAauto()
@@ -2882,7 +2887,7 @@ nmeaAutomaticFlags *SFE_UBLOX_GNSS::getNMEAFlagsPtr()
28822887
// Byte 2: 10-bits of length of this packet including the first two-ish header bytes, + 6.
28832888
// byte 3 + 4 bits: Msg type 12 bits
28842889
// Example: D3 00 7C 43 F0 ... / 0x7C = 124+6 = 130 bytes in this packet, 0x43F = Msg type 1087
2885-
SFE_UBLOX_GNSS::sfe_ublox_sentence_types_e SFE_UBLOX_GNSS::processRTCMframe(uint8_t incoming, uint16_t *rtcmFrameCounter)
2890+
SFE_UBLOX_GNSS::sfe_ublox_sentence_types_e SFE_UBLOX_GNSS::processRTCMframe_v(uint8_t incoming, uint16_t *rtcmFrameCounter)
28862891
{
28872892
static uint16_t rtcmLen = 0;
28882893

@@ -2912,10 +2917,15 @@ SFE_UBLOX_GNSS::sfe_ublox_sentence_types_e SFE_UBLOX_GNSS::processRTCMframe(uint
29122917
return (*rtcmFrameCounter == rtcmLen) ? SFE_UBLOX_SENTENCE_TYPE_NONE : SFE_UBLOX_SENTENCE_TYPE_RTCM;
29132918
}
29142919

2920+
SFE_UBLOX_GNSS::sfe_ublox_sentence_types_e SFE_UBLOX_GNSS::processRTCMframe(uint8_t incoming, uint16_t *rtcmFrameCounter)
2921+
{
2922+
return processRTCMframe_v(incoming, rtcmFrameCounter);
2923+
}
2924+
29152925
// This function is called for each byte of an RTCM frame
29162926
// Ths user can overwrite this function and process the RTCM frame as they please
29172927
// Bytes can be piped to Serial or other interface. The consumer could be a radio or the internet (Ntrip broadcaster)
2918-
void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming)
2928+
void SFE_UBLOX_GNSS::processRTCM_v(uint8_t incoming)
29192929
{
29202930
// Radio.sendReliable((String)incoming); //An example of passing this byte to a radio
29212931

@@ -2930,6 +2940,11 @@ void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming)
29302940
(void)incoming; // Do something with incoming just to get rid of the pesky compiler warning!
29312941
}
29322942

2943+
void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming)
2944+
{
2945+
processRTCM_v(incoming);
2946+
}
2947+
29332948
// Given a character, file it away into the uxb packet structure
29342949
// Set valid to VALID or NOT_VALID once sentence is completely received and passes or fails CRC
29352950
// The payload portion of the packet can be 100s of bytes but the max array size is packetCfgPayloadSize bytes.

Diff for: src/SparkFun_u-blox_GNSS_Arduino_Library.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ class SFE_UBLOX_GNSS
660660
{
661661
public:
662662
SFE_UBLOX_GNSS(void);
663-
~SFE_UBLOX_GNSS(void);
663+
virtual ~SFE_UBLOX_GNSS(void);
664664

665665
// Depending on the sentence type the processor will load characters into different arrays
666666
enum sfe_ublox_sentence_types_e
@@ -764,8 +764,11 @@ class SFE_UBLOX_GNSS
764764

765765
void process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); // Processes NMEA and UBX binary sentences one byte at a time
766766
void processNMEA(char incoming) __attribute__((weak)); // Given a NMEA character, do something with it. User can overwrite if desired to use something like tinyGPS or MicroNMEA libraries
767+
virtual void processNMEA_v(char incoming); // Given a NMEA character, do something with it. User can overwrite if desired to use something like tinyGPS or MicroNMEA libraries
767768
sfe_ublox_sentence_types_e processRTCMframe(uint8_t incoming, uint16_t *rtcmFrameCounter) __attribute__((weak)); // Monitor the incoming bytes for start and length bytes
769+
virtual sfe_ublox_sentence_types_e processRTCMframe_v(uint8_t incoming, uint16_t *rtcmFrameCounter); // Monitor the incoming bytes for start and length bytes
768770
void processRTCM(uint8_t incoming) __attribute__((weak)); // Given rtcm byte, do something with it. User can overwrite if desired to pipe bytes to radio, internet, etc.
771+
virtual void processRTCM_v(uint8_t incoming); // Given rtcm byte, do something with it. User can overwrite if desired to pipe bytes to radio, internet, etc.
769772
void processUBX(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); // Given a character, file it away into the uxb packet structure
770773
void processUBXpacket(ubxPacket *msg); // Once a packet has been received and validated, identify this packet's class/id and update internal flags
771774

0 commit comments

Comments
 (0)