Skip to content

Commit 5688707

Browse files
author
Nathan Seidle
committed
Prelim NTRIP server support. Reduced serial buffers. Reduced task stack size.
Serial buffers were 16384, task stack size was 10,000. Reduced to 4096 and 1k to make room for WiFi/NTRIP capabilities.
1 parent 27057af commit 5688707

File tree

5 files changed

+371
-160
lines changed

5 files changed

+371
-160
lines changed

Firmware/RTK_Surveyor/Base.ino

Lines changed: 173 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ bool updateSurveyInStatus()
4343
} //baseState = Surveying In Not started
4444
else
4545
{
46-
4746
bool response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (req can take a long time)
4847
if (response == true)
4948
{
@@ -135,65 +134,53 @@ bool configureUbloxModuleBase()
135134
digitalWrite(positionAccuracyLED_10cm, LOW);
136135
digitalWrite(positionAccuracyLED_100cm, LOW);
137136

137+
//In base mode we force 1Hz
138+
if (myGPS.getNavigationFrequency() != 1)
139+
{
140+
response &= myGPS.setNavigationFrequency(1); //Set output in Hz
141+
}
142+
138143
// Set dynamic model
139144
if (myGPS.getDynamicModel() != DYN_MODEL_STATIONARY)
140145
{
141-
if (myGPS.setDynamicModel(DYN_MODEL_STATIONARY) == false)
142-
{
146+
response &= myGPS.setDynamicModel(DYN_MODEL_STATIONARY);
147+
if (response == false)
143148
Serial.println(F("setDynamicModel failed!"));
144-
return (false);
145-
}
146149
}
147150

148-
//In base mode the Surveyor should output RTCM over UART1, UART2, and USB ports:
151+
//In base mode the Surveyor should output RTCM over UART2 and I2C ports:
149152
//(Primary) UART2 in case the Surveyor is connected via radio to rover
153+
//(Optional) I2C in case user wants base to connect to WiFi and NTRIP Serve to Caster
150154
//(Seconday) USB in case the Surveyor is used as an NTRIP caster
151155
//(Tertiary) UART1 in case Surveyor is sending RTCM to phone that is then NTRIP caster
152-
if (getRTCMSettings(UBX_RTCM_1005, COM_PORT_UART2) != 1)
153-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_UART2, 1); //Enable message 1005 to output through UART2, message every second
154-
if (getRTCMSettings(UBX_RTCM_1074, COM_PORT_UART2) != 1)
155-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_UART2, 1);
156-
if (getRTCMSettings(UBX_RTCM_1084, COM_PORT_UART2) != 1)
157-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_UART2, 1);
158-
if (getRTCMSettings(UBX_RTCM_1094, COM_PORT_UART2) != 1)
159-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_UART2, 1);
160-
if (getRTCMSettings(UBX_RTCM_1124, COM_PORT_UART2) != 1)
161-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_UART2, 1);
162-
if (getRTCMSettings(UBX_RTCM_1230, COM_PORT_UART2) != 10)
163-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_UART2, 10); //Enable message every 10 seconds
164-
165-
if (getRTCMSettings(UBX_RTCM_1005, COM_PORT_UART1) != 1)
166-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_UART1, 1); //Enable message 1005 to output through UART2, message every second
167-
if (getRTCMSettings(UBX_RTCM_1074, COM_PORT_UART1) != 1)
168-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_UART1, 1);
169-
if (getRTCMSettings(UBX_RTCM_1084, COM_PORT_UART1) != 1)
170-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_UART1, 1);
171-
if (getRTCMSettings(UBX_RTCM_1094, COM_PORT_UART1) != 1)
172-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_UART1, 1);
173-
if (getRTCMSettings(UBX_RTCM_1124, COM_PORT_UART1) != 1)
174-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_UART1, 1);
175-
if (getRTCMSettings(UBX_RTCM_1230, COM_PORT_UART1) != 10)
176-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_UART1, 10); //Enable message every 10 seconds
177-
178-
if (getRTCMSettings(UBX_RTCM_1005, COM_PORT_USB) != 1)
179-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_USB, 1); //Enable message 1005 to output through UART2, message every second
180-
if (getRTCMSettings(UBX_RTCM_1074, COM_PORT_USB) != 1)
181-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_USB, 1);
182-
if (getRTCMSettings(UBX_RTCM_1084, COM_PORT_USB) != 1)
183-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_USB, 1);
184-
if (getRTCMSettings(UBX_RTCM_1094, COM_PORT_USB) != 1)
185-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_USB, 1);
186-
if (getRTCMSettings(UBX_RTCM_1124, COM_PORT_USB) != 1)
187-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_USB, 1);
188-
if (getRTCMSettings(UBX_RTCM_1230, COM_PORT_USB) != 10)
189-
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_USB, 10); //Enable message every 10 seconds
156+
response &= enableRTCMSentences(COM_PORT_UART2);
157+
response &= enableRTCMSentences(COM_PORT_UART1);
158+
response &= enableRTCMSentences(COM_PORT_USB);
190159

