diff --git a/src/main/config/config.c b/src/main/config/config.c index 665d3fd3c0..3461d7e2cc 100755 --- a/src/main/config/config.c +++ b/src/main/config/config.c @@ -270,6 +270,7 @@ void resetBatteryConfig(batteryConfig_t *batteryConfig) batteryConfig->vbatmaxcellvoltage = 43; batteryConfig->vbatmincellvoltage = 33; batteryConfig->vbatwarningcellvoltage = 35; + batteryConfig->vbatPidCompensation = 0; batteryConfig->currentMeterOffset = 0; batteryConfig->currentMeterScale = 400; // for Allegro ACS758LCB-100U (40mV/A) batteryConfig->batteryCapacity = 0; diff --git a/src/main/flight/mixer.c b/src/main/flight/mixer.c index ae6eb57ed8..af5dd34b64 100755 --- a/src/main/flight/mixer.c +++ b/src/main/flight/mixer.c @@ -43,6 +43,7 @@ #include "sensors/sensors.h" #include "sensors/acceleration.h" +#include "sensors/battery.h" #include "flight/mixer.h" #include "flight/failsafe.h" @@ -775,6 +776,8 @@ void mixTable(void) axisPID[ROLL] * currentMixer[i].roll + -mixerConfig->yaw_motor_direction * axisPID[YAW] * currentMixer[i].yaw; + if (batteryConfig->vbatPidCompensation) rollPitchYawMix[i] *= calculateVbatPidCompensation(); // Add voltage PID compensation + if (rollPitchYawMix[i] > rollPitchYawMixMax) rollPitchYawMixMax = rollPitchYawMix[i]; if (rollPitchYawMix[i] < rollPitchYawMixMin) rollPitchYawMixMin = rollPitchYawMix[i]; } diff --git a/src/main/io/serial_cli.c b/src/main/io/serial_cli.c index 6bd9f4c245..5bea5bea40 100644 --- a/src/main/io/serial_cli.c +++ b/src/main/io/serial_cli.c @@ -581,6 +581,7 @@ const clivalue_t valueTable[] = { { "vbat_max_cell_voltage", VAR_UINT8 | MASTER_VALUE, &masterConfig.batteryConfig.vbatmaxcellvoltage, .config.minmax = { 10, 50 } }, { "vbat_min_cell_voltage", VAR_UINT8 | MASTER_VALUE, &masterConfig.batteryConfig.vbatmincellvoltage, .config.minmax = { 10, 50 } }, { "vbat_warning_cell_voltage", VAR_UINT8 | MASTER_VALUE, &masterConfig.batteryConfig.vbatwarningcellvoltage, .config.minmax = { 10, 50 } }, + { "vbat_pid_compensation", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.batteryConfig.vbatPidCompensation, .config.lookup = { TABLE_OFF_ON } }, { "current_meter_scale", VAR_INT16 | MASTER_VALUE, &masterConfig.batteryConfig.currentMeterScale, .config.minmax = { -10000, 10000 } }, { "current_meter_offset", VAR_UINT16 | MASTER_VALUE, &masterConfig.batteryConfig.currentMeterOffset, .config.minmax = { 0, 3300 } }, { "multiwii_current_meter_output", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.batteryConfig.multiwiiCurrentMeterOutput, .config.lookup = { TABLE_OFF_ON } }, diff --git a/src/main/sensors/battery.c b/src/main/sensors/battery.c index 7419eded90..be9dc826b2 100644 --- a/src/main/sensors/battery.c +++ b/src/main/sensors/battery.c @@ -51,8 +51,6 @@ uint16_t amperageLatestADC = 0; // most recent raw reading from current ADC int32_t amperage = 0; // amperage read by current sensor in centiampere (1/100th A) int32_t mAhDrawn = 0; // milliampere hours drawn from the battery since start -batteryConfig_t *batteryConfig; - static batteryState_e batteryState; static lowpass_t lowpassFilter; @@ -207,6 +205,15 @@ void updateCurrentMeter(int32_t lastUpdateAt, rxConfig_t *rxConfig, uint16_t dea mAhDrawn = mAhdrawnRaw / (3600 * 100); } +float calculateVbatPidCompensation(void) { + float batteryScaler = 1.0f; + if (batteryConfig->vbatPidCompensation && feature(FEATURE_VBAT) && batteryCellCount > 1) { + batteryScaler = 0.2f + constrainf(batteryWarningVoltage / vbat, 0.80f, 1.0f); // Up to 20% increment. Should be fine for 3,3 to 4,2 difference + } + + return batteryScaler; +} + uint8_t calculateBatteryPercentage(void) { return (((uint32_t)vbat - (batteryConfig->vbatmincellvoltage * batteryCellCount)) * 100) / ((batteryConfig->vbatmaxcellvoltage - batteryConfig->vbatmincellvoltage) * batteryCellCount); diff --git a/src/main/sensors/battery.h b/src/main/sensors/battery.h index a836c7c1fe..9a284aa048 100644 --- a/src/main/sensors/battery.h +++ b/src/main/sensors/battery.h @@ -39,6 +39,7 @@ typedef struct batteryConfig_s { uint8_t vbatmaxcellvoltage; // maximum voltage per cell, used for auto-detecting battery voltage in 0.1V units, default is 43 (4.3V) uint8_t vbatmincellvoltage; // minimum voltage per cell, this triggers battery critical alarm, in 0.1V units, default is 33 (3.3V) uint8_t vbatwarningcellvoltage; // warning voltage per cell, this triggers battery warning alarm, in 0.1V units, default is 35 (3.5V) + uint8_t vbatPidCompensation; // Scale PIDsum to battery voltage int16_t currentMeterScale; // scale the current sensor output voltage to milliamps. Value in 1/10th mV/A uint16_t currentMeterOffset; // offset of the current sensor in millivolt steps @@ -70,9 +71,11 @@ batteryState_e getBatteryState(void); const char * getBatteryStateString(void); void updateBattery(void); void batteryInit(batteryConfig_t *initialBatteryConfig); +batteryConfig_t *batteryConfig; void updateCurrentMeter(int32_t lastUpdateAt, rxConfig_t *rxConfig, uint16_t deadband3d_throttle); int32_t currentMeterToCentiamps(uint16_t src); +float calculateVbatPidCompensation(void); uint8_t calculateBatteryPercentage(void); uint8_t calculateBatteryCapacityRemainingPercentage(void);