Skip to content

Commit ef0bac1

Browse files
authored
Merge pull request #777 from sparkfun/release_candidate
Add support for multiple NTRIP Servers
2 parents 7e8fd85 + 40607b9 commit ef0bac1

28 files changed

+3520
-2459
lines changed

.github/workflows/compile-rtk-firmware.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
env:
77
FILENAME_PREFIX: RTK_Surveyor_Firmware
88
FIRMWARE_VERSION_MAJOR: 4
9-
FIRMWARE_VERSION_MINOR: 0
9+
FIRMWARE_VERSION_MINOR: 1
1010
POINTPERFECT_TOKEN: ${{ secrets.POINTPERFECT_TOKEN }}
1111

1212
jobs:

Firmware/RTK_Surveyor/AP-Config/index.html

Lines changed: 158 additions & 94 deletions
Large diffs are not rendered by default.

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

Lines changed: 141 additions & 95 deletions
Large diffs are not rendered by default.

Firmware/RTK_Surveyor/Base.ino

Lines changed: 88 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -239,76 +239,92 @@ bool surveyInReset()
239239
bool startFixedBase()
240240
{
241241
bool response = true;
242+
int retries = 0;
243+
uint16_t maxWait = 1100;
242244

243-
if (settings.fixedBaseCoordinateType == COORD_TYPE_ECEF)
244-
{
245-
// Break ECEF into main and high precision parts
246-
// The type casting should not effect rounding of original double cast coordinate
247-
long majorEcefX = floor((settings.fixedEcefX * 100.0) + 0.5);
248-
long minorEcefX = floor((((settings.fixedEcefX * 100.0) - majorEcefX) * 100.0) + 0.5);
249-
long majorEcefY = floor((settings.fixedEcefY * 100) + 0.5);
250-
long minorEcefY = floor((((settings.fixedEcefY * 100.0) - majorEcefY) * 100.0) + 0.5);
251-
long majorEcefZ = floor((settings.fixedEcefZ * 100) + 0.5);
252-
long minorEcefZ = floor((((settings.fixedEcefZ * 100.0) - majorEcefZ) * 100.0) + 0.5);
253-
254-
// systemPrintf("fixedEcefY (should be -4716808.5807): %0.04f\r\n", settings.fixedEcefY);
255-
// systemPrintf("major (should be -471680858): %ld\r\n", majorEcefY);
256-
// systemPrintf("minor (should be -7): %ld\r\n", minorEcefY);
257-
258-
// Units are cm with a high precision extension so -1234.5678 should be called: (-123456, -78)
259-
//-1280208.308,-4716803.847,4086665.811 is SparkFun HQ so...
260-
261-
response &= theGNSS.newCfgValset();
262-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_MODE, 2); // Fixed
263-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_POS_TYPE, 0); // Position in ECEF
264-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_X, majorEcefX);
265-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_X_HP, minorEcefX);
266-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Y, majorEcefY);
267-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Y_HP, minorEcefY);
268-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Z, majorEcefZ);
269-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Z_HP, minorEcefZ);
270-
response &= theGNSS.sendCfgValset();
271-
}
272-
else if (settings.fixedBaseCoordinateType == COORD_TYPE_GEODETIC)
273-
{
274-
// Add height of instrument (HI) to fixed altitude
275-
// https://www.e-education.psu.edu/geog862/node/1853
276-
// For example, if HAE is at 100.0m, + 2m stick + 73mm ARP = 102.073
277-
float totalFixedAltitude =
278-
settings.fixedAltitude + (settings.antennaHeight / 1000.0) + (settings.antennaReferencePoint / 1000.0);
279-
280-
// Break coordinates into main and high precision parts
281-
// The type casting should not effect rounding of original double cast coordinate
282-
int64_t majorLat = settings.fixedLat * 10000000;
283-
int64_t minorLat = ((settings.fixedLat * 10000000) - majorLat) * 100;
284-
int64_t majorLong = settings.fixedLong * 10000000;
285-
int64_t minorLong = ((settings.fixedLong * 10000000) - majorLong) * 100;
286-
int32_t majorAlt = totalFixedAltitude * 100;
287-
int32_t minorAlt = ((totalFixedAltitude * 100) - majorAlt) * 100;
288-
289-
// systemPrintf("fixedLong (should be -105.184774720): %0.09f\r\n", settings.fixedLong);
290-
// systemPrintf("major (should be -1051847747): %lld\r\n", majorLat);
291-
// systemPrintf("minor (should be -20): %lld\r\n", minorLat);
292-
//
293-
// systemPrintf("fixedLat (should be 40.090335429): %0.09f\r\n", settings.fixedLat);
294-
// systemPrintf("major (should be 400903354): %lld\r\n", majorLong);
295-
// systemPrintf("minor (should be 29): %lld\r\n", minorLong);
296-
//
297-
// systemPrintf("fixedAlt (should be 1560.2284): %0.04f\r\n", settings.fixedAltitude);
298-
// systemPrintf("major (should be 156022): %ld\r\n", majorAlt);
299-
// systemPrintf("minor (should be 84): %ld\r\n", minorAlt);
245+
do {
246+
if (settings.fixedBaseCoordinateType == COORD_TYPE_ECEF)
247+
{
248+
// Break ECEF into main and high precision parts
249+
// The type casting should not effect rounding of original double cast coordinate
250+
long majorEcefX = floor((settings.fixedEcefX * 100.0) + 0.5);
251+
long minorEcefX = floor((((settings.fixedEcefX * 100.0) - majorEcefX) * 100.0) + 0.5);
252+
long majorEcefY = floor((settings.fixedEcefY * 100) + 0.5);
253+
long minorEcefY = floor((((settings.fixedEcefY * 100.0) - majorEcefY) * 100.0) + 0.5);
254+
long majorEcefZ = floor((settings.fixedEcefZ * 100) + 0.5);
255+
long minorEcefZ = floor((((settings.fixedEcefZ * 100.0) - majorEcefZ) * 100.0) + 0.5);
256+
257+
// systemPrintf("fixedEcefY (should be -4716808.5807): %0.04f\r\n", settings.fixedEcefY);
258+
// systemPrintf("major (should be -471680858): %ld\r\n", majorEcefY);
259+
// systemPrintf("minor (should be -7): %ld\r\n", minorEcefY);
260+
261+
// Units are cm with a high precision extension so -1234.5678 should be called: (-123456, -78)
262+
//-1280208.308,-4716803.847,4086665.811 is SparkFun HQ so...
263+
264+
response &= theGNSS.newCfgValset();
265+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_MODE, 2); // Fixed
266+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_POS_TYPE, 0); // Position in ECEF
267+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_X, majorEcefX);
268+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_X_HP, minorEcefX);
269+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Y, majorEcefY);
270+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Y_HP, minorEcefY);
271+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Z, majorEcefZ);
272+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_ECEF_Z_HP, minorEcefZ);
273+
response &= theGNSS.sendCfgValset();
274+
}
275+
else if (settings.fixedBaseCoordinateType == COORD_TYPE_GEODETIC)
276+
{
277+
// Add height of instrument (HI) to fixed altitude
278+
// https://www.e-education.psu.edu/geog862/node/1853
279+
// For example, if HAE is at 100.0m, + 2m stick + 73mm ARP = 102.073
280+
float totalFixedAltitude =
281+
settings.fixedAltitude + (settings.antennaHeight / 1000.0) + (settings.antennaReferencePoint / 1000.0);
282+
283+
// Break coordinates into main and high precision parts
284+
// The type casting should not effect rounding of original double cast coordinate
285+
int64_t majorLat = settings.fixedLat * 10000000;
286+
int64_t minorLat = ((settings.fixedLat * 10000000) - majorLat) * 100;
287+
int64_t majorLong = settings.fixedLong * 10000000;
288+
int64_t minorLong = ((settings.fixedLong * 10000000) - majorLong) * 100;
289+
int32_t majorAlt = totalFixedAltitude * 100;
290+
int32_t minorAlt = ((totalFixedAltitude * 100) - majorAlt) * 100;
291+
292+
// systemPrintf("fixedLong (should be -105.184774720): %0.09f\r\n", settings.fixedLong);
293+
// systemPrintf("major (should be -1051847747): %lld\r\n", majorLat);
294+
// systemPrintf("minor (should be -20): %lld\r\n", minorLat);
295+
//
296+
// systemPrintf("fixedLat (should be 40.090335429): %0.09f\r\n", settings.fixedLat);
297+
// systemPrintf("major (should be 400903354): %lld\r\n", majorLong);
298+
// systemPrintf("minor (should be 29): %lld\r\n", minorLong);
299+
//
300+
// systemPrintf("fixedAlt (should be 1560.2284): %0.04f\r\n", settings.fixedAltitude);
301+
// systemPrintf("major (should be 156022): %ld\r\n", majorAlt);
302+
// systemPrintf("minor (should be 84): %ld\r\n", minorAlt);
303+
304+
response &= theGNSS.newCfgValset();
305+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_MODE, 2); // Fixed
306+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_POS_TYPE, 1); // Position in LLH
307+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LAT, majorLat);
308+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LAT_HP, minorLat);
309+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LON, majorLong);
310+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LON_HP, minorLong);
311+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_HEIGHT, majorAlt);
312+
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_HEIGHT_HP, minorAlt);
313+
response &= theGNSS.sendCfgValset(maxWait);
314+
}
300315