191-
if (response == false)
160+
if (settings.enableNtripServer == true)
192161
{
193-
Serial.println(F("RTCM failed to enable."));
194-
return (false);
162+
//Turn on RTCM over I2C port so that we can harvest RTCM over I2C and send out over WiFi
163+
//This is easier than parsing over UART because the library handles the frame detection
164+
165+
#define OUTPUT_SETTING 14
166+
#define INPUT_SETTING 12
167+
getPortSettings(COM_PORT_I2C); //Load the settingPayload with this port's settings
168+
if (settingPayload[OUTPUT_SETTING] != COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_RTCM3 || settingPayload[INPUT_SETTING] != COM_TYPE_UBX)
169+
{
170+
response &= myGPS.setPortOutput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_RTCM3); //UBX+RTCM3 is not a valid option so we enable all three.
171+
response &= myGPS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX); //Set the I2C port to input UBX only
172+
}
173+
174+
//Disable any NMEA sentences
175+
response &= disableNMEASentences(COM_PORT_I2C);
176+
177+
//Enable necessary RTCM sentences
178+
response &= enableRTCMSentences(COM_PORT_I2C);
195179
}
196180

181+
if (response == false)
182+
Serial.println(F("RTCM settings failed to enable"));
183+
197184
return (response);
198185
}
199186

@@ -266,17 +253,17 @@ bool startFixedBase()
266253
int32_t majorAlt = settings.fixedAltitude * 100;
267254
int32_t minorAlt = ((settings.fixedAltitude * 100) - majorAlt) * 100;
268255

269-
Serial.printf("fixedLat (should be -105.184774720): %0.09f\n", settings.fixedLat);
270-
Serial.printf("major (should be -1051847747): %lld\n", majorLat);
271-
Serial.printf("minor (should be -20): %lld\n", minorLat);
272-
273-
Serial.printf("fixedLong (should be 40.090335429): %0.09f\n", settings.fixedLong);
274-
Serial.printf("major (should be 400903354): %lld\n", majorLong);
275-
Serial.printf("minor (should be 29): %lld\n", minorLong);
276-
277-
Serial.printf("fixedAlt (should be 1560.2284): %0.04f\n", settings.fixedAltitude);
278-
Serial.printf("major (should be 156022): %ld\n", majorAlt);
279-
Serial.printf("minor (should be 84): %ld\n", minorAlt);
256+
// Serial.printf("fixedLat (should be -105.184774720): %0.09f\n", settings.fixedLat);
257+
// Serial.printf("major (should be -1051847747): %lld\n", majorLat);
258+
// Serial.printf("minor (should be -20): %lld\n", minorLat);
259+
//
260+
// Serial.printf("fixedLong (should be 40.090335429): %0.09f\n", settings.fixedLong);
261+
// Serial.printf("major (should be 400903354): %lld\n", majorLong);
262+
// Serial.printf("minor (should be 29): %lld\n", minorLong);
263+
//
264+
// Serial.printf("fixedAlt (should be 1560.2284): %0.04f\n", settings.fixedAltitude);
265+
// Serial.printf("major (should be 156022): %ld\n", majorAlt);
266+
// Serial.printf("minor (should be 84): %ld\n", minorAlt);
280267

