1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-20 23:05:19 +03:00

Watt Hours Drawn OSD Element and Post Flight Stat

The Watt hours used element was added per a feature request to give
another way of interpreting the battery usage. It was also added as a
post flight stat to show consumption similar to the mAh post flight
stat. This once again is just giving pilots another option that some may
find useful.
This commit is contained in:
Jon Mahoney 2022-09-19 23:36:23 -04:00
parent 8d909fbe99
commit a2d356dc78
8 changed files with 58 additions and 2 deletions

View file

@ -1360,6 +1360,7 @@ const clivalue_t valueTable[] = {
{ "osd_ah_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_ARTIFICIAL_HORIZON]) },
{ "osd_current_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_CURRENT_DRAW]) },
{ "osd_mah_drawn_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_MAH_DRAWN]) },
{ "osd_wh_drawn_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_WATT_HOURS_DRAWN]) },
{ "osd_motor_diag_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_MOTOR_DIAG]) },
{ "osd_craft_name_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_CRAFT_NAME]) },
{ "osd_display_name_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_DISPLAY_NAME]) },

View file

@ -187,6 +187,7 @@ const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
OSD_STAT_TOTAL_FLIGHTS,
OSD_STAT_TOTAL_TIME,
OSD_STAT_TOTAL_DIST,
OSD_STAT_WATT_HOURS_DRAWN,
};
// Group elements in a number of groups to reduce task scheduling overhead
@ -781,6 +782,14 @@ static bool osdDisplayStat(int statistic, uint8_t displayRow)
}
break;
case OSD_STAT_WATT_HOURS_DRAWN:
if (batteryConfig()->currentMeterSource != CURRENT_METER_NONE) {
osdPrintFloat(buff, SYM_NONE, getWhDrawn(), "", 2, true, SYM_NONE);
osdDisplayStatisticLabel(displayRow, "USED WATT HOURS", buff);
return true;
}
break;
#ifdef USE_BLACKBOX
case OSD_STAT_BLACKBOX:
if (blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) {

View file

@ -161,6 +161,7 @@ typedef enum {
OSD_TOTAL_FLIGHTS,
OSD_UP_DOWN_REFERENCE,
OSD_TX_UPLINK_POWER,
OSD_WATT_HOURS_DRAWN,
OSD_ITEM_COUNT // MUST BE LAST
} osd_items_e;
@ -200,6 +201,7 @@ typedef enum {
OSD_STAT_TOTAL_TIME,
OSD_STAT_TOTAL_DIST,
OSD_STAT_MIN_RSSI_DBM,
OSD_STAT_WATT_HOURS_DRAWN,
OSD_STAT_COUNT // MUST BE LAST
} osd_stats_e;

View file

@ -1166,6 +1166,20 @@ static void osdElementMahDrawn(osdElementParms_t *element)
tfp_sprintf(element->buff, "%4d%c", getMAhDrawn(), SYM_MAH);
}
static void osdElementWattHoursDrawn(osdElementParms_t *element)
{
const float wattHoursDrawn = getWhDrawn();
if (wattHoursDrawn < 1.0f) {
tfp_sprintf(element->buff, "%3dMWH", lrintf(wattHoursDrawn * 1000));
} else {
int wattHourWholeNumber = (int)wattHoursDrawn;
int wattHourDecimalValue = (int)((wattHoursDrawn - wattHourWholeNumber) * 100);
tfp_sprintf(element->buff, wattHourDecimalValue >= 10 ? "%3d.%2dWH" : "%3d.0%1dWH", wattHourWholeNumber, wattHourDecimalValue);
}
}
static void osdElementMainBatteryUsage(osdElementParms_t *element)
{
// Set length of indicator bar
@ -1524,6 +1538,7 @@ static const uint8_t osdElementDisplayOrder[] = {
OSD_VTX_CHANNEL,
OSD_CURRENT_DRAW,
OSD_MAH_DRAWN,
OSD_WATT_HOURS_DRAWN,
OSD_CRAFT_NAME,
OSD_ALTITUDE,
OSD_ROLL_PIDS,
@ -1610,6 +1625,7 @@ const osdElementDrawFn osdElementDrawFunction[OSD_ITEM_COUNT] = {
#endif
[OSD_CURRENT_DRAW] = osdElementCurrentDraw,
[OSD_MAH_DRAWN] = osdElementMahDrawn,
[OSD_WATT_HOURS_DRAWN] = osdElementWattHoursDrawn,
#ifdef USE_GPS
[OSD_GPS_SPEED] = osdElementGpsSpeed,
[OSD_GPS_SATS] = osdElementGpsSats,

View file

@ -75,13 +75,14 @@ static uint16_t batteryCriticalVoltage;
static uint16_t batteryWarningHysteresisVoltage;
static uint16_t batteryCriticalHysteresisVoltage;
static lowVoltageCutoff_t lowVoltageCutoff;
//
static currentMeter_t currentMeter;
static voltageMeter_t voltageMeter;
static batteryState_e batteryState;
static batteryState_e voltageState;
static batteryState_e consumptionState;
static float wattHoursDrawn;
#ifndef DEFAULT_CURRENT_METER_SOURCE
#ifdef USE_VIRTUAL_CURRENT_METER
@ -197,7 +198,6 @@ static bool isVoltageFromBat(void)
void batteryUpdatePresence(void)
{
if ((voltageState == BATTERY_NOT_PRESENT || voltageState == BATTERY_INIT) && isVoltageFromBat() && isVoltageStable()) {
// Battery has just been connected - calculate cells, warning voltages and reset state
@ -232,9 +232,18 @@ void batteryUpdatePresence(void)
batteryCriticalVoltage = 0;
batteryWarningHysteresisVoltage = 0;
batteryCriticalHysteresisVoltage = 0;
wattHoursDrawn = 0.0;
}
}
void batteryUpdateWhDrawn(void)
{
static int32_t mAhDrawnPrev = 0;
const int32_t mAhDrawnCurrent = getMAhDrawn();
wattHoursDrawn += voltageMeter.displayFiltered * (mAhDrawnCurrent - mAhDrawnPrev) / 100000.0f;
mAhDrawnPrev = mAhDrawnCurrent;
}
static void batteryUpdateVoltageState(void)
{
// alerts are currently used by beeper, osd and other subsystems
@ -317,6 +326,7 @@ void batteryUpdateStates(timeUs_t currentTimeUs)
batteryUpdateConsumptionState();
batteryUpdateLVC(currentTimeUs);
batteryState = MAX(voltageState, consumptionState);
batteryUpdateWhDrawn();
}
const lowVoltageCutoff_t *getLowVoltageCutoff(void)
@ -354,6 +364,11 @@ void batteryInit(void)
batteryState = BATTERY_INIT;
batteryCellCount = 0;
//
// Consumption
//
wattHoursDrawn = 0;
//
// voltage
//
@ -565,3 +580,8 @@ void setMAhDrawn(uint32_t mAhDrawn)
currentMeter.mAhDrawnOffset = mAhDrawn;
}
#endif
float getWhDrawn(void)
{
return wattHoursDrawn;
}

View file

@ -120,6 +120,7 @@ bool isAmperageConfigured(void);
int32_t getAmperage(void);
int32_t getAmperageLatest(void);
int32_t getMAhDrawn(void);
float getWhDrawn(void);
#ifdef USE_BATTERY_CONTINUE
bool hasUsedMAh();
void setMAhDrawn(uint32_t mAhDrawn);

View file

@ -479,6 +479,7 @@ extern "C" {
uint16_t getBatteryAverageCellVoltage() { return 420; }
int32_t getAmperage() { return 0; }
int32_t getMAhDrawn() { return 0; }
float getWhDrawn() { return 0.0; }
int32_t getEstimatedAltitudeCm() { return 0; }
int32_t getEstimatedVario() { return 0; }
int32_t blackboxGetLogNumber() { return 0; }

View file

@ -100,6 +100,7 @@ extern "C" {
uint16_t simulationBatteryVoltage;
uint32_t simulationBatteryAmperage;
uint32_t simulationMahDrawn;
float simulationWhDrawn;
int32_t simulationAltitude;
int32_t simulationVerticalSpeed;
uint16_t simulationCoreTemperature;
@ -128,6 +129,7 @@ void setDefaultSimulationState()
simulationBatteryVoltage = 1680;
simulationBatteryAmperage = 0;
simulationMahDrawn = 0;
simulationWhDrawn = 0;
simulationAltitude = 0;
simulationVerticalSpeed = 0;
simulationCoreTemperature = 0;
@ -1324,6 +1326,10 @@ extern "C" {
return simulationMahDrawn;
}
float getWhDrawn() {
return simulationWhDrawn;
}
int32_t getEstimatedAltitudeCm() {
return simulationAltitude;
}