301-
response &= theGNSS.newCfgValset();
302-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_MODE, 2); // Fixed
303-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_POS_TYPE, 1); // Position in LLH
304-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LAT, majorLat);
305-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LAT_HP, minorLat);
306-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LON, majorLong);
307-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_LON_HP, minorLong);
308-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_HEIGHT, majorAlt);
309-
response &= theGNSS.addCfgValset(UBLOX_CFG_TMODE_HEIGHT_HP, minorAlt);
310-
response &= theGNSS.sendCfgValset();
311-
}
316+
if (!response) {
317+
systemPrint("startFixedBase failed! ");
318+
if (retries <= 2) {
319+
systemPrintln("Retrying...");
320+
delay(1000);
321+
maxWait = 2200;
322+
}
323+
else {
324+
systemPrintln("Giving up and going into Rover mode!");
325+
}
326+
}
327+
} while ((!response) && (++retries <= 3));
312328

313329
return (response);
314330
}
@@ -349,7 +365,8 @@ void DevUBLOXGNSS::processRTCM(uint8_t incoming)
349365
rtcmLastReceived = millis();
350366
rtcmBytesSent++;
351367

352-
ntripServerProcessRTCM(incoming);
368+
for (int serverIndex = 0; serverIndex < NTRIP_SERVER_MAX; serverIndex++)
369+
ntripServerProcessRTCM(serverIndex, incoming);
353370