281268
response = myGPS.setStaticPosition(
282269
majorLong, minorLong,
@@ -293,6 +280,133 @@ bool startFixedBase()
293280
return (response);
294281
}
295282

283+
//Call regularly to get data from u-blox module and send out over local WiFi
284+
//We make sure we are connected to WiFi, then
285+
bool updateNtripServer()
286+
{
287+
//Is WiFi setup?
288+
if (WiFi.isConnected() == false)
289+
{
290+
//Turn off Bluetooth and turn on WiFi
291+
endBluetooth();
292+
293+
Serial.printf("Connecting to local WiFi: %s\n", settings.wifiSSID);
294+
WiFi.begin(settings.wifiSSID, settings.wifiPW);
295+
296+
//while(1) delay(10);
297+
298+
int maxTime = 10000;
299+
long startTime = millis();
300+
while (WiFi.status() != WL_CONNECTED) {
301+
delay(500);
302+
Serial.print(F("."));
303+
304+
if (millis() - startTime > maxTime)
305+
{
306+
Serial.println(F("Failed to connect to WiFi. Are you sure your WiFi credentials are correct?"));
307+
return (false);
308+
}
309+
}
310+
delay(10);
311+
312+
} //End WiFi connect check
313+
314+
//Are we connected to caster?
315+
if (caster.connected() == false)
316+
{
317+
Serial.printf("Opening socket to %s\n", settings.casterHost);
318+
319+
if (caster.connect(settings.casterHost, settings.casterPort) == true) //Attempt connection
320+
{
321+
Serial.printf("Connected to %s:%d\n", settings.casterHost, settings.casterPort);
322+
323+
const int SERVER_BUFFER_SIZE = 512;
324+
char serverBuffer[SERVER_BUFFER_SIZE];
325+
326+
snprintf(serverBuffer, SERVER_BUFFER_SIZE, "SOURCE %s /%s\r\nSource-Agent: NTRIP %s/%s\r\n\r\n",
327+
settings.mountPointPW, settings.mountPoint, ntrip_server_name, "App Version 1.0");
328+
329+
Serial.printf("Sending credentials:\n%s\n", serverBuffer);
330+
caster.write(serverBuffer, strlen(serverBuffer));
331+
332+
//Wait for response
333+
unsigned long timeout = millis();
334+
while (caster.available() == 0)
335+
{
336+
if (millis() - timeout > 5000)
337+
{
338+
Serial.println(F("Caster failed to respond. Do you have your caster address and port correct?"));
339+
caster.stop();
340+
delay(10);
341+
return (false);
342+
}
343+
delay(10);
344+
}
345+
346+
delay(10); //Yield to RTOS
347+
348+
//Check reply
349+
bool connectionSuccess = false;
350+
char response[512];
351+
int responseSpot = 0;
352+
while (caster.available())
353+
{
354+
response[responseSpot++] = caster.read();
355+
if (strstr(response, "200") > 0) //Look for 'ICY 200 OK'
356+
connectionSuccess = true;
357+
if (responseSpot == 512 - 1) break;
358+
}
359+
response[responseSpot] = '\0';
360+
Serial.printf("Caster responded with: %s\n", response);
361+
362+
if (connectionSuccess == false)
363+
{
364+
Serial.printf("Caster responded with bad news: %s. Are you sure your caster credentials are correct?", response);
365+
}
366+
else
367+
{
368+
//We're connected!
369+
Serial.println(F("Connected to caster"));
370+
371+
//Reset flags
372+
lastServerReport_ms = millis();
373+
lastServerSent_ms = millis();
374+
serverBytesSent = 0;
375+
}
376+
} //End attempt to connect
377+
else
378+
{
379+
Serial.println(F("Failed to connect to caster"));
380+
delay(10); //Give RTOS some time
381+
return (false);
382+
}
383+
} //End connected == false
384+
385+
386+
//Poll module for any new I2C data including RTCM
387+
//These bytes will automatically be parsed by processRTCM() function
388+
myGPS.checkUblox();
389+
390+
//Close socket if we don't have new data for 10s
391+
//RTK2Go will ban your IP address if you abuse it. See http://www.rtk2go.com/how-to-get-your-ip-banned/
392+
//So let's not leave the socket open/hanging without data
393+
if (millis() - lastServerSent_ms > maxTimeBeforeHangup_ms)
394+
{
395+
Serial.println(F("RTCM timeout. Disconnecting from caster."));
396+
caster.stop();
397+
return (false);
398+
}
399+
400+
//Report some statistics every 250
401+
if (millis() - lastServerReport_ms > 250)
402+
{
403+
lastServerReport_ms += 250;
404+
Serial.printf("Total bytes sent to caster: %d\n", serverBytesSent);
405+
}
406+
407+
return (true);
408+
}
409+
296410
//This function gets called from the SparkFun u-blox Arduino Library.
297411
//As each RTCM byte comes in you can specify what to do with it
298412
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
@@ -302,6 +416,6 @@ void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
302416
{
303417
caster.write(incoming); //Send this byte to socket
304418
serverBytesSent++;
305-
lastSentRTCM_ms = millis();
419+
lastServerSent_ms = millis();
306420
}
307421
}

