diff --git a/Firmware/RTK_Surveyor/AP-Config/index.html b/Firmware/RTK_Surveyor/AP-Config/index.html index a9b4778ae..b9c099e53 100644 --- a/Firmware/RTK_Surveyor/AP-Config/index.html +++ b/Firmware/RTK_Surveyor/AP-Config/index.html @@ -874,55 +874,57 @@

-
- +
- -

+ +

-
-
-
-
diff --git a/Firmware/RTK_Surveyor/AP-Config/src/main.js b/Firmware/RTK_Surveyor/AP-Config/src/main.js index aee3be499..09d6d9f62 100644 --- a/Firmware/RTK_Surveyor/AP-Config/src/main.js +++ b/Firmware/RTK_Surveyor/AP-Config/src/main.js @@ -293,12 +293,12 @@ function validateFields() { checkElementValue("fixedLong", -180, 180, "Must be -180 to 180", "collapseBaseConfig"); checkElementValue("fixedAltitude", 0, 8849, "Must be 0 to 8849", "collapseBaseConfig"); - checkElementString("wifiSSID", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); - checkElementString("wifiPW", 0, 30, "Must be 0 to 30 characters", "collapseBaseConfig"); - checkElementString("casterHost", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); - checkElementValue("casterPort", 1, 99999, "Must be 1 to 99999", "collapseBaseConfig"); - checkElementString("mountPointUpload", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); - checkElementString("mountPointUploadPW", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_wifiSSID", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_wifiPW", 0, 30, "Must be 0 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_CasterHost", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementValue("ntripServer_CasterPort", 1, 99999, "Must be 1 to 99999", "collapseBaseConfig"); + checkElementString("ntripServer_MountPoint", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_MountPointPW", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); //System Config checkElementValue("maxLogTime_minutes", 1, 2880, "Must be 1 to 2880", "collapseSystemConfig"); @@ -610,21 +610,21 @@ document.addEventListener("DOMContentLoaded", (event) => { ge("enableNtripServer").addEventListener("change", function () { if (ge("enableNtripServer").checked) { //Enable NTRIP inputs - ge("wifiSSID").disabled = false; - ge("wifiPW").disabled = false; - ge("casterHost").disabled = false; - ge("casterPort").disabled = false; - ge("mountPointUpload").disabled = false; - ge("mountPointUploadPW").disabled = false; + ge("ntripServer_wifiSSID").disabled = false; + ge("ntripServer_wifiPW").disabled = false; + ge("ntripServer_CasterHost").disabled = false; + ge("ntripServer_CasterPort").disabled = false; + ge("ntripServer_MountPoint").disabled = false; + ge("ntripServer_MountPointPW").disabled = false; } else { //Disable NTRIP inputs - ge("wifiSSID").disabled = true; - ge("wifiPW").disabled = true; - ge("casterHost").disabled = true; - ge("casterPort").disabled = true; - ge("mountPointUpload").disabled = true; - ge("mountPointUploadPW").disabled = true; + ge("ntripServer_wifiSSID").disabled = true; + ge("ntripServer_wifiPW").disabled = true; + ge("ntripServer_CasterHost").disabled = true; + ge("ntripServer_CasterPort").disabled = true; + ge("ntripServer_MountPoint").disabled = true; + ge("ntripServer_MountPointPW").disabled = true; } }); diff --git a/Firmware/RTK_Surveyor/Base.ino b/Firmware/RTK_Surveyor/Base.ino index 365d94219..d1b307297 100644 --- a/Firmware/RTK_Surveyor/Base.ino +++ b/Firmware/RTK_Surveyor/Base.ino @@ -26,6 +26,9 @@ bool configureUbloxModuleBase() i2cGNSS.checkUblox(); //Regularly poll to get latest data and any RTCM + i2cGNSS.setNMEAGPGGAcallbackPtr(NULL); // Disable GPGGA call back that may have been set during Rover Client mode + i2cGNSS.disableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C); // Disable NMEA message + if (i2cGNSS.getSurveyInActive() == true) { log_d("Disabling survey"); @@ -250,9 +253,9 @@ void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming) } #ifdef COMPILE_WIFI - if (caster.connected() == true) + if (ntripServer.connected() == true) { - caster.write(incoming); //Send this byte to socket + ntripServer.write(incoming); //Send this byte to socket casterBytesSent++; lastServerSent_ms = millis(); } diff --git a/Firmware/RTK_Surveyor/Begin.ino b/Firmware/RTK_Surveyor/Begin.ino index 1e73cafa1..54b6ddbb2 100644 --- a/Firmware/RTK_Surveyor/Begin.ino +++ b/Firmware/RTK_Surveyor/Begin.ino @@ -168,16 +168,20 @@ void beginSD() if (settings.enableSD == true) { - //Max power up time is 250ms: https://www.kingston.com/datasheets/SDCIT-specsheet-64gb_en.pdf - //Max current is 200mA average across 1s, peak 300mA - delay(10); - //Do a quick test to see if a card is present - if (sdPresent() == false) + int tries = 0; + int maxTries = 5; + while (tries++ < maxTries) { - log_d("SD card not detected"); - return; + if (sdPresent() == true) break; + log_d("SD present failed. Trying again %d out of %d", tries + 1, maxTries); + + //Max power up time is 250ms: https://www.kingston.com/datasheets/SDCIT-specsheet-64gb_en.pdf + //Max current is 200mA average across 1s, peak 300mA + delay(10); } + if (tries == maxTries) return; + //If an SD card is present, allow SdFat to take over log_d("SD card detected"); @@ -189,8 +193,8 @@ void beginSD() if (sd.begin(SdSpiConfig(pin_microSD_CS, SHARED_SPI, SD_SCK_MHZ(settings.spiFrequency))) == false) { - int tries = 0; - int maxTries = 1; + tries = 0; + maxTries = 1; for ( ; tries < maxTries ; tries++) { log_d("SD init failed. Trying again %d out of %d", tries + 1, maxTries); @@ -315,6 +319,8 @@ void stopUART2Tasks() void beginFS() { +#define FORMAT_LITTLEFS_IF_FAILED true + if (online.fs == false) { Serial.println("Starting FS"); diff --git a/Firmware/RTK_Surveyor/Display.ino b/Firmware/RTK_Surveyor/Display.ino index 1edc62cc1..658877d4a 100644 --- a/Firmware/RTK_Surveyor/Display.ino +++ b/Firmware/RTK_Surveyor/Display.ino @@ -30,6 +30,17 @@ void updateDisplay() case (STATE_ROVER_RTK_FIX): paintRoverRTKFix(); break; + + case (STATE_ROVER_CLIENT_WIFI_STARTED): + paintRoverWiFiStarted(); + break; + case (STATE_ROVER_CLIENT_WIFI_CONNECTED): + paintRoverWiFiStarted(); + break; + case (STATE_ROVER_CLIENT_STARTED): + paintRoverWiFiStarted(); + break; + case (STATE_BASE_NOT_STARTED): //Do nothing. Static display shown during state change. break; @@ -230,7 +241,7 @@ void paintWirelessIcon() wifiIconDisplayed = true; //Draw the icon - displayBitmap(6, 1, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol); + displayBitmap(0, 1, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol); } else wifiIconDisplayed = false; @@ -239,7 +250,14 @@ void paintWirelessIcon() else if (radioState == WIFI_CONNECTED) { //Solid WiFi icon - displayBitmap(6, 1, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol); + displayBitmap(0, 1, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol); + + //If we are connected to NTRIP Client, show download arrow + if(online.ntripClient == true) + displayBitmap(18, 1, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); + + oled.line(0, 11, 16, 11); + } else { @@ -480,7 +498,6 @@ void paintSIV() if (online.display == true && online.gnss == true) { //Blink satellite dish icon if we don't have a fix - uint8_t fixType = fixType; if (fixType == 3 || fixType == 4 || fixType == 5) //3D, 3D+DR, or Time { //Fix, turn on icon @@ -509,13 +526,9 @@ void paintSIV() oled.print(":"); if (fixType == 0) //0 = No Fix - { oled.print("0"); - } else - { oled.print(numSV); - } paintResets(); } //End gnss online @@ -672,6 +685,25 @@ void paintRoverRTKFix() } } +//Display Blinking WiFi +void paintRoverWiFiStarted() +{ + if (online.display == true) + { + paintBatteryLevel(); //Top right corner + + paintWirelessIcon(); //Top left corner + + paintBaseState(); //Top center + + paintHorizontalAccuracy(); + + paintSIV(); + + paintLogging(); + } +} + //Start of base / survey in / NTRIP mode //Screen is displayed while we are waiting for horz accuracy to drop to appropriate level //Blink crosshair icon until we have we have horz accuracy < user defined level diff --git a/Firmware/RTK_Surveyor/Form.ino b/Firmware/RTK_Surveyor/Form.ino index 9969f3b97..79e8c6df3 100644 --- a/Firmware/RTK_Surveyor/Form.ino +++ b/Firmware/RTK_Surveyor/Form.ino @@ -348,17 +348,25 @@ void createSettingsString(char* settingsCSV) stringRecord(settingsCSV, "fixedAltitude", settings.fixedAltitude, 4); stringRecord(settingsCSV, "enableNtripServer", settings.enableNtripServer); - stringRecord(settingsCSV, "casterHost", settings.casterHost); - stringRecord(settingsCSV, "casterPort", settings.casterPort); - stringRecord(settingsCSV, "casterUser", settings.casterUser); - stringRecord(settingsCSV, "casterUserPW", settings.casterUserPW); - stringRecord(settingsCSV, "mountPointUpload", settings.mountPointUpload); - stringRecord(settingsCSV, "mountPointUploadPW", settings.mountPointUploadPW); - stringRecord(settingsCSV, "mountPointDownload", settings.mountPointDownload); - stringRecord(settingsCSV, "mountPointDownloadPW", settings.mountPointDownloadPW); - stringRecord(settingsCSV, "casterTransmitGGA", settings.casterTransmitGGA); - stringRecord(settingsCSV, "wifiSSID", settings.wifiSSID); - stringRecord(settingsCSV, "wifiPW", settings.wifiPW); + stringRecord(settingsCSV, "ntripServer_CasterHost", settings.ntripServer_CasterHost); + stringRecord(settingsCSV, "ntripServer_CasterPort", settings.ntripServer_CasterPort); + stringRecord(settingsCSV, "ntripServer_CasterUser", settings.ntripServer_CasterUser); + stringRecord(settingsCSV, "ntripServer_CasterUserPW", settings.ntripServer_CasterUserPW); + stringRecord(settingsCSV, "ntripServer_MountPoint", settings.ntripServer_MountPoint); + stringRecord(settingsCSV, "ntripServer_MountPointPW", settings.ntripServer_MountPointPW); + stringRecord(settingsCSV, "ntripServer_wifiSSID", settings.ntripServer_wifiSSID); + stringRecord(settingsCSV, "ntripServer_wifiPW", settings.ntripServer_wifiPW); + + stringRecord(settingsCSV, "enableNtripClient", settings.enableNtripClient); + stringRecord(settingsCSV, "ntripClient_CasterHost", settings.ntripClient_CasterHost); + stringRecord(settingsCSV, "ntripClient_CasterPort", settings.ntripClient_CasterPort); + stringRecord(settingsCSV, "ntripClient_CasterUser", settings.ntripClient_CasterUser); + stringRecord(settingsCSV, "ntripClient_CasterUserPW", settings.ntripClient_CasterUserPW); + stringRecord(settingsCSV, "ntripClient_MountPoint", settings.ntripClient_MountPoint); + stringRecord(settingsCSV, "ntripClient_MountPointPW", settings.ntripClient_MountPointPW); + stringRecord(settingsCSV, "ntripClient_wifiSSID", settings.ntripClient_wifiSSID); + stringRecord(settingsCSV, "ntripClient_wifiPW", settings.ntripClient_wifiPW); + stringRecord(settingsCSV, "ntripClient_TransmitGGA", settings.ntripClient_TransmitGGA); //Sensor Fusion Config stringRecord(settingsCSV, "enableSensorFusion", settings.enableSensorFusion); @@ -440,30 +448,6 @@ void updateSettingWithValue(const char *settingName, const char* settingValueStr settings.dataPortBaud = settingValue; else if (strcmp(settingName, "radioPortBaud") == 0) settings.radioPortBaud = settingValue; - else if (strcmp(settingName, "enableNtripServer") == 0) - settings.enableNtripServer = settingValueBool; - else if (strcmp(settingName, "casterHost") == 0) - strcpy(settings.casterHost, settingValueStr); - else if (strcmp(settingName, "casterPort") == 0) - settings.casterPort = settingValue; - else if (strcmp(settingName, "casterUser") == 0) - strcpy(settings.casterUser, settingValueStr); - else if (strcmp(settingName, "casterUserPW") == 0) - strcpy(settings.casterUserPW, settingValueStr); - else if (strcmp(settingName, "mountPointUpload") == 0) - strcpy(settings.mountPointUpload, settingValueStr); - else if (strcmp(settingName, "mountPointUploadPW") == 0) - strcpy(settings.mountPointUploadPW, settingValueStr); - else if (strcmp(settingName, "mountPointDownload") == 0) - strcpy(settings.mountPointDownload, settingValueStr); - else if (strcmp(settingName, "mountPointDownloadPW") == 0) - strcpy(settings.mountPointDownloadPW, settingValueStr); - else if (strcmp(settingName, "casterTransmitGGA") == 0) - settings.casterTransmitGGA = settingValueBool; - else if (strcmp(settingName, "wifiSSID") == 0) - strcpy(settings.wifiSSID, settingValueStr); - else if (strcmp(settingName, "wifiPW") == 0) - strcpy(settings.wifiPW, settingValueStr); else if (strcmp(settingName, "enableLogging") == 0) settings.enableLogging = settingValueBool; else if (strcmp(settingName, "dataPortChannel") == 0) @@ -488,6 +472,46 @@ void updateSettingWithValue(const char *settingName, const char* settingValueStr else if (strcmp(settingName, "profileName") == 0) strcpy(settings.profileName, settingValueStr); + else if (strcmp(settingName, "enableNtripServer") == 0) + settings.enableNtripServer = settingValueBool; + else if (strcmp(settingName, "ntripServer_CasterHost") == 0) + strcpy(settings.ntripServer_CasterHost, settingValueStr); + else if (strcmp(settingName, "ntripServer_CasterPort") == 0) + settings.ntripServer_CasterPort = settingValue; + else if (strcmp(settingName, "ntripServer_CasterUser") == 0) + strcpy(settings.ntripServer_CasterUser, settingValueStr); + else if (strcmp(settingName, "ntripServer_CasterUserPW") == 0) + strcpy(settings.ntripServer_CasterUserPW, settingValueStr); + else if (strcmp(settingName, "ntripServer_MountPoint") == 0) + strcpy(settings.ntripServer_MountPoint, settingValueStr); + else if (strcmp(settingName, "ntripServer_MountPointPW") == 0) + strcpy(settings.ntripServer_MountPointPW, settingValueStr); + else if (strcmp(settingName, "ntripServer_wifiSSID") == 0) + strcpy(settings.ntripServer_wifiSSID, settingValueStr); + else if (strcmp(settingName, "ntripServer_wifiPW") == 0) + strcpy(settings.ntripServer_wifiPW, settingValueStr); + + else if (strcmp(settingName, "enableNtripClient") == 0) + settings.enableNtripClient = settingValueBool; + else if (strcmp(settingName, "ntripClient_CasterHost") == 0) + strcpy(settings.ntripClient_CasterHost, settingValueStr); + else if (strcmp(settingName, "ntripClient_CasterPort") == 0) + settings.ntripClient_CasterPort = settingValue; + else if (strcmp(settingName, "ntripClient_CasterUser") == 0) + strcpy(settings.ntripClient_CasterUser, settingValueStr); + else if (strcmp(settingName, "ntripClient_CasterUserPW") == 0) + strcpy(settings.ntripClient_CasterUserPW, settingValueStr); + else if (strcmp(settingName, "ntripClient_MountPoint") == 0) + strcpy(settings.ntripClient_MountPoint, settingValueStr); + else if (strcmp(settingName, "ntripClient_MountPointPW") == 0) + strcpy(settings.ntripClient_MountPointPW, settingValueStr); + else if (strcmp(settingName, "ntripClient_wifiSSID") == 0) + strcpy(settings.ntripClient_wifiSSID, settingValueStr); + else if (strcmp(settingName, "ntripClient_wifiPW") == 0) + strcpy(settings.ntripClient_wifiPW, settingValueStr); + else if (strcmp(settingName, "ntripClient_TransmitGGA") == 0) + settings.ntripClient_TransmitGGA = settingValueBool; + //Unused variables - read to avoid errors else if (strcmp(settingName, "measurementRateSec") == 0) {} else if (strcmp(settingName, "baseTypeSurveyIn") == 0) {} diff --git a/Firmware/RTK_Surveyor/NVM.ino b/Firmware/RTK_Surveyor/NVM.ino index 1cdfa6b72..2d02d061b 100644 --- a/Firmware/RTK_Surveyor/NVM.ino +++ b/Firmware/RTK_Surveyor/NVM.ino @@ -76,7 +76,7 @@ bool getSettings(uint8_t fileNumber, Settings &localSettings) //(It is possible for two different versions of the code to have the same sizeOfSettings - which causes problems!) if (localSettings.rtkIdentifier != RTK_IDENTIFIER) { - log_d("Settings are not valid for this variant of RTK %s. Found %s, should be %s. Using default settings.", platformPrefix, settings.rtkIdentifier, RTK_IDENTIFIER); + log_d("Settings are not valid for this variant of RTK %s. Found 0x%02X, should be 0x%02X. Using default settings.", platformPrefix, localSettings.rtkIdentifier, RTK_IDENTIFIER); return (false); } @@ -251,6 +251,7 @@ void loadSettingsPartial() //Load the settings file into a temp holder until we know it's valid Settings tempSettings; + if (getSettings(profileNumber, tempSettings) == true) settings = tempSettings; //Settings are good. Move them over. } @@ -312,18 +313,6 @@ void recordSystemSettingsToFile() settingsFile.println("dataPortBaud=" + (String)settings.dataPortBaud); settingsFile.println("radioPortBaud=" + (String)settings.radioPortBaud); - settingsFile.println("enableNtripServer=" + (String)settings.enableNtripServer); - settingsFile.println("casterHost=" + (String)settings.casterHost); - settingsFile.println("casterPort=" + (String)settings.casterPort); - settingsFile.println("casterUser=" + (String)settings.casterUser); - settingsFile.println("casterUserPW=" + (String)settings.casterUserPW); - settingsFile.println("mountPointUpload=" + (String)settings.mountPointUpload); - settingsFile.println("mountPointUploadPW=" + (String)settings.mountPointUploadPW); - settingsFile.println("mountPointDownload=" + (String)settings.mountPointDownload); - settingsFile.println("mountPointDownloadPW=" + (String)settings.mountPointDownloadPW); - settingsFile.println("casterTransmitGGA=" + (String)settings.casterTransmitGGA); - settingsFile.println("wifiSSID=" + (String)settings.wifiSSID); - settingsFile.println("wifiPW=" + (String)settings.wifiPW); settingsFile.println("surveyInStartingAccuracy=" + (String)settings.surveyInStartingAccuracy); settingsFile.println("measurementRate=" + (String)settings.measurementRate); settingsFile.println("navigationRate=" + (String)settings.navigationRate); @@ -346,6 +335,25 @@ void recordSystemSettingsToFile() settingsFile.println("externalPulsePolarity=" + (String)settings.externalPulsePolarity); settingsFile.println("enableExternalHardwareEventLogging=" + (String)settings.enableExternalHardwareEventLogging); settingsFile.println("profileName=" + (String)settings.profileName); + settingsFile.println("enableNtripServer=" + (String)settings.enableNtripServer); + settingsFile.println("ntripServer_CasterHost=" + (String)settings.ntripServer_CasterHost); + settingsFile.println("ntripServer_CasterPort=" + (String)settings.ntripServer_CasterPort); + settingsFile.println("ntripServer_CasterUser=" + (String)settings.ntripServer_CasterUser); + settingsFile.println("ntripServer_CasterUserPW=" + (String)settings.ntripServer_CasterUserPW); + settingsFile.println("ntripServer_MountPoint=" + (String)settings.ntripServer_MountPoint); + settingsFile.println("ntripServer_MountPointPW=" + (String)settings.ntripServer_MountPointPW); + settingsFile.println("ntripServer_wifiSSID=" + (String)settings.ntripServer_wifiSSID); + settingsFile.println("ntripServer_wifiPW=" + (String)settings.ntripServer_wifiPW); + settingsFile.println("enableNtripClient=" + (String)settings.enableNtripClient); + settingsFile.println("ntripClient_CasterHost=" + (String)settings.ntripClient_CasterHost); + settingsFile.println("ntripClient_CasterPort=" + (String)settings.ntripClient_CasterPort); + settingsFile.println("ntripClient_CasterUser=" + (String)settings.ntripClient_CasterUser); + settingsFile.println("ntripClient_CasterUserPW=" + (String)settings.ntripClient_CasterUserPW); + settingsFile.println("ntripClient_MountPoint=" + (String)settings.ntripClient_MountPoint); + settingsFile.println("ntripClient_MountPointPW=" + (String)settings.ntripClient_MountPointPW); + settingsFile.println("ntripClient_wifiSSID=" + (String)settings.ntripClient_wifiSSID); + settingsFile.println("ntripClient_wifiPW=" + (String)settings.ntripClient_wifiPW); + settingsFile.println("ntripClient_TransmitGGA=" + (String)settings.ntripClient_TransmitGGA); //Record constellation settings for (int x = 0 ; x < MAX_CONSTELLATIONS ; x++) @@ -506,9 +514,9 @@ bool parseLine(char* str) { } } - // log_d("settingName: %s", settingName); - // log_d("settingValue: %s", settingValue); - // log_d("d: %0.3f", d); + //log_d("settingName: %s", settingName); + //log_d("settingValue: %s", settingValue); + //log_d("d: %0.3f", d); // Get setting name if (strcmp(settingName, "sizeOfSettings") == 0) @@ -625,30 +633,6 @@ bool parseLine(char* str) { settings.dataPortBaud = d; else if (strcmp(settingName, "radioPortBaud") == 0) settings.radioPortBaud = d; - else if (strcmp(settingName, "enableNtripServer") == 0) - settings.enableNtripServer = d; - else if (strcmp(settingName, "casterHost") == 0) - strcpy(settings.casterHost, settingValue); - else if (strcmp(settingName, "casterPort") == 0) - settings.casterPort = d; - else if (strcmp(settingName, "casterUser") == 0) - strcpy(settings.casterUser, settingValue); - else if (strcmp(settingName, "casterUserPW") == 0) - strcpy(settings.casterUserPW, settingValue); - else if (strcmp(settingName, "mountPointUpload") == 0) - strcpy(settings.mountPointUpload, settingValue); - else if (strcmp(settingName, "mountPointUploadPW") == 0) - strcpy(settings.mountPointUploadPW, settingValue); - else if (strcmp(settingName, "mountPointDownload") == 0) - strcpy(settings.mountPointDownload, settingValue); - else if (strcmp(settingName, "mountPointDownloadPW") == 0) - strcpy(settings.mountPointDownloadPW, settingValue); - else if (strcmp(settingName, "casterTransmitGGA") == 0) - settings.casterTransmitGGA = d; - else if (strcmp(settingName, "wifiSSID") == 0) - strcpy(settings.wifiSSID, settingValue); - else if (strcmp(settingName, "wifiPW") == 0) - strcpy(settings.wifiPW, settingValue); else if (strcmp(settingName, "surveyInStartingAccuracy") == 0) settings.surveyInStartingAccuracy = d; else if (strcmp(settingName, "measurementRate") == 0) @@ -761,6 +745,44 @@ bool parseLine(char* str) { } else if (strcmp(settingName, "profileName") == 0) strcpy(settings.profileName, settingValue); + else if (strcmp(settingName, "enableNtripServer") == 0) + settings.enableNtripServer = d; + else if (strcmp(settingName, "ntripServer_CasterHost") == 0) + strcpy(settings.ntripServer_CasterHost, settingValue); + else if (strcmp(settingName, "ntripServer_CasterPort") == 0) + settings.ntripServer_CasterPort = d; + else if (strcmp(settingName, "ntripServer_CasterUser") == 0) + strcpy(settings.ntripServer_CasterUser, settingValue); + else if (strcmp(settingName, "ntripServer_CasterUserPW") == 0) + strcpy(settings.ntripServer_CasterUserPW, settingValue); + else if (strcmp(settingName, "ntripServer_MountPoint") == 0) + strcpy(settings.ntripServer_MountPoint, settingValue); + else if (strcmp(settingName, "ntripServer_MountPointPW") == 0) + strcpy(settings.ntripServer_MountPointPW, settingValue); + else if (strcmp(settingName, "ntripServer_wifiSSID") == 0) + strcpy(settings.ntripServer_wifiSSID, settingValue); + else if (strcmp(settingName, "ntripServer_wifiPW") == 0) + strcpy(settings.ntripServer_wifiPW, settingValue); + else if (strcmp(settingName, "enableNtripClient") == 0) + settings.enableNtripClient = d; + else if (strcmp(settingName, "ntripClient_CasterHost") == 0) + strcpy(settings.ntripClient_CasterHost, settingValue); + else if (strcmp(settingName, "ntripClient_CasterPort") == 0) + settings.ntripClient_CasterPort = d; + else if (strcmp(settingName, "ntripClient_CasterUser") == 0) + strcpy(settings.ntripClient_CasterUser, settingValue); + else if (strcmp(settingName, "ntripClient_CasterUserPW") == 0) + strcpy(settings.ntripClient_CasterUserPW, settingValue); + else if (strcmp(settingName, "ntripClient_MountPoint") == 0) + strcpy(settings.ntripClient_MountPoint, settingValue); + else if (strcmp(settingName, "ntripClient_MountPointPW") == 0) + strcpy(settings.ntripClient_MountPointPW, settingValue); + else if (strcmp(settingName, "ntripClient_wifiSSID") == 0) + strcpy(settings.ntripClient_wifiSSID, settingValue); + else if (strcmp(settingName, "ntripClient_wifiPW") == 0) + strcpy(settings.ntripClient_wifiPW, settingValue); + else if (strcmp(settingName, "ntripClient_TransmitGGA") == 0) + settings.ntripClient_TransmitGGA = d; //Check for bulk settings (constellations and message rates) //Must be last on else list @@ -805,7 +827,7 @@ bool parseLine(char* str) { settings.ubxMessages[x].msgRate = d; updateZEDSettings = true; } - + knownSetting = true; break; } @@ -815,7 +837,7 @@ bool parseLine(char* str) { //Last catch if (knownSetting == false) { - Serial.printf("Unknown setting %s on line: %s\r\n", settingName, str); + Serial.printf("Unknown setting %s\r\n", settingName); } } diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index 4c0565d31..841b4cf9a 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -40,15 +40,15 @@ Enable various debug outputs sent over BT TODO: - Add mountPointDownload and PWDownload to AP config - Add casterTransmitGGA to AP config - Add casterUser/PW to AP config + Add ntripServer_MountPoint and PWDownload to AP config + Add ntripClient_TransmitGGA to AP config + Add ntripServer_CasterUser/PW to AP config Add maxLogLength_minutes to AP config */ const int FIRMWARE_VERSION_MAJOR = 1; -const int FIRMWARE_VERSION_MINOR = 11; +const int FIRMWARE_VERSION_MINOR = 12; #define COMPILE_WIFI //Comment out to remove all WiFi functionality #define COMPILE_BT //Comment out to disable all Bluetooth @@ -106,7 +106,6 @@ int pin_radio_rts; //LittleFS for storing settings for different user profiles //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #include -#define FORMAT_LITTLEFS_IF_FAILED true const char *rtkProfileSettings = "SFERTK"; //Holds the profileNumber const char *rtkSettings[] = {"SFERTK_0", "SFERTK_1", "SFERTK_2", "SFERTK_3"}; //User profiles @@ -153,8 +152,11 @@ uint32_t sdUsedSpaceMB = 0; #ifdef COMPILE_WIFI #include #include "esp_wifi.h" //Needed for init/deinit of resources to free up RAM +#include "base64.h" //Built-in ESP32 library. Needed for NTRIP Client credential encoding. + +WiFiClient ntripServer; // The WiFi connection to the NTRIP caster. We use this to push local RTCM to the caster. +WiFiClient ntripClient; // The WiFi connection to the NTRIP caster. We use this to obtain RTCM from the caster. -WiFiClient caster; #endif unsigned long lastServerSent_ms = 0; //Time of last data pushed to caster @@ -422,6 +424,8 @@ int binBytesLastUpdate = 0; //Allows websocket notification to be sent every 100 bool updateZEDSettings = false; //If settings from file are different from LittleFS, config the ZED bool firstPowerOn = true; //After boot, apply new settings to ZED if user switches between base or rover unsigned long splashStart = 0; //Controls how long the splash is displayed for. Currently min of 2s. +unsigned long clientWiFiStartTime = 0; //If we cannot connect to local wifi for NTRIP client, give up/go to Rover after 8 seconds +bool restartRover = false; //If user modifies any NTRIP Client settings, we need to restart the rover unsigned long startTime = 0; //Used for checking longest running functions //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -488,6 +492,8 @@ void loop() updateSerial(); //Menu system via ESP32 USB connection + updateNTRIPClient(); //Move any available incoming NTRIP to ZED + //Convert current system time to minutes. This is used in F9PSerialReadTask()/updateLogs() to see if we are within max log window. systemTime_minutes = millis() / 1000L / 60; diff --git a/Firmware/RTK_Surveyor/Rover.ino b/Firmware/RTK_Surveyor/Rover.ino index 6b8d9bc66..e36775d5e 100644 --- a/Firmware/RTK_Surveyor/Rover.ino +++ b/Firmware/RTK_Surveyor/Rover.ino @@ -349,3 +349,60 @@ void storeHPdata(UBX_NAV_HPPOSLLH_data_t *ubxDataStruct) longitude = ((double)ubxDataStruct->lon) / 10000000.0; longitude += ((double)ubxDataStruct->lonHp) / 1000000000.0; } + +//Used during Rover+WiFi NTRIP Client mode to provide caster with GGA sentence every 10 seconds +void pushGPGGA(NMEA_GGA_data_t *nmeaData) +{ + //Provide the caster with our current position as needed + if ((ntripClient.connected() == true) && (settings.ntripClient_TransmitGGA == true)) + { + log_d("Pushing GGA to server: %s", nmeaData->nmea); //nmea is printable (NULL-terminated) and already has \r\n on the end + + ntripClient.print((const char *)nmeaData->nmea); //Push our current GGA sentence to caster + } +} + +//Check for the arrival of any correction data. Push it to the GNSS. +//Stop task if the connection has dropped or if we receive no data for maxTimeBeforeHangup_ms +void updateNTRIPClient() +{ + if (online.ntripClient == true) + { + if (ntripClient.connected() == true) // Check that the connection is still open + { + uint8_t rtcmData[512 * 4]; //Most incoming data is around 500 bytes but may be larger + size_t rtcmCount = 0; + + //Collect any available RTCM data + while (ntripClient.available()) + { + rtcmData[rtcmCount++] = ntripClient.read(); + if (rtcmCount == sizeof(rtcmData)) + break; + } + + if (rtcmCount > 0) + { + lastReceivedRTCM_ms = millis(); + + //Push RTCM to GNSS module over I2C + i2cGNSS.pushRawData(rtcmData, rtcmCount); + + //log_d("Pushed %d RTCM bytes to ZED", rtcmCount); + } + } + else + { + Serial.println(F("NTRIP Client connection dropped")); + online.ntripClient = false; + } + + //Timeout if we don't have new data for maxTimeBeforeHangup_ms + if ((millis() - lastReceivedRTCM_ms) > maxTimeBeforeHangup_ms) + { + Serial.println(F("NTRIP Client timeout")); + ntripClient.stop(); + online.ntripClient = false; + } + } +} diff --git a/Firmware/RTK_Surveyor/SD.ino b/Firmware/RTK_Surveyor/SD.ino index 49f79fae7..4d2692a68 100644 --- a/Firmware/RTK_Surveyor/SD.ino +++ b/Firmware/RTK_Surveyor/SD.ino @@ -48,7 +48,7 @@ bool sdPresent(void) //Sending clocks while card power stabilizes... deselectCard(); // always make sure - for (byte i = 0; i < 10; i++) // send several clocks while card power stabilizes + for (byte i = 0; i < 30; i++) // send several clocks while card power stabilizes xchg(0xff); //Sending CMD0 - GO IDLE... @@ -106,7 +106,7 @@ byte sdSendCommand(byte command, unsigned long arg) if (command == SD_SEND_IF_COND) crc = 0x87; // special case, have to use different CRC xchg(crc); // send final byte - for (int i = 0; i < 10; i++) // loop until timeout or response + for (int i = 0; i < 30; i++) // loop until timeout or response { response = xchg(0xFF); if ((response & 0x80) == 0) break; // high bit cleared means we got a response diff --git a/Firmware/RTK_Surveyor/States.ino b/Firmware/RTK_Surveyor/States.ino index 571a887f2..7589387f5 100644 --- a/Firmware/RTK_Surveyor/States.ino +++ b/Firmware/RTK_Surveyor/States.ino @@ -25,12 +25,12 @@ void updateSystemState() { case (STATE_ROVER_NOT_STARTED): { - if(online.gnss == false) + if (online.gnss == false) { firstRoverStart = false; //If GNSS is offline, we still need to allow button use return; } - + if (productVariant == RTK_SURVEYOR) { digitalWrite(pin_baseStatusLED, LOW); @@ -64,7 +64,18 @@ void updateSystemState() displayRoverSuccess(500); - changeState(STATE_ROVER_NO_FIX); + if (settings.enableNtripClient == false) + changeState(STATE_ROVER_NO_FIX); + else + { + //Turn off Bluetooth and turn on WiFi + stopBluetooth(); + startClientWiFi(); + clientWiFiStartTime = millis(); + + changeState(STATE_ROVER_CLIENT_WIFI_STARTED); + } + firstRoverStart = false; //Do not allow entry into test menu again } break; @@ -109,9 +120,178 @@ void updateSystemState() } break; + case (STATE_ROVER_CLIENT_WIFI_STARTED): + { + if (millis() - clientWiFiStartTime > 8000) + changeState(STATE_ROVER_NO_FIX); //Give up and move to normal Rover mode + +#ifdef COMPILE_WIFI + byte wifiStatus = WiFi.status(); + if (wifiStatus == WL_CONNECTED) + { + radioState = WIFI_CONNECTED; + + // Set the Main Talker ID to "GP". The NMEA GGA messages will be GPGGA instead of GNGGA + i2cGNSS.setMainTalkerID(SFE_UBLOX_MAIN_TALKER_ID_GP); + + i2cGNSS.setNMEAGPGGAcallbackPtr(&pushGPGGA); // Set up the callback for GPGGA + + i2cGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C, 10); // Tell the module to output GGA every 10 seconds + + changeState(STATE_ROVER_CLIENT_WIFI_CONNECTED); + } + else + { + Serial.print(F("WiFi Status: ")); + switch (wifiStatus) { + case WL_NO_SSID_AVAIL: + Serial.printf("SSID '%s' not detected\n\r", settings.ntripClient_wifiSSID); + break; + case WL_NO_SHIELD: Serial.println(F("WL_NO_SHIELD")); break; + case WL_IDLE_STATUS: Serial.println(F("WL_IDLE_STATUS")); break; + case WL_SCAN_COMPLETED: Serial.println(F("WL_SCAN_COMPLETED")); break; + case WL_CONNECTED: Serial.println(F("WL_CONNECTED")); break; + case WL_CONNECT_FAILED: Serial.println(F("WL_CONNECT_FAILED")); break; + case WL_CONNECTION_LOST: Serial.println(F("WL_CONNECTION_LOST")); break; + case WL_DISCONNECTED: Serial.println(F("WL_DISCONNECTED")); break; + } + } +#endif + } + break; + + case (STATE_ROVER_CLIENT_WIFI_CONNECTED): + { + //Open connection to caster service +#ifdef COMPILE_WIFI + if (ntripClient.connect(settings.ntripClient_CasterHost, settings.ntripClient_CasterPort) == true) //Attempt connection + { + Serial.printf("Connected to %s:%d\n\r", settings.ntripClient_CasterHost, settings.ntripClient_CasterPort); + + // Set up the server request (GET) + const int SERVER_BUFFER_SIZE = 512; + char serverRequest[SERVER_BUFFER_SIZE]; + snprintf(serverRequest, + SERVER_BUFFER_SIZE, + "GET /%s HTTP/1.0\r\nUser-Agent: NTRIP SparkFun SparkFun_RTK_%s_v%d.%d\r\n", + settings.ntripClient_MountPoint, platformPrefix, FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR); + + // Set up the credentials + char credentials[512]; + if (strlen(settings.ntripClient_CasterUser) == 0) + { + strncpy(credentials, "Accept: */*\r\nConnection: close\r\n", sizeof(credentials)); + } + else + { + //Pass base64 encoded user:pw + char userCredentials[sizeof(settings.ntripClient_CasterUser) + sizeof(settings.ntripClient_CasterUserPW) + 1]; //The ':' takes up a spot + snprintf(userCredentials, sizeof(userCredentials), "%s:%s", settings.ntripClient_CasterUser, settings.ntripClient_CasterUserPW); + + Serial.print(F("Sending credentials: ")); + Serial.println(userCredentials); + + //Encode with ESP32 built-in library + base64 b; + String strEncodedCredentials = b.encode(userCredentials); + char encodedCredentials[strEncodedCredentials.length() + 1]; + strEncodedCredentials.toCharArray(encodedCredentials, sizeof(encodedCredentials)); //Convert String to char array + + snprintf(credentials, sizeof(credentials), "Authorization: Basic %s\r\n", encodedCredentials); + } + + // Add the encoded credentials to the server request + strncat(serverRequest, credentials, SERVER_BUFFER_SIZE - 1); + strncat(serverRequest, "\r\n", SERVER_BUFFER_SIZE - 1); + + Serial.print(F("serverRequest size: ")); + Serial.print(strlen(serverRequest)); + Serial.print(F(" of ")); + Serial.print(sizeof(serverRequest)); + Serial.println(F(" bytes available")); + + // Send the server request + Serial.println(F("Sending server request: ")); + Serial.println(serverRequest); + ntripClient.write(serverRequest, strlen(serverRequest)); + + casterResponseWaitStartTime = millis(); + + changeState(STATE_ROVER_CLIENT_STARTED); + } +#endif + } + break; + + case (STATE_ROVER_CLIENT_STARTED): + { +#ifdef COMPILE_WIFI + //Check if caster service responded + if (ntripClient.available() == 0) + { + if (millis() - casterResponseWaitStartTime > 5000) + { + Serial.println(F("Caster failed to respond. Do you have your caster address and port correct?")); + ntripClient.stop(); + + stopWiFi(); //Turn off WiFi and release all resources + startBluetooth(); //Turn on Bluetooth with 'Rover' name + + changeState(STATE_ROVER_NO_FIX); //Start rover without WiFi + } + } + else + { + //Check reply + int connectionResult = 0; + char response[512]; + size_t responseSpot = 0; + while (ntripClient.available()) // Read bytes from the caster and store them + { + if (responseSpot == sizeof(response) - 1) // Exit the loop if we get too much data + break; + + response[responseSpot++] = ntripClient.read(); + + if (connectionResult == 0) // Only print success/fail once + { + if (strstr(response, "200") != NULL) //Look for '200 OK' + connectionResult = 200; + if (strstr(response, "401") != NULL) //Look for '401 Unauthorized' + connectionResult = 401; + } + } + response[responseSpot] = '\0'; // NULL-terminate the response + + if (connectionResult != 200) + { + Serial.printf("Caster responded with bad news: %s. Are you sure your caster credentials are correct?\n\r", response); + ntripClient.stop(); + + stopWiFi(); //Turn off WiFi and release all resources + startBluetooth(); //Turn on Bluetooth with 'Rover' name + + changeState(STATE_ROVER_NO_FIX); //Start rover without WiFi + } + else + { + log_d("Connected to caster"); + + lastReceivedRTCM_ms = millis(); //Reset timeout + + //We don't use a task because we use I2C hardware (and don't have a semphore). + online.ntripClient = true; + + changeState(STATE_ROVER_NO_FIX); //Start rover *with* WiFi + } + } +#endif + } + break; + case (STATE_BASE_NOT_STARTED): { - if(online.gnss == false) + if (online.gnss == false) { firstRoverStart = false; //If GNSS is offline, we still need to allow button use return; @@ -245,7 +425,7 @@ void updateSystemState() { //Turn off Bluetooth and turn on WiFi stopBluetooth(); - startWiFi(); + startServerWiFi(); changeState(STATE_BASE_TEMP_WIFI_STARTED); } @@ -268,7 +448,7 @@ void updateSystemState() Serial.print(F("WiFi Status: ")); switch (wifiStatus) { case WL_NO_SSID_AVAIL: - Serial.printf("SSID '%s' not detected\n\r", settings.wifiSSID); + Serial.printf("SSID '%s' not detected\n\r", settings.ntripServer_wifiSSID); break; case WL_NO_SHIELD: Serial.println(F("WL_NO_SHIELD")); break; case WL_IDLE_STATUS: Serial.println(F("WL_IDLE_STATUS")); break; @@ -278,7 +458,6 @@ void updateSystemState() case WL_CONNECTION_LOST: Serial.println(F("WL_CONNECTION_LOST")); break; case WL_DISCONNECTED: Serial.println(F("WL_DISCONNECTED")); break; } - delay(500); } #endif } @@ -297,20 +476,20 @@ void updateSystemState() { //Open connection to caster service #ifdef COMPILE_WIFI - if (caster.connect(settings.casterHost, settings.casterPort) == true) //Attempt connection + if (ntripServer.connect(settings.ntripServer_CasterHost, settings.ntripServer_CasterPort) == true) //Attempt connection { changeState(STATE_BASE_TEMP_CASTER_STARTED); - Serial.printf("Connected to %s:%d\n\r", settings.casterHost, settings.casterPort); + Serial.printf("Connected to %s:%d\n\r", settings.ntripServer_CasterHost, settings.ntripServer_CasterPort); const int SERVER_BUFFER_SIZE = 512; char serverBuffer[SERVER_BUFFER_SIZE]; snprintf(serverBuffer, SERVER_BUFFER_SIZE, "SOURCE %s /%s\r\nSource-Agent: NTRIP SparkFun_RTK_%s/v%d.%d\r\n\r\n", - settings.mountPointUploadPW, settings.mountPointUpload, platformPrefix, FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR); + settings.ntripServer_MountPointPW, settings.ntripServer_MountPoint, platformPrefix, FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR); //Serial.printf("Sending credentials:\n%s\n\r", serverBuffer); - caster.write(serverBuffer, strlen(serverBuffer)); + ntripServer.write(serverBuffer, strlen(serverBuffer)); casterResponseWaitStartTime = millis(); } @@ -324,12 +503,12 @@ void updateSystemState() { #ifdef COMPILE_WIFI //Check if caster service responded - if (caster.available() == 0) + if (ntripServer.available() == 0) { if (millis() - casterResponseWaitStartTime > 5000) { Serial.println(F("Caster failed to respond. Do you have your caster address and port correct?")); - caster.stop(); + ntripServer.stop(); changeState(STATE_BASE_TEMP_WIFI_CONNECTED); //Return to previous state } @@ -340,9 +519,9 @@ void updateSystemState() bool connectionSuccess = false; char response[512]; int responseSpot = 0; - while (caster.available()) + while (ntripServer.available()) { - response[responseSpot++] = caster.read(); + response[responseSpot++] = ntripServer.read(); if (strstr(response, "200") != NULL) //Look for 'ICY 200 OK' connectionSuccess = true; if (responseSpot == 512 - 1) break; @@ -380,7 +559,7 @@ void updateSystemState() cyclePositionLEDs(); #ifdef COMPILE_WIFI - if (caster.connected() == false) + if (ntripServer.connected() == false) { Serial.println(F("Caster no longer connected. Reconnecting...")); changeState(STATE_BASE_TEMP_WIFI_CONNECTED); //Return to 2 earlier states to try to reconnect @@ -418,7 +597,7 @@ void updateSystemState() { //Turn off Bluetooth and turn on WiFi stopBluetooth(); - startWiFi(); + startServerWiFi(); rtcmPacketsSent = 0; //Reset any previous number @@ -443,7 +622,7 @@ void updateSystemState() Serial.print(F("WiFi Status: ")); switch (wifiStatus) { case WL_NO_SSID_AVAIL: - Serial.printf("SSID '%s' not detected\n\r", settings.wifiSSID); + Serial.printf("SSID '%s' not detected\n\r", settings.ntripServer_wifiSSID); break; case WL_NO_SHIELD: Serial.println(F("WL_NO_SHIELD")); break; case WL_IDLE_STATUS: Serial.println(F("WL_IDLE_STATUS")); break; @@ -471,20 +650,20 @@ void updateSystemState() { #ifdef COMPILE_WIFI //Open connection to caster service - if (caster.connect(settings.casterHost, settings.casterPort) == true) //Attempt connection + if (ntripServer.connect(settings.ntripServer_CasterHost, settings.ntripServer_CasterPort) == true) //Attempt connection { changeState(STATE_BASE_FIXED_CASTER_STARTED); - Serial.printf("Connected to %s:%d\n\r", settings.casterHost, settings.casterPort); + Serial.printf("Connected to %s:%d\n\r", settings.ntripServer_CasterHost, settings.ntripServer_CasterPort); const int SERVER_BUFFER_SIZE = 512; char serverBuffer[SERVER_BUFFER_SIZE]; snprintf(serverBuffer, SERVER_BUFFER_SIZE, "SOURCE %s /%s\r\nSource-Agent: NTRIP SparkFun_RTK_%s/v%d.%d\r\n\r\n", - settings.mountPointUploadPW, settings.mountPointUpload, platformPrefix, FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR); + settings.ntripServer_MountPointPW, settings.ntripServer_MountPoint, platformPrefix, FIRMWARE_VERSION_MAJOR, FIRMWARE_VERSION_MINOR); //Serial.printf("Sending credentials:\n%s\n\r", serverBuffer); - caster.write(serverBuffer, strlen(serverBuffer)); + ntripServer.write(serverBuffer, strlen(serverBuffer)); casterResponseWaitStartTime = millis(); } @@ -498,12 +677,12 @@ void updateSystemState() { #ifdef COMPILE_WIFI //Check if caster service responded - if (caster.available() < 10) + if (ntripServer.available() < 10) { if (millis() - casterResponseWaitStartTime > 5000) { Serial.println(F("Caster failed to respond. Do you have your caster address and port correct?")); - caster.stop(); + ntripServer.stop(); delay(10); //Yield to RTOS changeState(STATE_BASE_FIXED_WIFI_CONNECTED); //Return to previous state @@ -515,9 +694,9 @@ void updateSystemState() bool connectionSuccess = false; char response[512]; int responseSpot = 0; - while (caster.available()) + while (ntripServer.available()) { - response[responseSpot++] = caster.read(); + response[responseSpot++] = ntripServer.read(); if (strstr(response, "200") != NULL) //Look for 'ICY 200 OK' connectionSuccess = true; if (responseSpot == 512 - 1) break; @@ -555,7 +734,7 @@ void updateSystemState() cyclePositionLEDs(); #ifdef COMPILE_WIFI - if (caster.connected() == false) + if (ntripServer.connected() == false) { changeState(STATE_BASE_FIXED_WIFI_CONNECTED); } @@ -739,6 +918,15 @@ void changeState(SystemState newState) case (STATE_ROVER_RTK_FIX): Serial.println(F("State: Rover - RTK Fix")); break; + case (STATE_ROVER_CLIENT_WIFI_STARTED): + Serial.println(F("State: Rover - Client WiFi Started")); + break; + case (STATE_ROVER_CLIENT_WIFI_CONNECTED): + Serial.println(F("State: Rover - Client WiFi Connected")); + break; + case (STATE_ROVER_CLIENT_STARTED): + Serial.println(F("State: Rover - Client Started")); + break; case (STATE_BASE_NOT_STARTED): Serial.println(F("State: Base - Not Started")); break; diff --git a/Firmware/RTK_Surveyor/System.ino b/Firmware/RTK_Surveyor/System.ino index fda9dd713..b7a53cefd 100644 --- a/Firmware/RTK_Surveyor/System.ino +++ b/Firmware/RTK_Surveyor/System.ino @@ -118,14 +118,27 @@ bool customBTstop() { //Start WiFi assuming it was previously fully released //See WiFiBluetoothSwitch sketch for more info -void startWiFi() +void startServerWiFi() { #ifdef COMPILE_WIFI wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&wifi_init_config); //Restart WiFi resources - Serial.printf("Connecting to local WiFi: %s\n\r", settings.wifiSSID); - WiFi.begin(settings.wifiSSID, settings.wifiPW); + Serial.printf("Connecting to local WiFi: %s\n\r", settings.ntripServer_wifiSSID); + WiFi.begin(settings.ntripServer_wifiSSID, settings.ntripServer_wifiPW); +#endif + + radioState = WIFI_ON_NOCONNECTION; +} + +void startClientWiFi() +{ +#ifdef COMPILE_WIFI + wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&wifi_init_config); //Restart WiFi resources + + Serial.printf("Connecting to local WiFi: %s\n\r", settings.ntripClient_wifiSSID); + WiFi.begin(settings.ntripClient_wifiSSID, settings.ntripClient_wifiPW); #endif radioState = WIFI_ON_NOCONNECTION; @@ -136,7 +149,7 @@ void startWiFi() void stopWiFi() { #ifdef COMPILE_WIFI - caster.stop(); + ntripServer.stop(); WiFi.mode(WIFI_OFF); if (radioState == WIFI_ON_NOCONNECTION || radioState == WIFI_CONNECTED) @@ -211,7 +224,7 @@ bool configureUbloxModule() response &= i2cGNSS.setPortInput(COM_PORT_UART2, COM_TYPE_RTCM3); //Set the UART2 to input RTCM if (settingPayload[INPUT_SETTING] != COM_TYPE_UBX) - response &= i2cGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX); //Set the I2C port to input UBX only + response &= i2cGNSS.setPortInput(COM_PORT_I2C, (COM_TYPE_NMEA | COM_TYPE_UBX | COM_TYPE_RTCM3)); //We don't want NMEA, but we will want to deliver RTCM over I2C //The USB port on the ZED may be used for RTCM to/from the computer (as an NTRIP caster or client) //So let's be sure all protocols are on for the USB port diff --git a/Firmware/RTK_Surveyor/Tasks.ino b/Firmware/RTK_Surveyor/Tasks.ino index fb12e3fb7..190de234c 100644 --- a/Firmware/RTK_Surveyor/Tasks.ino +++ b/Firmware/RTK_Surveyor/Tasks.ino @@ -94,8 +94,6 @@ void F9PSerialReadTask(void *e) } } - - //Control BT status LED according to radioState void updateBTled() { diff --git a/Firmware/RTK_Surveyor/form.h b/Firmware/RTK_Surveyor/form.h index 5b5b19f78..0dc18c26e 100644 --- a/Firmware/RTK_Surveyor/form.h +++ b/Firmware/RTK_Surveyor/form.h @@ -316,12 +316,12 @@ function validateFields() { checkElementValue("fixedLong", -180, 180, "Must be -180 to 180", "collapseBaseConfig"); checkElementValue("fixedAltitude", 0, 8849, "Must be 0 to 8849", "collapseBaseConfig"); - checkElementString("wifiSSID", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); - checkElementString("wifiPW", 0, 30, "Must be 0 to 30 characters", "collapseBaseConfig"); - checkElementString("casterHost", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); - checkElementValue("casterPort", 1, 99999, "Must be 1 to 99999", "collapseBaseConfig"); - checkElementString("mountPointUpload", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); - checkElementString("mountPointUploadPW", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_wifiSSID", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_wifiPW", 0, 30, "Must be 0 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_CasterHost", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementValue("ntripServer_CasterPort", 1, 99999, "Must be 1 to 99999", "collapseBaseConfig"); + checkElementString("ntripServer_MountPoint", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); + checkElementString("ntripServer_MountPointPW", 1, 30, "Must be 1 to 30 characters", "collapseBaseConfig"); //System Config checkElementValue("maxLogTime_minutes", 1, 2880, "Must be 1 to 2880", "collapseSystemConfig"); @@ -633,21 +633,21 @@ document.addEventListener("DOMContentLoaded", (event) => { ge("enableNtripServer").addEventListener("change", function () { if (ge("enableNtripServer").checked) { //Enable NTRIP inputs - ge("wifiSSID").disabled = false; - ge("wifiPW").disabled = false; - ge("casterHost").disabled = false; - ge("casterPort").disabled = false; - ge("mountPointUpload").disabled = false; - ge("mountPointUploadPW").disabled = false; + ge("ntripServer_wifiSSID").disabled = false; + ge("ntripServer_wifiPW").disabled = false; + ge("ntripServer_CasterHost").disabled = false; + ge("ntripServer_CasterPort").disabled = false; + ge("ntripServer_MountPoint").disabled = false; + ge("ntripServer_MountPointPW").disabled = false; } else { //Disable NTRIP inputs - ge("wifiSSID").disabled = true; - ge("wifiPW").disabled = true; - ge("casterHost").disabled = true; - ge("casterPort").disabled = true; - ge("mountPointUpload").disabled = true; - ge("mountPointUploadPW").disabled = true; + ge("ntripServer_wifiSSID").disabled = true; + ge("ntripServer_wifiPW").disabled = true; + ge("ntripServer_CasterHost").disabled = true; + ge("ntripServer_CasterPort").disabled = true; + ge("ntripServer_MountPoint").disabled = true; + ge("ntripServer_MountPointPW").disabled = true; } }); @@ -1582,55 +1582,55 @@ static const char *index_html = R"=====(
-
- +
- -

+ +

-
-
-
-
diff --git a/Firmware/RTK_Surveyor/icons.h b/Firmware/RTK_Surveyor/icons.h index b5dd48b13..7b6e1969b 100644 --- a/Firmware/RTK_Surveyor/icons.h +++ b/Firmware/RTK_Surveyor/icons.h @@ -3,123 +3,123 @@ //Otherwise the bitmap bitmap_converter will compress some of the bytes together uint8_t BT_Symbol [] = { -0x18, 0x30, 0xE0, 0xFF, 0xE6, 0x3C, 0x18, 0x06, 0x03, 0x01, 0x3F, 0x19, 0x0F, 0x06, + 0x18, 0x30, 0xE0, 0xFF, 0xE6, 0x3C, 0x18, 0x06, 0x03, 0x01, 0x3F, 0x19, 0x0F, 0x06, }; int BT_Symbol_Height = 14; int BT_Symbol_Width = 7; uint8_t WiFi_Symbol [] = { -0x08, 0x04, 0x12, 0x09, 0x25, 0x95, 0xD5, 0x95, 0x25, 0x09, 0x12, 0x04, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x12, 0x09, 0x25, 0x95, 0xD5, 0x95, 0x25, 0x09, 0x12, 0x04, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; int WiFi_Symbol_Height = 9; int WiFi_Symbol_Width = 13; uint8_t CrossHair [] = { -0x80, 0x80, 0xF0, 0x88, 0x84, 0x84, 0x84, 0x7F, 0x84, 0x84, 0x84, 0x88, 0xF0, 0x80, 0x80, 0x00, -0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x7F, 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, + 0x80, 0x80, 0xF0, 0x88, 0x84, 0x84, 0x84, 0x7F, 0x84, 0x84, 0x84, 0x88, 0xF0, 0x80, 0x80, 0x00, + 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x7F, 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, }; int CrossHair_Height = 15; int CrossHair_Width = 15; uint8_t CrossHairDual [] = { -0x80, 0x80, 0xF0, 0x88, 0xE4, 0x94, 0x94, 0x7F, 0x94, 0x94, 0xE4, 0x88, 0xF0, 0x80, 0x80, 0x00, -0x00, 0x07, 0x08, 0x13, 0x14, 0x14, 0x7F, 0x14, 0x14, 0x13, 0x08, 0x07, 0x00, 0x00, + 0x80, 0x80, 0xF0, 0x88, 0xE4, 0x94, 0x94, 0x7F, 0x94, 0x94, 0xE4, 0x88, 0xF0, 0x80, 0x80, 0x00, + 0x00, 0x07, 0x08, 0x13, 0x14, 0x14, 0x7F, 0x14, 0x14, 0x13, 0x08, 0x07, 0x00, 0x00, }; int CrossHairDual_Height = 15; int CrossHairDual_Width = 15; uint8_t SIV_Antenna [] = { -0x00, 0x1E, 0x62, 0x84, 0x08, 0x10, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, -0x1F, 0x12, 0x12, 0x04, 0x04, 0x05, 0x06, 0x00, + 0x00, 0x1E, 0x62, 0x84, 0x08, 0x10, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, + 0x1F, 0x12, 0x12, 0x04, 0x04, 0x05, 0x06, 0x00, }; int SIV_Antenna_Height = 13; int SIV_Antenna_Width = 12; uint8_t Rover_Fusion [] = { -0x3E, 0xC1, 0x21, 0x21, 0xC1, 0x7D, 0x55, 0x55, 0x45, 0x41, 0xC2, 0x24, 0x24, 0xC4, 0x3C, 0x00, -0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x3E, 0xC1, 0x21, 0x21, 0xC1, 0x7D, 0x55, 0x55, 0x45, 0x41, 0xC2, 0x24, 0x24, 0xC4, 0x3C, 0x00, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, }; int Rover_Fusion_Height = 9; int Rover_Fusion_Width = 15; uint8_t Rover_Fusion_Empty [] = { -0x3E, 0xC1, 0x21, 0x21, 0xC1, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC2, 0x24, 0x24, 0xC4, 0x3C, 0x00, -0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x3E, 0xC1, 0x21, 0x21, 0xC1, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC2, 0x24, 0x24, 0xC4, 0x3C, 0x00, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, }; int Rover_Fusion_Empty_Height = 9; int Rover_Fusion_Empty_Width = 15; uint8_t BaseTemporary [] = { -0x00, 0xFF, 0x99, 0x99, 0xE7, 0xCE, 0x32, 0x32, 0xE7, 0xE7, 0x99, 0x32, 0xFE, 0x00, 0x00, 0x1F, -0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, + 0x00, 0xFF, 0x99, 0x99, 0xE7, 0xCE, 0x32, 0x32, 0xE7, 0xE7, 0x99, 0x32, 0xFE, 0x00, 0x00, 0x1F, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, }; int BaseTemporary_Height = 12; int BaseTemporary_Width = 14; uint8_t BaseFixed [] = { -0x00, 0xFF, 0x01, 0x0F, 0x01, 0x8F, 0x88, 0x88, 0x8F, 0x01, 0x0F, 0x01, 0xFF, 0x00, 0x0E, 0x09, -0x08, 0x08, 0x08, 0x0F, 0x00, 0x00, 0x0F, 0x08, 0x08, 0x08, 0x09, 0x0E, + 0x00, 0xFF, 0x01, 0x0F, 0x01, 0x8F, 0x88, 0x88, 0x8F, 0x01, 0x0F, 0x01, 0xFF, 0x00, 0x0E, 0x09, + 0x08, 0x08, 0x08, 0x0F, 0x00, 0x00, 0x0F, 0x08, 0x08, 0x08, 0x09, 0x0E, }; int BaseFixed_Height = 12; int BaseFixed_Width = 14; uint8_t Battery_3 [] = { -0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, -0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, -0x0B, 0x0B, 0x08, 0x0F, 0x01, 0x01, + 0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, + 0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, + 0x0B, 0x0B, 0x08, 0x0F, 0x01, 0x01, }; int Battery_3_Height = 12; int Battery_3_Width = 19; uint8_t Battery_2 [] = { -0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x0F, 0x01, 0x01, + 0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x0F, 0x01, 0x01, }; int Battery_2_Height = 12; int Battery_2_Width = 19; uint8_t Battery_1 [] = { -0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x0F, 0x01, 0x01, + 0xFF, 0x01, 0xFD, 0xFD, 0xFD, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x0F, 0x01, 0x01, }; int Battery_1_Height = 12; int Battery_1_Width = 19; uint8_t Battery_0 [] = { -0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x0F, 0x01, 0x01, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x0F, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x0F, 0x01, 0x01, }; int Battery_0_Height = 12; int Battery_0_Width = 19; uint8_t Logging_3 [] = { -0xFF, 0x01, 0x51, 0x51, 0x51, 0x51, 0x53, 0x06, 0xFC, 0x0F, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, -0x08, 0x0F, + 0xFF, 0x01, 0x51, 0x51, 0x51, 0x51, 0x53, 0x06, 0xFC, 0x0F, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x08, 0x0F, }; int Logging_3_Height = 12; int Logging_3_Width = 9; uint8_t Logging_2 [] = { -0xFF, 0x01, 0x41, 0x41, 0x41, 0x41, 0x43, 0x06, 0xFC, 0x0F, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, -0x08, 0x0F, + 0xFF, 0x01, 0x41, 0x41, 0x41, 0x41, 0x43, 0x06, 0xFC, 0x0F, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x08, 0x0F, }; int Logging_2_Height = 12; int Logging_2_Width = 9; uint8_t Logging_1 [] = { -0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0xFC, 0x0F, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, -0x08, 0x0F, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0xFC, 0x0F, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x08, 0x0F, }; int Logging_1_Height = 12; int Logging_1_Width = 9; uint8_t Logging_0 [] = { -0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0xFC, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x0F, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0xFC, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x0F, }; int Logging_0_Height = 12; int Logging_0_Width = 9; @@ -128,51 +128,57 @@ int DynamicModel_Height = 12; int DynamicModel_Width = 15; uint8_t DynamicModel_1_Portable [] = { -0x00, 0xF0, 0x00, 0xF8, 0x04, 0x34, 0x34, 0x37, 0x37, 0x04, 0xF8, 0x00, 0xF0, 0x00, 0x00, 0x00, -0x03, 0x00, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x03, 0x00, 0x00, + 0x00, 0xF0, 0x00, 0xF8, 0x04, 0x34, 0x34, 0x37, 0x37, 0x04, 0xF8, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x03, 0x00, 0x00, }; uint8_t DynamicModel_2_Stationary [] = { -0x00, 0x00, 0x00, 0x00, 0x82, 0xC6, 0x6E, 0xFE, 0x6E, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x06, 0x03, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x82, 0xC6, 0x6E, 0xFE, 0x6E, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x06, 0x03, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, }; uint8_t DynamicModel_3_Pedestrian [] = { -0x00, 0x00, 0x00, 0x00, 0x20, 0x32, 0x95, 0xF9, 0x95, 0x32, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x32, 0x95, 0xF9, 0x95, 0x32, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, }; uint8_t DynamicModel_4_Automotive [] = { -0x78, 0x84, 0x44, 0x44, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x88, 0x50, 0x50, 0x90, 0x70, 0x00, -0x01, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, + 0x78, 0x84, 0x44, 0x44, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x88, 0x50, 0x50, 0x90, 0x70, 0x00, + 0x01, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, }; uint8_t DynamicModel_5_Sea [] = { -0x00, 0x60, 0xE0, 0x3C, 0x26, 0x3C, 0x20, 0x20, 0x20, 0xA0, 0xA0, 0x20, 0xE0, 0x60, 0x00, 0x00, -0x00, 0x03, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x03, 0x00, 0x00, + 0x00, 0x60, 0xE0, 0x3C, 0x26, 0x3C, 0x20, 0x20, 0x20, 0xA0, 0xA0, 0x20, 0xE0, 0x60, 0x00, 0x00, + 0x00, 0x03, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x03, 0x00, 0x00, }; uint8_t DynamicModel_6_Airborne1g [] = { -0x00, 0xFE, 0x0C, 0xF8, 0x08, 0x08, 0x88, 0x88, 0x88, 0x28, 0x08, 0x18, 0xB0, 0xE0, 0x00, 0x00, -0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x08, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0xFE, 0x0C, 0xF8, 0x08, 0x08, 0x88, 0x88, 0x88, 0x28, 0x08, 0x18, 0xB0, 0xE0, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x08, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, }; uint8_t DynamicModel_7_Airborne2g [] = { -0x00, 0xFE, 0x0C, 0xF8, 0x08, 0x08, 0x88, 0xA8, 0x88, 0x28, 0x08, 0x18, 0xB0, 0xE0, 0x00, 0x00, -0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x08, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0xFE, 0x0C, 0xF8, 0x08, 0x08, 0x88, 0xA8, 0x88, 0x28, 0x08, 0x18, 0xB0, 0xE0, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x08, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, }; uint8_t DynamicModel_8_Airborne4g [] = { -0x00, 0xFE, 0x0C, 0xF8, 0x08, 0x28, 0x88, 0xA8, 0x88, 0x28, 0x08, 0x18, 0xB0, 0xE0, 0x00, 0x00, -0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x08, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0xFE, 0x0C, 0xF8, 0x08, 0x28, 0x88, 0xA8, 0x88, 0x28, 0x08, 0x18, 0xB0, 0xE0, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x08, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, }; uint8_t DynamicModel_9_Wrist [] = { -0x00, 0x00, 0x00, 0xE0, 0x10, 0x08, 0x4F, 0x4F, 0x4F, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x02, 0x1E, 0x1E, 0x1E, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xE0, 0x10, 0x08, 0x4F, 0x4F, 0x4F, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x1E, 0x1E, 0x1E, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, }; uint8_t DynamicModel_10_Bike [] = { -0x00, 0x80, 0x40, 0x50, 0x90, 0xB0, 0xC0, 0xC0, 0xC0, 0xA0, 0x98, 0x4C, 0x4C, 0x80, 0x00, 0x00, -0x01, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, + 0x00, 0x80, 0x40, 0x50, 0x90, 0xB0, 0xC0, 0xC0, 0xC0, 0xA0, 0x98, 0x4C, 0x4C, 0x80, 0x00, 0x00, + 0x01, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, }; + +uint8_t DownloadArrow [] = { + 0x20, 0x60, 0xC0, 0xFF, 0xFF, 0xC0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00 +}; +int DownloadArrow_Height = 9; +int DownloadArrow_Width = 8; diff --git a/Firmware/RTK_Surveyor/menuBase.ino b/Firmware/RTK_Surveyor/menuBase.ino index a0db76e72..3b26845ed 100644 --- a/Firmware/RTK_Surveyor/menuBase.ino +++ b/Firmware/RTK_Surveyor/menuBase.ino @@ -58,22 +58,22 @@ void menuBase() if (settings.enableNtripServer == true) { Serial.print(F("5) Set WiFi SSID: ")); - Serial.println(settings.wifiSSID); + Serial.println(settings.ntripServer_wifiSSID); Serial.print(F("6) Set WiFi PW: ")); - Serial.println(settings.wifiPW); + Serial.println(settings.ntripServer_wifiPW); Serial.print(F("7) Set Caster Address: ")); - Serial.println(settings.casterHost); + Serial.println(settings.ntripServer_CasterHost); Serial.print(F("8) Set Caster Port: ")); - Serial.println(settings.casterPort); + Serial.println(settings.ntripServer_CasterPort); Serial.print(F("9) Set Mountpoint: ")); - Serial.println(settings.mountPointUpload); + Serial.println(settings.ntripServer_MountPoint); Serial.print(F("10) Set Mountpoint PW: ")); - Serial.println(settings.mountPointUploadPW); + Serial.println(settings.ntripServer_MountPointPW); } Serial.println(F("x) Exit")); @@ -174,37 +174,37 @@ void menuBase() else if (incoming == 5 && settings.enableNtripServer == true) { Serial.print(F("Enter local WiFi SSID: ")); - readLine(settings.wifiSSID, sizeof(settings.wifiSSID), menuTimeoutExtended); + readLine(settings.ntripServer_wifiSSID, sizeof(settings.ntripServer_wifiSSID), menuTimeoutExtended); } else if (incoming == 6 && settings.enableNtripServer == true) { - Serial.printf("Enter password for WiFi network %s: ", settings.wifiSSID); - readLine(settings.wifiPW, sizeof(settings.wifiPW), menuTimeoutExtended); + Serial.printf("Enter password for WiFi network %s: ", settings.ntripServer_wifiSSID); + readLine(settings.ntripServer_wifiPW, sizeof(settings.ntripServer_wifiPW), menuTimeoutExtended); } else if (incoming == 7 && settings.enableNtripServer == true) { Serial.print(F("Enter new Caster Address: ")); - readLine(settings.casterHost, sizeof(settings.casterHost), menuTimeoutExtended); + readLine(settings.ntripServer_CasterHost, sizeof(settings.ntripServer_CasterHost), menuTimeoutExtended); } else if (incoming == 8 && settings.enableNtripServer == true) { Serial.print(F("Enter new Caster Port: ")); - int casterPort = getNumber(menuTimeoutExtended); //Timeout after x seconds - if (casterPort < 1 || casterPort > 99999) //Arbitrary 99k max port # + int ntripServer_CasterPort = getNumber(menuTimeoutExtended); //Timeout after x seconds + if (ntripServer_CasterPort < 1 || ntripServer_CasterPort > 99999) //Arbitrary 99k max port # Serial.println(F("Error: Caster Port out of range")); else - settings.casterPort = casterPort; //Recorded to NVM and file at main menu exit + settings.ntripServer_CasterPort = ntripServer_CasterPort; //Recorded to NVM and file at main menu exit } else if (incoming == 9 && settings.enableNtripServer == true) { Serial.print(F("Enter new Mount Point: ")); - readLine(settings.mountPointUpload, sizeof(settings.mountPointUpload), menuTimeoutExtended); + readLine(settings.ntripServer_MountPoint, sizeof(settings.ntripServer_MountPoint), menuTimeoutExtended); } else if (incoming == 10 && settings.enableNtripServer == true) { - Serial.printf("Enter password for Mount Point %s: ", settings.mountPointUpload); - readLine(settings.mountPointUploadPW, sizeof(settings.mountPointUploadPW), menuTimeoutExtended); + Serial.printf("Enter password for Mount Point %s: ", settings.ntripServer_MountPoint); + readLine(settings.ntripServer_MountPointPW, sizeof(settings.ntripServer_MountPointPW), menuTimeoutExtended); } else if (incoming == STATUS_PRESSED_X) break; diff --git a/Firmware/RTK_Surveyor/menuGNSS.ino b/Firmware/RTK_Surveyor/menuGNSS.ino index df0649319..18cf778fe 100644 --- a/Firmware/RTK_Surveyor/menuGNSS.ino +++ b/Firmware/RTK_Surveyor/menuGNSS.ino @@ -2,6 +2,10 @@ //Update rate, constellations, etc void menuGNSS() { + int menuTimeoutExtended = 30; //Increase time needed for complex data entry (mount point ID, caster credentials, etc). + + restartRover = false; //If user modifies any NTRIP settings, we need to restart the rover + while (1) { Serial.println(); @@ -57,6 +61,41 @@ void menuGNSS() Serial.println(F("4) Set Constellations ")); + Serial.print(F("5) Toggle NTRIP Client: ")); + if (settings.enableNtripClient == true) Serial.println(F("Enabled")); + else Serial.println(F("Disabled")); + + if (settings.enableNtripClient == true) + { + Serial.print(F("6) Set WiFi SSID: ")); + Serial.println(settings.ntripClient_wifiSSID); + + Serial.print(F("7) Set WiFi PW: ")); + Serial.println(settings.ntripClient_wifiPW); + + Serial.print(F("8) Set Caster Address: ")); + Serial.println(settings.ntripClient_CasterHost); + + Serial.print(F("9) Set Caster Port: ")); + Serial.println(settings.ntripClient_CasterPort); + + Serial.print(F("10) Set Caster User Name: ")); + Serial.println(settings.ntripClient_CasterUser); + + Serial.print(F("11) Set Caster User Password: ")); + Serial.println(settings.ntripClient_CasterUserPW); + + Serial.print(F("12) Set Mountpoint: ")); + Serial.println(settings.ntripClient_MountPoint); + + Serial.print(F("13) Set Mountpoint PW: ")); + Serial.println(settings.ntripClient_MountPointPW); + + Serial.print(F("14) Toggle sending GGA Location to Caster: ")); + if (settings.ntripClient_TransmitGGA == true) Serial.println(F("Enabled")); + else Serial.println(F("Disabled")); + } + Serial.println(F("x) Exit")); int incoming = getNumber(menuTimeout); //Timeout after x seconds @@ -118,6 +157,69 @@ void menuGNSS() { menuConstellations(); } + else if (incoming == 5) + { + settings.enableNtripClient ^= 1; + restartRover = true; + } + else if (incoming == 6 && settings.enableNtripClient == true) + { + Serial.print(F("Enter local WiFi SSID: ")); + readLine(settings.ntripClient_wifiSSID, sizeof(settings.ntripClient_wifiSSID), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 7 && settings.enableNtripClient == true) + { + Serial.printf("Enter password for WiFi network %s: ", settings.ntripClient_wifiSSID); + readLine(settings.ntripClient_wifiPW, sizeof(settings.ntripClient_wifiPW), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 8 && settings.enableNtripClient == true) + { + Serial.print(F("Enter new Caster Address: ")); + readLine(settings.ntripClient_CasterHost, sizeof(settings.ntripClient_CasterHost), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 9 && settings.enableNtripClient == true) + { + Serial.print(F("Enter new Caster Port: ")); + + int ntripClient_CasterPort = getNumber(menuTimeoutExtended); //Timeout after x seconds + if (ntripClient_CasterPort < 1 || ntripClient_CasterPort > 99999) //Arbitrary 99k max port # + Serial.println(F("Error: Caster Port out of range")); + else + settings.ntripClient_CasterPort = ntripClient_CasterPort; //Recorded to NVM and file at main menu exit + restartRover = true; + } + else if (incoming == 10 && settings.enableNtripClient == true) + { + Serial.printf("Enter user name for %s: ", settings.ntripClient_CasterHost); + readLine(settings.ntripClient_CasterUser, sizeof(settings.ntripClient_CasterUser), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 11 && settings.enableNtripClient == true) + { + Serial.printf("Enter user password for %s: ", settings.ntripClient_CasterHost); + readLine(settings.ntripClient_CasterUserPW, sizeof(settings.ntripClient_CasterUserPW), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 12 && settings.enableNtripClient == true) + { + Serial.print(F("Enter new Mount Point: ")); + readLine(settings.ntripClient_MountPoint, sizeof(settings.ntripClient_MountPoint), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 13 && settings.enableNtripClient == true) + { + Serial.printf("Enter password for Mount Point %s: ", settings.ntripClient_MountPoint); + readLine(settings.ntripClient_MountPointPW, sizeof(settings.ntripClient_MountPointPW), menuTimeoutExtended); + restartRover = true; + } + else if (incoming == 14 && settings.enableNtripClient == true) + { + settings.ntripClient_TransmitGGA ^= 1; + restartRover = true; + } else if (incoming == STATUS_PRESSED_X) break; else if (incoming == STATUS_GETNUMBER_TIMEOUT) diff --git a/Firmware/RTK_Surveyor/menuMain.ino b/Firmware/RTK_Surveyor/menuMain.ino index 849c37e7e..d5272c542 100644 --- a/Firmware/RTK_Surveyor/menuMain.ino +++ b/Firmware/RTK_Surveyor/menuMain.ino @@ -90,6 +90,9 @@ void menuMain() if (online.gnss == true) i2cGNSS.saveConfiguration(); //Save the current settings to flash and BBR on the ZED-F9P + if(restartRover == true) + requestChangeState(STATE_ROVER_NOT_STARTED); //Restart rover upon exit for latest changes to take effect + while (Serial.available()) Serial.read(); //Empty buffer of any newline chars } @@ -208,12 +211,11 @@ void factoryReset() { displaySytemReset(); //Display friendly message on OLED - LittleFS.format(); + //With the given profile number, load appropriate settings file + char settingsFileName[40]; + sprintf(settingsFileName, "/%s_Settings_%d.txt", platformFilePrefix, getProfileNumber()); - //Assemble settings file name - char settingsFileName[40]; //SFE_Express_Plus_Settings.txt - strcpy(settingsFileName, platformFilePrefix); - strcat(settingsFileName, "_Settings.txt"); + LittleFS.format(); //Don't format before we getProfileNumber() //Attempt to write to file system. This avoids collisions with file writing from other functions like recordSystemSettingsToFile() and F9PSerialReadTask() if (settings.enableSD && online.microSD) diff --git a/Firmware/RTK_Surveyor/settings.h b/Firmware/RTK_Surveyor/settings.h index 2c0b4c1b3..251f3912f 100644 --- a/Firmware/RTK_Surveyor/settings.h +++ b/Firmware/RTK_Surveyor/settings.h @@ -6,12 +6,15 @@ typedef enum STATE_ROVER_FIX, STATE_ROVER_RTK_FLOAT, STATE_ROVER_RTK_FIX, + STATE_ROVER_CLIENT_WIFI_STARTED, + STATE_ROVER_CLIENT_WIFI_CONNECTED, + STATE_ROVER_CLIENT_STARTED, STATE_BASE_NOT_STARTED, STATE_BASE_TEMP_SETTLE, //User has indicated base, but current pos accuracy is too low STATE_BASE_TEMP_SURVEY_STARTED, STATE_BASE_TEMP_TRANSMITTING, STATE_BASE_TEMP_WIFI_STARTED, - STATE_BASE_TEMP_WIFI_CONNECTED, //10 + STATE_BASE_TEMP_WIFI_CONNECTED, STATE_BASE_TEMP_CASTER_STARTED, STATE_BASE_TEMP_CASTER_CONNECTED, STATE_BASE_FIXED_NOT_STARTED, @@ -21,12 +24,12 @@ typedef enum STATE_BASE_FIXED_CASTER_STARTED, STATE_BASE_FIXED_CASTER_CONNECTED, STATE_BUBBLE_LEVEL, - STATE_MARK_EVENT, //20 + STATE_MARK_EVENT, STATE_DISPLAY_SETUP, STATE_WIFI_CONFIG_NOT_STARTED, STATE_WIFI_CONFIG, STATE_TEST, - STATE_TESTING, //25 + STATE_TESTING, STATE_PROFILE_1, STATE_PROFILE_2, STATE_PROFILE_3, @@ -177,18 +180,6 @@ typedef struct struct_settings { double fixedAltitude = 1560.089; uint32_t dataPortBaud = 460800; //Default to 460800bps to support >10Hz update rates uint32_t radioPortBaud = 57600; //Default to 57600bps to support connection to SiK1000 radios - bool enableNtripServer = false; - char casterHost[50] = "rtk2go.com"; //It's free... - uint16_t casterPort = 2101; - char casterUser[50] = "test@test.com"; //Some free casters require auth. User must provide their own email address to use RTK2Go - char casterUserPW[50] = ""; - char mountPointUpload[50] = "bldr_dwntwn2"; - char mountPointUploadPW[50] = "WR5wRo4H"; - char mountPointDownload[50] = "bldr_SparkFun1"; - char mountPointDownloadPW[50] = ""; - bool casterTransmitGGA = true; - char wifiSSID[50] = "TRex"; - char wifiPW[50] = "parachutes"; float surveyInStartingAccuracy = 1.0; //Wait for 1m horizontal positional accuracy before starting survey in uint16_t measurementRate = 250; //Elapsed ms between GNSS measurements. 25ms to 65535ms. Default 4Hz. uint16_t navigationRate = 1; //Ratio between number of measurements and navigation solutions. Default 1 for 4Hz (with measurementRate). @@ -327,6 +318,29 @@ typedef struct struct_settings { int maxLogLength_minutes = 60 * 24; //Default to 24 hours char profileName[50] = "Default"; + //NTRIP Server + bool enableNtripServer = false; + char ntripServer_CasterHost[50] = "rtk2go.com"; //It's free... + uint16_t ntripServer_CasterPort = 2101; + char ntripServer_CasterUser[50] = "test@test.com"; //Some free casters require auth. User must provide their own email address to use RTK2Go + char ntripServer_CasterUserPW[50] = ""; + char ntripServer_MountPoint[50] = "bldr_dwntwn2"; //NTRIP Server + char ntripServer_MountPointPW[50] = "WR5wRo4H"; + char ntripServer_wifiSSID[50] = "TRex"; //NTRIP Server Wifi + char ntripServer_wifiPW[50] = "parachutes"; + + //NTRIP Client + bool enableNtripClient = false; + char ntripClient_CasterHost[50] = "rtk2go.com"; //It's free... + uint16_t ntripClient_CasterPort = 2101; + char ntripClient_CasterUser[50] = "test@test.com"; //Some free casters require auth. User must provide their own email address to use RTK2Go + char ntripClient_CasterUserPW[50] = ""; + char ntripClient_MountPoint[50] = "bldr_SparkFun1"; + char ntripClient_MountPointPW[50] = ""; + char ntripClient_wifiSSID[50] = "TRex"; //NTRIP Server Wifi + char ntripClient_wifiPW[50] = "parachutes"; + bool ntripClient_TransmitGGA = true; + } Settings; Settings settings; @@ -341,4 +355,5 @@ struct struct_online { bool rtc = false; bool battery = false; bool accelerometer = false; + bool ntripClient = false; } online; diff --git a/Graphics/DownloadArrow.bmp b/Graphics/DownloadArrow.bmp new file mode 100644 index 000000000..e9ee5b828 Binary files /dev/null and b/Graphics/DownloadArrow.bmp differ diff --git a/Graphics/icon.h b/Graphics/icon.h index 4a8fed1d1..ffc232f09 100644 --- a/Graphics/icon.h +++ b/Graphics/icon.h @@ -3,7 +3,7 @@ // http://en.radzio.dxp.pl/bitmap_converter/ //------------------------------------------------------------------------------ -const unsigned char DynamicModel-1-Portable [] = { -0x00, 0xF0, 0x00, 0xF8, 0x04, 0x34, 0x34, 0x37, 0x37, 0x04, 0xF8, 0x00, 0xF0, 0x00, 0x00, 0x00, -0x03, 0x00, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x03, 0x00, 0x00, +const unsigned char DownloadArrow [] = { +0x20, 0x60, 0xC0, 0xFF, 0xFF, 0xC0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, +0x00, 0x00, };