354371
espnowProcessRTCM(incoming);
355372
}
@@ -391,7 +408,8 @@ void processRTCMBuffer()
391408
rtcmLastReceived = millis();
392409
rtcmBytesSent++;
393410

394-
ntripServerProcessRTCM(incoming);
411+
for (int serverIndex = 0; serverIndex < NTRIP_SERVER_MAX; serverIndex++)
412+
ntripServerProcessRTCM(serverIndex, incoming);
395413

396414
espnowProcessRTCM(incoming);
397415
}

Firmware/RTK_Surveyor/Begin.ino

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ void beginBoard()
283283
settings.enablePrintBatteryMessages = false; // No pesky battery messages
284284
}
285285

286+
displaySfeFlame();
287+
286288
char versionString[21];
287289
getFirmwareVersion(versionString, sizeof(versionString), true);
288290
systemPrintf("SparkFun RTK %s %s\r\n", platformPrefix, versionString);
@@ -361,6 +363,9 @@ void beginBoard()
361363

362364
void beginSD()
363365
{
366+
if(sdCardForcedOffline == true)
367+
return;
368+
364369
bool gotSemaphore;
365370

366371
online.microSD = false;
@@ -445,6 +450,8 @@ void beginSD()
445450
systemPrintln("SD init failed - using SPI and SdFat. Is card formatted?");
446451
digitalWrite(pin_microSD_CS, HIGH); // Be sure SD is deselected
447452

453+
sdCardForcedOffline = true; //Prevent future scans for SD cards
454+
448455
// Check reset count and prevent rolling reboot
449456
if (settings.resetCount < 5)
450457
{
@@ -807,13 +814,14 @@ void beginGNSS()
807814
// Construct the firmware version as uint8_t. Note: will fail above 2.55!
808815
zedFirmwareVersionInt = (theGNSS.getFirmwareVersionHigh() * 100) + theGNSS.getFirmwareVersionLow();
809816

810-
// Check this is known firmware
817+
// Check if this is known firmware
811818
//"1.20" - Mostly for F9R HPS 1.20, but also F9P HPG v1.20
812819
//"1.21" - F9R HPS v1.21
813820
//"1.30" - ZED-F9P (HPG) released Dec, 2021. Also ZED-F9R (HPS) released Sept, 2022
814821
//"1.32" - ZED-F9P released May, 2022
822+
//"1.50" - ZED-F9P released July, 2024
815823

816-
const uint8_t knownFirmwareVersions[] = {100, 112, 113, 120, 121, 130, 132};
824+
const uint8_t knownFirmwareVersions[] = {100, 112, 113, 120, 121, 130, 132, 150};
817825
bool knownFirmware = false;
818826
for (uint8_t i = 0; i < (sizeof(knownFirmwareVersions) / sizeof(uint8_t)); i++)
819827
{

Firmware/RTK_Surveyor/Developer.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ void ntripClientValidateTables() {}
5959
// NTRIP server
6060
//----------------------------------------
6161

62-
bool ntripServerIsCasting() {return false;}
63-
void ntripServerPrintStatus() {systemPrint("NTRIP Server not compiled");}
64-
void ntripServerProcessRTCM(uint8_t incoming) {}
65-
void ntripServerStop(bool clientAllocated) {online.ntripServer = false;}
62+
bool ntripServerIsCasting(int serverIndex) {return false;}
63+
void ntripServerPrintStatus(int serverIndex) {systemPrintf("**NTRIP Server %d not compiled**\r\n", serverIndex);}
64+
void ntripServerProcessRTCM(int serverIndex, uint8_t incoming) {}
65+
void ntripServerStop(int serverIndex, bool clientAllocated) {online.ntripServer[serverIndex] = false;}
6666
void ntripServerUpdate() {}
6767
void ntripServerValidateTables() {}
6868

0 commit comments

Comments
 (0)