diff --git a/Firmware/RTK_Everywhere/States.ino b/Firmware/RTK_Everywhere/States.ino index e9614d9a7..eda7ef524 100644 --- a/Firmware/RTK_Everywhere/States.ino +++ b/Firmware/RTK_Everywhere/States.ino @@ -260,8 +260,9 @@ void stateUpdate() // Check for <1m horz accuracy before starting surveyIn char accuracy[20]; char temp[20]; - const char *units = getHpaUnits(hpa, temp, sizeof(temp), 2); - const char *accUnits = getHpaUnits(gnssGetSurveyInStartingAccuracy(), accuracy, sizeof(accuracy), 2); + const char *units = getHpaUnits(hpa, temp, sizeof(temp), 2, true); + // gnssGetSurveyInStartingAccuracy is 10m max + const char *accUnits = getHpaUnits(gnssGetSurveyInStartingAccuracy(), accuracy, sizeof(accuracy), 2, false); systemPrintf("Waiting for Horz Accuracy < %s (%s): %s%s%s%s, SIV: %d\r\n", accuracy, accUnits, temp, (accUnits != units) ? " (" : "", (accUnits != units) ? units : "", (accUnits != units) ? ")" : "", siv); @@ -313,7 +314,7 @@ void stateUpdate() else { char temp[20]; - const char *units = getHpaUnits(meanAccuracy, temp, sizeof(temp), 3); + const char *units = getHpaUnits(meanAccuracy, temp, sizeof(temp), 3, true); systemPrintf("Time elapsed: %d Accuracy (%s): %s SIV: %d\r\n", observationTime, units, temp, siv); if (observationTime > maxSurveyInWait_s) diff --git a/Firmware/RTK_Everywhere/System.ino b/Firmware/RTK_Everywhere/System.ino index 5425337d9..0edd2a570 100644 --- a/Firmware/RTK_Everywhere/System.ino +++ b/Firmware/RTK_Everywhere/System.ino @@ -369,7 +369,7 @@ void printReports() char modifiedHpa[20]; const char *hpaUnits = - getHpaUnits(hpa, modifiedHpa, sizeof(modifiedHpa), 3); // Returns string of the HPA units + getHpaUnits(hpa, modifiedHpa, sizeof(modifiedHpa), 3, true); // Returns string of the HPA units systemPrintf("Rover Accuracy (%s): %s, SIV: %d GNSS State: ", hpaUnits, modifiedHpa, gnssGetSatellitesInView()); @@ -716,44 +716,49 @@ void reportFatalError(const char *errorMsg) } } -// Returns string of the HPA units -const char *getHpaUnits(double hpa, char *buffer, int length, int decimals) +// This allows the measurementScaleTable to be alphabetised if desired +int measurementScaleToIndex(uint8_t scale) { - const char *units; - - // Return the units - if (settings.measurementScale >= MEASUREMENT_SCALE_MAX) + for (int i = 0; i < MEASUREMENT_UNITS_MAX; i++) { - units = "Unknown"; - strcpy(buffer, "Unknown"); + if (measurementScaleTable[i].measurementUnit == scale) + return i; } - else + + return -1; // This should never happen... +} + +// Returns string of the HPA units +const char *getHpaUnits(double hpa, char *buffer, int length, int decimals, bool limit) +{ + static const char unknown[] = "Unknown"; + + int i = measurementScaleToIndex(settings.measurementScale); + if (i >= 0) { - units = measurementScaleUnits[settings.measurementScale]; + const char *units = measurementScaleTable[i].measurementScale1NameShort; - // Convert the HPA value to a string - switch (settings.measurementScale) + hpa *= measurementScaleTable[i].multiplierMetersToScale1; // Scale1: m->m or m->ft + + bool limited = false; + if (limit && (hpa > measurementScaleTable[i].reportingLimitScale1)) // Limit the reported accuracy (Scale1) { - case MEASUREMENTS_IN_METERS: - snprintf(buffer, length, "%.*f", decimals, hpa); - break; + limited = true; + hpa = measurementScaleTable[i].reportingLimitScale1; + } - case MEASUREMENTS_IN_FEET_INCHES: - double inches; - double feet; - inches = hpa * INCHES_IN_A_METER; - feet = inches / 12.; - if (inches >= 36.) - snprintf(buffer, length, "%.*f", decimals, feet); - else - { - units = "in"; - snprintf(buffer, length, "%.*f", decimals, inches); - } - break; + if (hpa <= measurementScaleTable[i].changeFromScale1To2At) // Scale2: m->m or ft->in + { + hpa *= measurementScaleTable[i].multiplierScale1To2; + units = measurementScaleTable[i].measurementScale2NameShort; } + + snprintf(buffer, length, "%s%.*f", limited ? "> " : "", decimals, hpa); + return units; } - return units; + + strncpy(buffer, unknown, length); + return unknown; } // Helper method to convert GNSS time and date into Unix Epoch diff --git a/Firmware/RTK_Everywhere/menuSystem.ino b/Firmware/RTK_Everywhere/menuSystem.ino index 8c7725a0d..7054e141a 100644 --- a/Firmware/RTK_Everywhere/menuSystem.ino +++ b/Firmware/RTK_Everywhere/menuSystem.ino @@ -224,7 +224,8 @@ void menuSystem() systemPrintln("r) Reset all settings to default"); - systemPrintf("u) Toggle printed measurement scale: %s\r\n", measurementScaleName[settings.measurementScale]); + systemPrintf("u) Printed measurement units: %s\r\n", + measurementScaleTable[measurementScaleToIndex(settings.measurementScale)].measurementScaleName); systemPrintf("z) Set time zone offset: %02d:%02d:%02d\r\n", settings.timeZoneHours, settings.timeZoneMinutes, settings.timeZoneSeconds); @@ -294,7 +295,7 @@ void menuSystem() else if (incoming == 'u') { settings.measurementScale += 1; - if (settings.measurementScale >= MEASUREMENT_SCALE_MAX) + if (settings.measurementScale >= MEASUREMENT_UNITS_MAX) settings.measurementScale = 0; } else if (incoming == 'z') @@ -1353,7 +1354,7 @@ void printCurrentConditions() float hpa = gnssGetHorizontalAccuracy(); char temp[20]; - const char *units = getHpaUnits(hpa, temp, sizeof(temp), 3); + const char *units = getHpaUnits(hpa, temp, sizeof(temp), 3, true); systemPrintf(", HPA (%s): %s", units, temp); systemPrint(", Lat: "); diff --git a/Firmware/RTK_Everywhere/settings.h b/Firmware/RTK_Everywhere/settings.h index 2ef9e7fac..2118fd170 100644 --- a/Firmware/RTK_Everywhere/settings.h +++ b/Firmware/RTK_Everywhere/settings.h @@ -599,29 +599,34 @@ enum PeriodDisplayValues #define PERIODIC_SETTING(x) (settings.periodicDisplay & PERIODIC_MASK(x)) #define PERIODIC_TOGGLE(x) settings.periodicDisplay = settings.periodicDisplay ^ PERIODIC_MASK(x) -#define INCHES_IN_A_METER 39.37009424 +#define INCHES_IN_A_METER 39.37007874 +#define FEET_IN_A_METER 3.280839895 -enum MeasurementScale -{ - MEASUREMENTS_IN_METERS = 0, - MEASUREMENTS_IN_FEET_INCHES, - // Add new measurement scales above this line - MEASUREMENT_SCALE_MAX -}; - -const char * const measurementScaleName[] = +typedef enum { - "meters", - "feet and inches", -}; -const int measurementScaleNameEntries = sizeof(measurementScaleName) / sizeof(measurementScaleName[0]); + MEASUREMENT_UNITS_METERS = 0, + MEASUREMENT_UNITS_FEET_INCHES, + // Add new measurement units above this line + MEASUREMENT_UNITS_MAX +} measurementUnits; -const char * const measurementScaleUnits[] = +typedef struct { - "m", - "ft", + const measurementUnits measurementUnit; + const char *measurementScaleName; + const char *measurementScale1NameShort; + const char *measurementScale2NameShort; + const double multiplierMetersToScale1; + const double changeFromScale1To2At; + const double multiplierScale1To2; + const double reportingLimitScale1; +} measurementScaleEntry; + +const measurementScaleEntry measurementScaleTable[] = { + { MEASUREMENT_UNITS_METERS, "meters", "m", "m", 1.0, 1.0, 1.0, 30.0 }, + { MEASUREMENT_UNITS_FEET_INCHES, "feet and inches", "ft", "in", FEET_IN_A_METER, 3.0, 12.0, 100.0 } }; -const int measurementScaleUnitsEntries = sizeof(measurementScaleUnits) / sizeof(measurementScaleUnits[0]); +const int measurementScaleEntries = sizeof(measurementScaleTable) / sizeof(measurementScaleTable[0]); // These are the allowable messages to broadcast and log (if enabled) @@ -1190,7 +1195,7 @@ struct Settings uint8_t handleGnssDataTaskCore = 1; // Core where task should run, 0=core, 1=Arduino uint8_t handleGnssDataTaskPriority = 1; // Read from the cicular buffer and dole out to end points (SD, TCP, BT). uint8_t i2cInterruptsCore = 1; // Core where hardware is started and interrupts are assigned to, 0=core, 1=Arduino - uint8_t measurementScale = MEASUREMENTS_IN_METERS; + uint8_t measurementScale = MEASUREMENT_UNITS_METERS; bool printBootTimes = false; // Print times and deltas during boot bool printPartitionTable = false; bool printTaskStartStop = false; diff --git a/Firmware/RTK_Everywhere/support.ino b/Firmware/RTK_Everywhere/support.ino index 353d1a587..0c30a35fb 100644 --- a/Firmware/RTK_Everywhere/support.ino +++ b/Firmware/RTK_Everywhere/support.ino @@ -668,10 +668,8 @@ void verifyTables() reportFatalError("Fix platformProvisionTable to match ProductVariant"); // Verify the measurement scales - if (measurementScaleNameEntries != MEASUREMENT_SCALE_MAX) - reportFatalError("Fix measurementScaleName to match MeasurementScale"); - if (measurementScaleUnitsEntries != MEASUREMENT_SCALE_MAX) - reportFatalError("Fix measurementScaleUnits to match MeasurementScale"); + if (measurementScaleEntries != MEASUREMENT_UNITS_MAX) + reportFatalError("Fix measurementScaleTable to match measurementUnits"); // Verify the consistency of the internal tables ethernetVerifyTables();