diff --git a/Firmware/RTK_Surveyor/AP-Config/index.html b/Firmware/RTK_Surveyor/AP-Config/index.html index 192bb1360..522d69cda 100644 --- a/Firmware/RTK_Surveyor/AP-Config/index.html +++ b/Firmware/RTK_Surveyor/AP-Config/index.html @@ -117,6 +117,42 @@

+ +
+ Profiles +
+
+ 1: 12345678901234567890123456789012345678901234567890 +
+
+ 2: 12345678901234567890123456789012345678901234567890 +
+
+ 3: 12345678901234567890123456789012345678901234567890 +
+
+ 4: 12345678901234567890123456789012345678901234567890 +
+
+ 5: 12345678901234567890123456789012345678901234567890 +
+
+ 6: 12345678901234567890123456789012345678901234567890 +
+
+ 7: 12345678901234567890123456789012345678901234567890 +
+
+ 8: 12345678901234567890123456789012345678901234567890 +
+ +
+ +
+ +

+
+
diff --git a/Firmware/RTK_Surveyor/AP-Config/src/main.js b/Firmware/RTK_Surveyor/AP-Config/src/main.js index 09c2f24f0..7ef832c45 100644 --- a/Firmware/RTK_Surveyor/AP-Config/src/main.js +++ b/Firmware/RTK_Surveyor/AP-Config/src/main.js @@ -84,6 +84,14 @@ function parseIncoming(msg) { || id.includes("zedFirmwareVersion") || id.includes("hardwareID") || id.includes("daysRemaining") + || id.includes("profile0Name") + || id.includes("profile1Name") + || id.includes("profile2Name") + || id.includes("profile3Name") + || id.includes("profile4Name") + || id.includes("profile5Name") + || id.includes("profile6Name") + || id.includes("profile7Name") ) { ge(id).innerHTML = val; } @@ -124,6 +132,7 @@ function parseIncoming(msg) { //Force element updates ge("profileNumber").dispatchEvent(new CustomEvent('change')); ge("profileName").dispatchEvent(new CustomEvent('change')); + ge("bootProfileNumber").dispatchEvent(new CustomEvent('change')); ge("measurementRateHz").dispatchEvent(new CustomEvent('change')); ge("baseTypeSurveyIn").dispatchEvent(new CustomEvent('change')); ge("baseTypeFixed").dispatchEvent(new CustomEvent('change')); @@ -208,8 +217,9 @@ function validateFields() { errorCount = 0; //Profile Config - checkElementValue("profileNumber", 1, 4, "Must be between 1 and 4", "collapseProfileConfig"); + checkElementValue("profileNumber", 1, 8, "Must be between 1 and 8", "collapseProfileConfig"); checkElementString("profileName", 1, 49, "Must be 1 to 49 characters", "collapseProfileConfig"); + checkBitMapValue("bootProfileNumber", 1, 8, "activeProfiles", "Must be an active profile between 1 and 8", "collapseProfileConfig"); //GNSS Config checkElementValue("measurementRateHz", 0.00012, 10, "Must be between 0.00012 and 10Hz", "collapseGNSSConfig"); @@ -459,6 +469,19 @@ function checkConstellations() { clearError("ubxConstellations"); } +function checkBitMapValue(id, min, max, bitMap, errorText, collapseID) { + value = ge(id).value; + mask = ge(bitMap).value; + if ((value < min) || (value > max) || ((mask & (1 << value)) == 0)) { + ge(id + 'Error').innerHTML = 'Error: ' + errorText; + ge(collapseID).classList.add('show'); + errorCount++; + } + else { + clearError(id); + } +} + function checkElementValue(id, min, max, errorText, collapseID) { value = ge(id).value; if (value < min || value > max) { diff --git a/Firmware/RTK_Surveyor/Form.ino b/Firmware/RTK_Surveyor/Form.ino index b6148ee20..57afb8edb 100644 --- a/Firmware/RTK_Surveyor/Form.ino +++ b/Firmware/RTK_Surveyor/Form.ino @@ -1,6 +1,8 @@ //Once connected to the access point for WiFi Config, the ESP32 sends current setting values in one long string to websocket //After user clicks 'save', data is validated via main.js and a long string of values is returned. +static uint8_t bootProfileNumber; + //Start webserver in AP mode void startWebServer() { @@ -280,6 +282,9 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT void createSettingsString(char* settingsCSV) { #ifdef COMPILE_AP + char tagText[32]; + char nameText[64]; + //System Info stringRecord(settingsCSV, "platformPrefix", platformPrefix); @@ -407,6 +412,15 @@ void createSettingsString(char* settingsCSV) //Profiles stringRecord(settingsCSV, "profileNumber", profileNumber + 1); stringRecord(settingsCSV, "profileName", profileNames[profileNumber]); + for (int index = 0; index < MAX_PROFILE_COUNT; index++) + { + sprintf(tagText, "profile%dName", index); + sprintf(nameText, "%d: %s", index + 1, profileNames[index]); + stringRecord(settingsCSV, tagText, nameText); + } + bootProfileNumber = profileNumber + 1; + stringRecord(settingsCSV, "bootProfileNumber", bootProfileNumber); + stringRecord(settingsCSV, "activeProfiles", activeProfiles); //New settings not yet integrated //... @@ -503,7 +517,14 @@ void updateSettingWithValue(const char *settingName, const char* settingValueStr recordProfileNumber(profileNumber); } } - + else if (strcmp(settingName, "bootProfileNumber") == 0) + { + if ((sscanf(settingValueStr, "%d", &bootProfileNumber) != 1) + || (bootProfileNumber < 1) + || (bootProfileNumber > (MAX_PROFILE_COUNT + 1))) + bootProfileNumber = 1; +Serial.printf("bootProfileNumber: %d\r\n", bootProfileNumber); + } else if (strcmp(settingName, "enableNtripServer") == 0) settings.enableNtripServer = settingValueBool; else if (strcmp(settingName, "ntripServer_CasterHost") == 0) @@ -579,6 +600,12 @@ void updateSettingWithValue(const char *settingName, const char* settingValueStr { if (newAPSettings == true) recordSystemSettings(); //If we've recieved settings, record before restart + //Determine which profile to boot + bootProfileNumber -= 1; + if (bootProfileNumber != profileNumber) + recordProfileNumber(bootProfileNumber); + + //Reboot the machine ESP.restart(); } diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index 5073a2c6b..1ceb5b23b 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -305,7 +305,7 @@ AsyncWebSocket ws("/ws"); //Because the incoming string is longer than max len, there are multiple callbacks so we //use a global to combine the incoming -#define AP_CONFIG_SETTING_SIZE 3500 +#define AP_CONFIG_SETTING_SIZE 5000 char incomingSettings[AP_CONFIG_SETTING_SIZE]; int incomingSettingsSpot = 0; unsigned long timeSinceLastIncomingSetting = 0; diff --git a/Firmware/RTK_Surveyor/form.h b/Firmware/RTK_Surveyor/form.h index 6895a50d0..5a05d8844 100644 --- a/Firmware/RTK_Surveyor/form.h +++ b/Firmware/RTK_Surveyor/form.h @@ -107,6 +107,14 @@ function parseIncoming(msg) { || id.includes("zedFirmwareVersion") || id.includes("hardwareID") || id.includes("daysRemaining") + || id.includes("profile0Name") + || id.includes("profile1Name") + || id.includes("profile2Name") + || id.includes("profile3Name") + || id.includes("profile4Name") + || id.includes("profile5Name") + || id.includes("profile6Name") + || id.includes("profile7Name") ) { ge(id).innerHTML = val; } @@ -147,6 +155,7 @@ function parseIncoming(msg) { //Force element updates ge("profileNumber").dispatchEvent(new CustomEvent('change')); ge("profileName").dispatchEvent(new CustomEvent('change')); + ge("bootProfileNumber").dispatchEvent(new CustomEvent('change')); ge("measurementRateHz").dispatchEvent(new CustomEvent('change')); ge("baseTypeSurveyIn").dispatchEvent(new CustomEvent('change')); ge("baseTypeFixed").dispatchEvent(new CustomEvent('change')); @@ -231,8 +240,9 @@ function validateFields() { errorCount = 0; //Profile Config - checkElementValue("profileNumber", 1, 4, "Must be between 1 and 4", "collapseProfileConfig"); + checkElementValue("profileNumber", 1, 8, "Must be between 1 and 8", "collapseProfileConfig"); checkElementString("profileName", 1, 49, "Must be 1 to 49 characters", "collapseProfileConfig"); + checkBitMapValue("bootProfileNumber", 1, 8, "activeProfiles", "Must be an active profile between 1 and 8", "collapseProfileConfig"); //GNSS Config checkElementValue("measurementRateHz", 0.00012, 10, "Must be between 0.00012 and 10Hz", "collapseGNSSConfig"); @@ -482,6 +492,19 @@ function checkConstellations() { clearError("ubxConstellations"); } +function checkBitMapValue(id, min, max, bitMap, errorText, collapseID) { + value = ge(id).value; + mask = ge(bitMap).value; + if ((value < min) || (value > max) || ((mask & (1 << value)) == 0)) { + ge(id + 'Error').innerHTML = 'Error: ' + errorText; + ge(collapseID).classList.add('show'); + errorCount++; + } + else { + clearError(id); + } +} + function checkElementValue(id, min, max, errorText, collapseID) { value = ge(id).value; if (value < min || value > max) { @@ -896,6 +919,42 @@ static const char *index_html = R"=====(

+ +
+ Profiles +
+
+ 1: 12345678901234567890123456789012345678901234567890 +
+
+ 2: 12345678901234567890123456789012345678901234567890 +
+
+ 3: 12345678901234567890123456789012345678901234567890 +
+
+ 4: 12345678901234567890123456789012345678901234567890 +
+
+ 5: 12345678901234567890123456789012345678901234567890 +
+
+ 6: 12345678901234567890123456789012345678901234567890 +
+
+ 7: 12345678901234567890123456789012345678901234567890 +
+
+ 8: 12345678901234567890123456789012345678901234567890 +
+ +
+ +
+ +

+
+