Skip to content

Commit 12291f8

Browse files
authored
Merge pull request #456 from sparkfun/release_candidate
Merge v3.3 changes
2 parents 68e602e + 5074c60 commit 12291f8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+16341
-12344
lines changed

Firmware/RTK_Surveyor/AP-Config/index.html

Lines changed: 365 additions & 555 deletions
Large diffs are not rendered by default.

Firmware/RTK_Surveyor/AP-Config/src/main.js

Lines changed: 539 additions & 219 deletions
Large diffs are not rendered by default.
5.67 KB
Loading
183 Bytes
Loading

Firmware/RTK_Surveyor/Base.ino

Lines changed: 154 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -14,113 +14,116 @@ bool configureUbloxModuleBase()
1414
firstPowerOn = false; //If we switch between rover/base in the future, force config of module.
1515

1616
theGNSS.checkUblox(); //Regularly poll to get latest data and any RTCM
17+
theGNSS.checkCallbacks(); //Process any callbacks: ie, storePVTdata
1718

1819
theGNSS.setNMEAGPGGAcallbackPtr(nullptr); //Disable GPGGA call back that may have been set during Rover NTRIP Client mode
1920

20-
bool response = true;
21+
bool success = false;
22+
int tryNo = -1;
2123

22-
//In Base mode we force 1Hz
23-
response &= theGNSS.newCfgValset();
24-
response &= theGNSS.addCfgValset(UBLOX_CFG_RATE_MEAS, 1000);
25-
response &= theGNSS.addCfgValset(UBLOX_CFG_RATE_NAV, 1);
26-
27-
//Since we are at 1Hz, allow GSV NMEA to be reported at whatever the user has chosen
28-
response &= theGNSS.addCfgValset(settings.ubxMessages[8].msgConfigKey, settings.ubxMessages[8].msgRate); //Update rate on module
29-
30-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_NMEA_ID_GGA_I2C, 0); //Disable NMEA message that may have been set during Rover NTRIP Client mode
31-
32-
//Survey mode is only available on ZED-F9P modules
33-
if (zedModuleType == PLATFORM_F9P)
34-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_MODE, 0); //Disable survey-in mode
35-
36-
response &= theGNSS.addCfgValset(UBLOX_CFG_NAVSPG_DYNMODEL, (dynModel)settings.dynamicModel); //Set dynamic model
37-
38-
//RTCM is only available on ZED-F9P modules
39-
//
40-
//For most RTK products, the GNSS is interfaced via both I2C and UART1. Configuration and PVT/HPPOS messages are
41-
//configured over I2C. Any messages that need to be logged are output on UART1, and received by this code using
42-
//serialGNSS.
43-
//In base mode the RTK device should output RTCM over all ports:
44-
//(Primary) UART2 in case the Surveyor is connected via radio to rover
45-
//(Optional) I2C in case user wants base to connect to WiFi and NTRIP Caster
46-
//(Seconday) USB in case the Surveyor is used as an NTRIP caster connected to SBC or other
47-
//(Tertiary) UART1 in case Surveyor is sending RTCM to phone that is then NTRIP Caster
48-
//
49-
//But, on the Reference Station, the GNSS is interfaced via SPI. It has no access to I2C and UART1.
50-
//We use the GNSS library's built-in logging buffer to mimic UART1. The code in Tasks.ino reads
51-
//data from the logging buffer as if it had come from UART1.
52-
//So for that product - in Base mode - we can only output RTCM on SPI, USB and UART2.
53-
//If we want to log the RTCM messages, we need to add them to the logging buffer inside the GNSS library.
54-
//If we want to pass them along to (e.g.) radio, we do that using processRTCM (defined below).
55-
56-
if (USE_I2C_GNSS)
57-
{
58-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_I2C, 1);
59-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_I2C, 1);
60-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_I2C, 1);
61-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_I2C, 1);
62-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_I2C, 1);
63-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_I2C, 10); //Enable message every 10 cycles - note: this may conflict with settings and setMessages?
64-
65-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_UART1, 1);
66-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_UART1, 1);
67-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_UART1, 1);
68-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_UART1, 1);
69-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_UART1, 1);
70-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_UART1, 10);
71-
}
72-
else //SPI GNSS
24+
//Try up to MAX_SET_MESSAGES_RETRIES times to configure the GNSS
25+
//This corrects occasional failures seen on the Reference Station where the GNSS is connected via SPI
26+
//instead of I2C and UART1. I believe the SETVAL ACK is occasionally missed due to the level of messages being processed.
27+
while ((++tryNo < MAX_SET_MESSAGES_RETRIES) && !success)
7328
{
74-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_SPI, 1);
75-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_SPI, 1);
76-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_SPI, 1);
77-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_SPI, 1);
78-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_SPI, 1);
79-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_SPI, 10); //Enable message every 10 cycles - note: this may conflict with settings and setMessages?
80-
81-
//Enable logging of these messages so the RTCM will be stored automatically in the logging buffer.
82-
//This mimics the data arriving via UART1.
83-
uint32_t logRTCMMessages = theGNSS.getRTCMLoggingMask();
84-
logRTCMMessages |= ( SFE_UBLOX_FILTER_RTCM_TYPE1005 | SFE_UBLOX_FILTER_RTCM_TYPE1074 | SFE_UBLOX_FILTER_RTCM_TYPE1084
85-
| SFE_UBLOX_FILTER_RTCM_TYPE1094 | SFE_UBLOX_FILTER_RTCM_TYPE1124 | SFE_UBLOX_FILTER_RTCM_TYPE1230 );
86-
theGNSS.setRTCMLoggingMask(logRTCMMessages);
87-
log_d("setRTCMLoggingMask 0x%X", logRTCMMessages);
88-
89-
//Update settings, otherwise setMessages could disable these again...
90-
for (int x = 0; x < MAX_UBX_MSG; x++)
29+
bool response = true;
30+
31+
//In Base mode we force 1Hz
32+
response &= theGNSS.newCfgValset();
33+
response &= theGNSS.addCfgValset(UBLOX_CFG_RATE_MEAS, 1000);
34+
response &= theGNSS.addCfgValset(UBLOX_CFG_RATE_NAV, 1);
35+
36+
//Since we are at 1Hz, allow GSV NMEA to be reported at whatever the user has chosen
37+
uint32_t spiOffset = 0; //Set to 3 if using SPI to convert UART1 keys to SPI. This is brittle and non-perfect, but works.
38+
if (USE_SPI_GNSS)
39+
spiOffset = 3;
40+
response &= theGNSS.addCfgValset(ubxMessages[8].msgConfigKey + spiOffset, settings.ubxMessageRates[8]); //Update rate on module
41+
42+
if (USE_I2C_GNSS)
43+
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_NMEA_ID_GGA_I2C, 0); //Disable NMEA message that may have been set during Rover NTRIP Client mode
44+
45+
//Survey mode is only available on ZED-F9P modules
46+
if (commandSupported(UBLOX_CFG_TMODE_MODE) == true)
47+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_MODE, 0); //Disable survey-in mode
48+
49+
//Note that using UBX-CFG-TMODE3 to set the receiver mode to Survey In or to Fixed Mode, will set
50+
//automatically the dynamic platform model (CFG-NAVSPG-DYNMODEL) to Stationary.
51+
//response &= theGNSS.addCfgValset(UBLOX_CFG_NAVSPG_DYNMODEL, (dynModel)settings.dynamicModel); //Not needed
52+
53+
//RTCM is only available on ZED-F9P modules
54+
//
55+
//For most RTK products, the GNSS is interfaced via both I2C and UART1. Configuration and PVT/HPPOS messages are
56+
//configured over I2C. Any messages that need to be logged are output on UART1, and received by this code using
57+
//serialGNSS.
58+
//In base mode the RTK device should output RTCM over all ports:
59+
//(Primary) UART2 in case the Surveyor is connected via radio to rover
60+
//(Optional) I2C in case user wants base to connect to WiFi and NTRIP Caster
61+
//(Seconday) USB in case the Surveyor is used as an NTRIP caster connected to SBC or other
62+
//(Tertiary) UART1 in case Surveyor is sending RTCM to phone that is then NTRIP Caster
63+
//
64+
//But, on the Reference Station, the GNSS is interfaced via SPI. It has no access to I2C and UART1.
65+
//We use the GNSS library's built-in logging buffer to mimic UART1. The code in Tasks.ino reads
66+
//data from the logging buffer as if it had come from UART1.
67+
//So for that product - in Base mode - we can only output RTCM on SPI, USB and UART2.
68+
//If we want to log the RTCM messages, we need to add them to the logging buffer inside the GNSS library.
69+
//If we want to pass them along to (e.g.) radio, we do that using processRTCM (defined below).
70+
71+
//Find first RTCM record in ubxMessage array
72+
int firstRTCMRecord = getMessageNumberByName("UBX_RTCM_1005");
73+
74+
//ubxMessageRatesBase is an array of ~12 uint8_ts
75+
//ubxMessage is an array of ~80 messages
76+
//We use firstRTCMRecord as an offset for the keys, but use x as the rate
77+
78+
if (USE_I2C_GNSS)
9179
{
92-
if (settings.ubxMessages[x].msgClass == UBX_RTCM_MSB) //RTCM messages
80+
for (int x = 0; x < MAX_UBX_MSG_RTCM; x++)
9381
{
94-
if (settings.ubxMessages[x].filterMask & //This is quicker than checking the msgID
95-
( SFE_UBLOX_FILTER_RTCM_TYPE1005 | SFE_UBLOX_FILTER_RTCM_TYPE1074 | SFE_UBLOX_FILTER_RTCM_TYPE1084
96-
| SFE_UBLOX_FILTER_RTCM_TYPE1094 | SFE_UBLOX_FILTER_RTCM_TYPE1124))
97-
settings.ubxMessages[x].msgRate = 1;
98-
if (settings.ubxMessages[x].filterMask & SFE_UBLOX_FILTER_RTCM_TYPE1230)
99-
settings.ubxMessages[x].msgRate = 10;
82+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey - 1, settings.ubxMessageRatesBase[x]); //UBLOX_CFG UART1 - 1 = I2C
83+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey, settings.ubxMessageRatesBase[x]); //UBLOX_CFG UART1
84+
85+
//Disable messages on SPI
86+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey + 3, 0); //UBLOX_CFG UART1 + 3 = SPI
10087
}
10188
}
102-
}
89+
else //SPI GNSS
90+
{
91+
for (int x = 0; x < MAX_UBX_MSG_RTCM; x++)
92+
{
93+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey + 3, settings.ubxMessageRatesBase[x]); //UBLOX_CFG UART1 + 3 = SPI
10394

104-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_USB, 1);
105-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_USB, 1);
106-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_USB, 1);
107-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_USB, 1);
108-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_USB, 1);
109-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_USB, 10);
95+
//Disable messages on I2C and UART1
96+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey - 1, 0); //UBLOX_CFG UART1 - 1 = I2C
97+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey, 0); //UBLOX_CFG UART1
98+
}
11099