Firmware/RTK_Surveyor/RTK_Surveyor.ino

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
(Done) Ports - Configure Radio and Data port baud rates
3030
(Done) Test menu
3131
Enable various debug outputs sent over BT
32-
3332
*/
3433

3534
const int FIRMWARE_VERSION_MAJOR = 1;
@@ -87,7 +86,8 @@ long startLogTime_minutes = 0; //Mark when we start logging so we can stop loggi
8786
WiFiClient caster;
8887
const char * ntrip_server_name = "SparkFun_RTK_Surveyor";
8988

90-
long lastSentRTCM_ms = 0; //Time of last data pushed to socket
89+
unsigned long lastServerSent_ms = 0; //Time of last data pushed to caster
90+
unsigned long lastServerReport_ms = 0; //Time of last report of caster bytes sent
9191
int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster
9292

9393
uint32_t serverBytesSent = 0; //Just a running total
@@ -125,6 +125,10 @@ SFE_UBLOX_GPS_ADD myGPS;
125125
//u-blox firmware to work correctly. We check the module firmware at startup but
126126
//don't prevent operation if firmware is mismatched.
127127
char latestZEDFirmware[] = "FWVER=HPG 1.13";
128+
129+
//Used for config ZED for things not supported in library: getPortSettings, getSerialRate, getNMEASettings, getRTCMSettings
130+
//This array holds the payload data bytes. Global so that we can use between config functions.
131+
uint8_t settingPayload[MAX_PAYLOAD_SIZE];
128132
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
129133

130134
//Battery fuel gauge and PWM LEDs
@@ -143,14 +147,17 @@ const int resolution = 8;
143147
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
144148
#include "BluetoothSerial.h"
145149
BluetoothSerial SerialBT;
150+
#include "esp_bt.h" //Core access is needed for BT stop. See customBTstop() for more info.
146151

147152
HardwareSerial GPS(2);
148153
#define RXD2 16
149154
#define TXD2 17
150155

151-
#define SERIAL_SIZE_RX 16384 //Using a large buffer. This might be much bigger than needed but the ESP32 has enough RAM
156+
#define SERIAL_SIZE_RX 4096 //Reduced from 16384 to make room for WiFi/NTRIP server capabilities
152157
uint8_t rBuffer[SERIAL_SIZE_RX]; //Buffer for reading F9P
153158
uint8_t wBuffer[SERIAL_SIZE_RX]; //Buffer for writing to F9P
159+
TaskHandle_t F9PSerialReadTaskHandle = NULL; //Store handles so that we can kill them if user goes into WiFi NTRIP Server mode
160+
TaskHandle_t F9PSerialWriteTaskHandle = NULL; //Store handles so that we can kill them if user goes into WiFi NTRIP Server mode
154161
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
155162

156163
//External Display
@@ -280,6 +287,13 @@ void loop()
280287
{
281288
updateSurveyInStatus();
282289
}
290+
else if (baseState == BASE_TRANSMITTING)
291+
{
292+
if(settings.enableNtripServer == true)
293+
{
294+
updateNtripServer();
295+
}
296+
}
283297
else if (baseState == BASE_OFF)
284298
{
285299
updateRoverStatus();

0 commit comments

Comments
 (0)