diff --git a/docs/Battery.md b/docs/Battery.md index f6bdbd50391..e519c325410 100644 --- a/docs/Battery.md +++ b/docs/Battery.md @@ -201,7 +201,6 @@ Up to 3 battery profiles are supported. You can select the battery profile from - `vbat_max_cell_voltage` - `vbat_warning_cell_voltage` - `vbat_min_cell_voltage` -- `battery_capacity_unit` - `battery_capacity` - `battery_capacity_warning` - `battery_capacity_critical` @@ -253,7 +252,6 @@ feature BAT_PROF_AUTOSWITCH battery_profile 1 set bat_cells = 3 -set battery_capacity_unit = MAH set battery_capacity = 2200 set battery_capacity_warning = 440 set battery_capacity_critical = 220 @@ -262,7 +260,6 @@ set battery_capacity_critical = 220 battery_profile 2 set bat_cells = 4 -set battery_capacity_unit = MAH set battery_capacity = 1500 set battery_capacity_warning = 300 set battery_capacity_critical = 150 diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 4ae42184816..2109d3e08a9 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -856,7 +856,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU32(dst, currentBatteryProfile->capacity.value); sbufWriteU32(dst, currentBatteryProfile->capacity.warning); sbufWriteU32(dst, currentBatteryProfile->capacity.critical); - sbufWriteU8(dst, currentBatteryProfile->capacity.unit); + sbufWriteU8(dst, batteryMetersConfig()->capacity_unit); break; case MSP2_INAV_MISC2: @@ -895,7 +895,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU32(dst, currentBatteryProfile->capacity.value); sbufWriteU32(dst, currentBatteryProfile->capacity.warning); sbufWriteU32(dst, currentBatteryProfile->capacity.critical); - sbufWriteU8(dst, currentBatteryProfile->capacity.unit); + sbufWriteU8(dst, batteryMetersConfig()->capacity_unit); break; #ifdef USE_GPS @@ -2081,13 +2081,13 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) currentBatteryProfileMutable->capacity.value = sbufReadU32(src); currentBatteryProfileMutable->capacity.warning = sbufReadU32(src); currentBatteryProfileMutable->capacity.critical = sbufReadU32(src); - currentBatteryProfileMutable->capacity.unit = sbufReadU8(src); + batteryMetersConfigMutable()->capacity_unit = sbufReadU8(src); if ((batteryMetersConfig()->voltageSource != BAT_VOLTAGE_RAW) && (batteryMetersConfig()->voltageSource != BAT_VOLTAGE_SAG_COMP)) { batteryMetersConfigMutable()->voltageSource = BAT_VOLTAGE_RAW; return MSP_RESULT_ERROR; } - if ((currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MAH) && (currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MWH)) { - currentBatteryProfileMutable->capacity.unit = BAT_CAPACITY_UNIT_MAH; + if ((batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MAH) && (batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MWH)) { + batteryMetersConfigMutable()->capacity_unit = BAT_CAPACITY_UNIT_MAH; return MSP_RESULT_ERROR; } } else @@ -2120,13 +2120,13 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) currentBatteryProfileMutable->capacity.value = sbufReadU32(src); currentBatteryProfileMutable->capacity.warning = sbufReadU32(src); currentBatteryProfileMutable->capacity.critical = sbufReadU32(src); - currentBatteryProfileMutable->capacity.unit = sbufReadU8(src); + batteryMetersConfigMutable()->capacity_unit = sbufReadU8(src); if ((batteryMetersConfig()->voltageSource != BAT_VOLTAGE_RAW) && (batteryMetersConfig()->voltageSource != BAT_VOLTAGE_SAG_COMP)) { batteryMetersConfigMutable()->voltageSource = BAT_VOLTAGE_RAW; return MSP_RESULT_ERROR; } - if ((currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MAH) && (currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MWH)) { - currentBatteryProfileMutable->capacity.unit = BAT_CAPACITY_UNIT_MAH; + if ((batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MAH) && (batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MWH)) { + batteryMetersConfigMutable()->capacity_unit = BAT_CAPACITY_UNIT_MAH; return MSP_RESULT_ERROR; } } else diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index d9aa83c93cf..3c192495751 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -890,6 +890,12 @@ groups: condition: USE_ADC min: 0 max: 65535 + - name: battery_capacity_unit + description: "Unit used for `battery_capacity`, `battery_capacity_warning` and `battery_capacity_critical` [MAH/MWH] (milliAmpere hour / milliWatt hour)." + default_value: "MAH" + field: capacity_unit + table: bat_capacity_unit + type: uint8_t - name: current_meter_scale description: "This sets the output voltage to current scaling for the current sensor in 0.1 mV/A steps. 400 is 40mV/A such as the ACS756 sensor outputs. 183 is the setting for the uberdistro with a 0.25mOhm shunt." default_value: :target @@ -996,12 +1002,6 @@ groups: field: capacity.critical min: 0 max: 4294967295 - - name: battery_capacity_unit - description: "Unit used for `battery_capacity`, `battery_capacity_warning` and `battery_capacity_critical` [MAH/MWH] (milliAmpere hour / milliWatt hour)." - default_value: "MAH" - field: capacity.unit - table: bat_capacity_unit - type: uint8_t - name: controlrate_profile description: "Control rate profile to switch to when the battery profile is selected, 0 to disable and keep the currently selected control rate profile" default_value: 0 diff --git a/src/main/flight/rth_estimator.c b/src/main/flight/rth_estimator.c index 708c71bd1cf..e0ca0fba20d 100644 --- a/src/main/flight/rth_estimator.c +++ b/src/main/flight/rth_estimator.c @@ -222,7 +222,7 @@ float calculateRemainingDistanceBeforeRTH(bool takeWindIntoAccount) { // check requirements const bool areBatterySettingsOK = feature(FEATURE_VBAT) && feature(FEATURE_CURRENT_METER) && batteryWasFullWhenPluggedIn(); - const bool areRTHEstimatorSettingsOK = batteryMetersConfig()->cruise_power > 0 && currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH &¤tBatteryProfile->capacity.value > 0 && navConfig()->fw.cruise_speed > 0; + const bool areRTHEstimatorSettingsOK = batteryMetersConfig()->cruise_power > 0 && batteryMetersConfig()->capacity_unit == BAT_CAPACITY_UNIT_MWH && currentBatteryProfile->capacity.value > 0 && navConfig()->fw.cruise_speed > 0; const bool isNavigationOK = navigationPositionEstimateIsHealthy() && isImuHeadingValid(); if (!(areBatterySettingsOK && areRTHEstimatorSettingsOK && isNavigationOK)) { diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 34135ce2fd7..a3a298962a3 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -1780,7 +1780,7 @@ static bool osdDrawSingleElement(uint8_t item) tfp_sprintf(buff, " NA"); else if (!batteryWasFullWhenPluggedIn()) tfp_sprintf(buff, " NF"); - else if (currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH) { + else if (batteryMetersConfig()->capacity_unit == BAT_CAPACITY_UNIT_MAH) { uint8_t mah_digits = osdConfig()->mAh_precision; // Initialize to config value #ifndef DISABLE_MSP_DJI_COMPAT // IF DJICOMPAT is not supported, there's no need to check for it @@ -1803,11 +1803,11 @@ static bool osdDrawSingleElement(uint8_t item) buff[mah_digits + 1] = '\0'; unitsDrawn = true; } - } else // currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH + } else // batteryMetersConfig()->capacityUnit == BAT_CAPACITY_UNIT_MWH osdFormatCentiNumber(buff + 1, getBatteryRemainingCapacity() / 10, 0, 2, 0, 3, false); if (!unitsDrawn) { - buff[4] = currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH ? SYM_MAH : SYM_WH; + buff[4] = batteryMetersConfig()->capacity_unit == BAT_CAPACITY_UNIT_MAH ? SYM_MAH : SYM_WH; buff[5] = '\0'; } diff --git a/src/main/sensors/battery.c b/src/main/sensors/battery.c index 2ca7024694e..a29fa2e07cf 100644 --- a/src/main/sensors/battery.c +++ b/src/main/sensors/battery.c @@ -97,7 +97,7 @@ static int32_t mWhDrawn = 0; // energy (milliWatt hours) draw batteryState_e batteryState; const batteryProfile_t *currentBatteryProfile; -PG_REGISTER_ARRAY_WITH_RESET_FN(batteryProfile_t, MAX_BATTERY_PROFILE_COUNT, batteryProfiles, PG_BATTERY_PROFILES, 2); +PG_REGISTER_ARRAY_WITH_RESET_FN(batteryProfile_t, MAX_BATTERY_PROFILE_COUNT, batteryProfiles, PG_BATTERY_PROFILES, 3); void pgResetFn_batteryProfiles(batteryProfile_t *instance) { @@ -118,7 +118,6 @@ void pgResetFn_batteryProfiles(batteryProfile_t *instance) .value = SETTING_BATTERY_CAPACITY_DEFAULT, .warning = SETTING_BATTERY_CAPACITY_WARNING_DEFAULT, .critical = SETTING_BATTERY_CAPACITY_CRITICAL_DEFAULT, - .unit = SETTING_BATTERY_CAPACITY_UNIT_DEFAULT, }, .controlRateProfile = 0, @@ -167,7 +166,7 @@ void pgResetFn_batteryProfiles(batteryProfile_t *instance) } } -PG_REGISTER_WITH_RESET_TEMPLATE(batteryMetersConfig_t, batteryMetersConfig, PG_BATTERY_METERS_CONFIG, 1); +PG_REGISTER_WITH_RESET_TEMPLATE(batteryMetersConfig_t, batteryMetersConfig, PG_BATTERY_METERS_CONFIG, 2); PG_RESET_TEMPLATE(batteryMetersConfig_t, batteryMetersConfig, @@ -186,6 +185,8 @@ PG_RESET_TEMPLATE(batteryMetersConfig_t, batteryMetersConfig, .voltageSource = SETTING_BAT_VOLTAGE_SRC_DEFAULT, + .capacity_unit = SETTING_BATTERY_CAPACITY_UNIT_DEFAULT, + .cruise_power = SETTING_CRUISE_POWER_DEFAULT, .idle_power = SETTING_IDLE_POWER_DEFAULT, .rth_energy_margin = SETTING_RTH_ENERGY_MARGIN_DEFAULT, @@ -405,7 +406,7 @@ void batteryUpdate(timeUs_t timeDelta) if ((currentBatteryProfile->capacity.value > 0) && batteryFullWhenPluggedIn) { uint32_t capacityDiffBetweenFullAndEmpty = currentBatteryProfile->capacity.value - currentBatteryProfile->capacity.critical; - int32_t drawn = (currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH ? mWhDrawn : mAhDrawn); + int32_t drawn = (batteryMetersConfig()->capacity_unit == BAT_CAPACITY_UNIT_MWH ? mWhDrawn : mAhDrawn); batteryRemainingCapacity = (drawn > (int32_t)capacityDiffBetweenFullAndEmpty ? 0 : capacityDiffBetweenFullAndEmpty - drawn); } diff --git a/src/main/sensors/battery_config_structs.h b/src/main/sensors/battery_config_structs.h index 81eafef44ad..829ac8d8794 100644 --- a/src/main/sensors/battery_config_structs.h +++ b/src/main/sensors/battery_config_structs.h @@ -61,16 +61,18 @@ typedef struct batteryMetersConfig_s { #endif struct { - int16_t scale; // scale the current sensor output voltage to milliamps. Value in 1/10th mV/A - int16_t offset; // offset of the current sensor in millivolt steps - currentSensor_e type; // type of current meter used, either ADC or virtual + int16_t scale; // scale the current sensor output voltage to milliamps. Value in 1/10th mV/A + int16_t offset; // offset of the current sensor in millivolt steps + currentSensor_e type; // type of current meter used, either ADC or virtual } current; batVoltageSource_e voltageSource; - uint32_t cruise_power; // power drawn by the motor(s) at cruise throttle/speed (cW) - uint16_t idle_power; // power drawn by the system when the motor(s) are stopped (cW) - uint8_t rth_energy_margin; // Energy that should be left after RTH (%), used for remaining time/distance before RTH + batCapacityUnit_e capacity_unit; // Describes unit of capacity.value, capacity.warning and capacity.critical + + uint32_t cruise_power; // power drawn by the motor(s) at cruise throttle/speed (cW) + uint16_t idle_power; // power drawn by the system when the motor(s) are stopped (cW) + uint8_t rth_energy_margin; // Energy that should be left after RTH (%), used for remaining time/distance before RTH float throttle_compensation_weight; @@ -90,10 +92,9 @@ typedef struct batteryProfile_s { #endif struct { - uint32_t value; // mAh or mWh (see capacity.unit) - uint32_t warning; // mAh or mWh (see capacity.unit) - uint32_t critical; // mAh or mWh (see capacity.unit) - batCapacityUnit_e unit; // Describes unit of capacity.value, capacity.warning and capacity.critical + uint32_t value; // mAh or mWh (see batteryMetersConfig()->capacity_unit) + uint32_t warning; // mAh or mWh (see batteryMetersConfig()->capacity_unit) + uint32_t critical; // mAh or mWh (see batteryMetersConfig()->capacity_unit) } capacity; uint8_t controlRateProfile;