111-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_UART2, 1);
112-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_UART2, 1);
113-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_UART2, 1);
114-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_UART2, 1);
115-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_UART2, 1);
116-
response &= theGNSS.addCfgValset(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_UART2, 10);
100+
//Enable logging of these messages so the RTCM will be stored automatically in the logging buffer.
101+
//This mimics the data arriving via UART1.
102+
uint32_t logRTCMMessages = theGNSS.getRTCMLoggingMask();
103+
logRTCMMessages |= ( SFE_UBLOX_FILTER_RTCM_TYPE1005 | SFE_UBLOX_FILTER_RTCM_TYPE1074 | SFE_UBLOX_FILTER_RTCM_TYPE1084
104+
| SFE_UBLOX_FILTER_RTCM_TYPE1094 | SFE_UBLOX_FILTER_RTCM_TYPE1124 | SFE_UBLOX_FILTER_RTCM_TYPE1230 );
105+
theGNSS.setRTCMLoggingMask(logRTCMMessages);
106+
}
117107

118-
response &= theGNSS.sendCfgValset(); //Closing value - #31
108+
//Update message rates for UART2 and USB
109+
for (int x = 0; x < MAX_UBX_MSG_RTCM; x++)
110+
{
111+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey + 1 , settings.ubxMessageRatesBase[x]); //UBLOX_CFG UART1 + 1 = UART2
112+
response &= theGNSS.addCfgValset(ubxMessages[firstRTCMRecord + x].msgConfigKey + 2 , settings.ubxMessageRatesBase[x]); //UBLOX_CFG UART1 + 2 = USB
113+
}
119114

120-
if (response == false)
115+
response &= theGNSS.addCfgValset(UBLOX_CFG_NAVSPG_INFIL_MINELEV, settings.minElev); //Set minimum elevation
116+
117+
response &= theGNSS.sendCfgValset(); //Closing value
118+
119+
if (response)
120+
success = true;
121+
}
122+
123+
if (!success)
121124
systemPrintln("Base config fail");
122125

123-
return (response);
126+
return (success);
124127
}
125128

126129
//Start survey
@@ -140,9 +143,15 @@ bool surveyInStart()
140143

141144
if (surveyInReset() == false)
142145
{
143-
systemPrintln("Survey reset failed");
146+
systemPrintln("Survey reset failed - attempt 1/3");
144147
if (surveyInReset() == false)
145-
systemPrintln("Survey reset failed - 2nd attempt");
148+
{
149+
systemPrintln("Survey reset failed - attempt 2/3");
150+
if (surveyInReset() == false)
151+
{
152+
systemPrintln("Survey reset failed - attempt 3/3");
153+
}
154+
}
146155
}
147156
}
148157

@@ -158,9 +167,9 @@ bool surveyInStart()
158167
}
159168

160169
systemPrintf("Survey started. This will run until %d seconds have passed and less than %0.03f meter accuracy is achieved.\r\n",
161-
settings.observationSeconds,
162-
settings.observationPositionAccuracy
163-
);
170+
settings.observationSeconds,
171+
settings.observationPositionAccuracy
172+
);
164173

165174
//Wait until active becomes true
166175
long maxTime = 5000;
@@ -291,6 +300,13 @@ bool startFixedBase()
291300
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
292301
void DevUBLOXGNSS::processRTCM(uint8_t incoming)
293302
{
303+
//We need to prevent ntripServerProcessRTCM from writing data via Ethernet (SPI W5500)
304+
//during an SPI checkUbloxSpi...
305+
//We can pass incoming to ntripServerProcessRTCM if the GNSS is I2C or the variant does not have Ethernet.
306+
//For the Ref Stn, processRTCMBuffer is called manually from inside ntripServerUpdate
307+
if ((USE_SPI_GNSS) && (HAS_ETHERNET))
308+
return;
309+
294310
//Check for too many digits
295311
if (settings.enableResetDisplay == true)
296312
{
@@ -318,3 +334,44 @@ void DevUBLOXGNSS::processRTCM(uint8_t incoming)
318334
espnowProcessRTCM(incoming);
319335
}
320336
}
337+
338+
//For Ref Stn (USE_SPI_GNSS and HAS_ETHERNET), call ntripServerProcessRTCM manually if there is RTCM data in the buffer
339+
void processRTCMBuffer()
340+
{
341+
if ((USE_I2C_GNSS) || (!HAS_ETHERNET))
342+
return;
343+
344+
//Check if there is any data waiting in the RTCM buffer
345+
uint16_t rtcmBytesAvail = theGNSS.rtcmBufferAvailable();
346+
if (rtcmBytesAvail > 0)
347+
{
348+
//Check for too many digits
349+
if (settings.enableResetDisplay == true)
350+
{
351+
if (rtcmPacketsSent > 99) rtcmPacketsSent = 1; //Trim to two digits to avoid overlap
352+
}
353+
else
354+
{
355+
if (rtcmPacketsSent > 999) rtcmPacketsSent = 1; //Trim to three digits to avoid log icon and increasing bar
356+
}
357+
358+
while (rtcmBytesAvail > 0)
359+
{
360+
uint8_t incoming;
361+
362+
if (theGNSS.extractRTCMBufferData(&incoming, 1) != 1)
363+
return;
364+
365+
rtcmBytesAvail--;
366+
367+
//Data in the u-blox library RTCM buffer is pre-checked. We don't need to check it again here.
368+
369+
rtcmLastReceived = millis();
370+
rtcmBytesSent++;
371+
372+
ntripServerProcessRTCM(incoming);
373+
374+
espnowProcessRTCM(incoming);
375+
}
376+
}
377+
}

0 commit comments

Comments
 (0)