Skip to content

Commit c2752cf

Browse files
authored
Merge pull request #11308 from breadoven/abo_add_batt_volt_warning
Multifunction add battery voltage warnings
2 parents 1ce09df + 4e07d5c commit c2752cf

File tree

6 files changed

+66
-73
lines changed

6 files changed

+66
-73
lines changed

src/main/fc/multifunction.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,32 +45,29 @@ static void multiFunctionApply(multi_function_e selectedItem)
4545
switch (selectedItem) {
4646
case MULTI_FUNC_NONE:
4747
break;
48-
case MULTI_FUNC_1: // redisplay current warnings
49-
osdResetWarningFlags();
50-
break;
51-
case MULTI_FUNC_2: // control manual emergency landing
48+
case MULTI_FUNC_1: // control manual emergency landing
5249
checkManualEmergencyLandingControl(ARMING_FLAG(ARMED));
5350
break;
54-
case MULTI_FUNC_3: // toggle Safehome suspend
51+
case MULTI_FUNC_2: // toggle Safehome suspend
5552
#if defined(USE_SAFE_HOME)
5653
if (navConfig()->general.flags.safehome_usage_mode != SAFEHOME_USAGE_OFF) {
5754
MULTI_FUNC_FLAG(MF_SUSPEND_SAFEHOMES) ? MULTI_FUNC_FLAG_DISABLE(MF_SUSPEND_SAFEHOMES) : MULTI_FUNC_FLAG_ENABLE(MF_SUSPEND_SAFEHOMES);
5855
}
5956
#endif
6057
break;
61-
case MULTI_FUNC_4: // toggle RTH Trackback suspend
58+
case MULTI_FUNC_3: // toggle RTH Trackback suspend
6259
if (navConfig()->general.flags.rth_trackback_mode != RTH_TRACKBACK_OFF) {
6360
MULTI_FUNC_FLAG(MF_SUSPEND_TRACKBACK) ? MULTI_FUNC_FLAG_DISABLE(MF_SUSPEND_TRACKBACK) : MULTI_FUNC_FLAG_ENABLE(MF_SUSPEND_TRACKBACK);
6461
}
6562
break;
66-
case MULTI_FUNC_5:
63+
case MULTI_FUNC_4:
6764
#ifdef USE_DSHOT
6865
if (STATE(MULTIROTOR)) { // toggle Turtle mode
6966
MULTI_FUNC_FLAG(MF_TURTLE_MODE) ? MULTI_FUNC_FLAG_DISABLE(MF_TURTLE_MODE) : MULTI_FUNC_FLAG_ENABLE(MF_TURTLE_MODE);
7067
}
7168
#endif
7269
break;
73-
case MULTI_FUNC_6: // emergency ARM
70+
case MULTI_FUNC_5: // emergency ARM
7471
if (!ARMING_FLAG(ARMED)) {
7572
emergencyArmingUpdate(true, true);
7673
}

src/main/fc/multifunction.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626

2727
#include <stdbool.h>
2828

29+
typedef struct multiFunctionWarning_s {
30+
uint8_t osdWarningsFlags; // bitfield
31+
bool newWarningActive;
32+
} multiFunctionWarning_t;
33+
34+
extern multiFunctionWarning_t multiFunctionWarning;
35+
2936
#ifdef USE_MULTI_FUNCTIONS
3037

3138
extern uint8_t multiFunctionFlags;
@@ -47,7 +54,6 @@ typedef enum {
4754
MULTI_FUNC_3,
4855
MULTI_FUNC_4,
4956
MULTI_FUNC_5,
50-
MULTI_FUNC_6,
5157
MULTI_FUNC_END,
5258
} multi_function_e;
5359

src/main/fc/settings.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3904,6 +3904,7 @@ groups:
39043904
field: osd_switch_indicators_align_left
39053905
type: bool
39063906
default_value: ON
3907+
39073908
- name: PG_OSD_COMMON_CONFIG
39083909
type: osdCommonConfig_t
39093910
headers: ["io/osd_common.h"]

src/main/io/osd.c

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,9 @@ static bool fullRedraw = false;
203203

204204
static uint8_t armState;
205205

206+
// Multifunction
206207
static textAttributes_t osdGetMultiFunctionMessage(char *buff);
207-
static uint8_t osdWarningsFlags = 0;
208+
multiFunctionWarning_t multiFunctionWarning;
208209

209210
typedef struct osdMapData_s {
210211
uint32_t scale;
@@ -6405,49 +6406,35 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
64056406
return elemAttr;
64066407
}
64076408

6408-
void osdResetWarningFlags(void)
6409+
static bool osdCheckWarning(bool condition, uint8_t warningFlag)
64096410
{
6410-
osdWarningsFlags = 0;
6411-
}
6412-
6413-
static bool osdCheckWarning(bool condition, uint8_t warningFlag, uint8_t *warningsCount)
6414-
{
6415-
#define WARNING_REDISPLAY_DURATION 5000; // milliseconds
6416-
6411+
static timeMs_t newWarningEndTime = 0;
6412+
static uint8_t newWarningFlags = 0; // bitfield
64176413
const timeMs_t currentTimeMs = millis();
6418-
static timeMs_t warningDisplayStartTime = 0;
6419-
static timeMs_t redisplayStartTimeMs = 0;
6420-
static uint16_t osdWarningTimerDuration;
6421-
static uint8_t newWarningFlags;
64226414

6415+
/* New warnings dislayed individually for 10s with blinking after which
6416+
* all current warnings displayed without blinking on 1 second cycle */
64236417
if (condition) { // condition required to trigger warning
6424-
if (!(osdWarningsFlags & warningFlag)) {
6425-
osdWarningsFlags |= warningFlag;
6418+
if (!(multiFunctionWarning.osdWarningsFlags & warningFlag)) { // check for new warnings
6419+
multiFunctionWarning.osdWarningsFlags |= warningFlag;
64266420
newWarningFlags |= warningFlag;
6427-
redisplayStartTimeMs = 0;
6421+
newWarningEndTime = currentTimeMs + 10000;
6422+
multiFunctionWarning.newWarningActive = true;
64286423
}
64296424
#ifdef USE_DEV_TOOLS
64306425
if (systemConfig()->groundTestMode) {
64316426
return true;
64326427
}
64336428
#endif
6434-
/* Warnings displayed in full for set time before shrinking down to alert symbol with warning count only.
6435-
* All current warnings then redisplayed for 5s on 30s rolling cycle.
6436-
* New warnings dislayed individually for 10s */
6437-
if (currentTimeMs > redisplayStartTimeMs) {
6438-
warningDisplayStartTime = currentTimeMs;
6439-
osdWarningTimerDuration = newWarningFlags ? 10000 : WARNING_REDISPLAY_DURATION;
6440-
redisplayStartTimeMs = currentTimeMs + osdWarningTimerDuration + 30000;
6441-
}
6442-
6443-
if (currentTimeMs - warningDisplayStartTime < osdWarningTimerDuration) {
6444-
return (newWarningFlags & warningFlag) || osdWarningTimerDuration == WARNING_REDISPLAY_DURATION;
6429+
if (currentTimeMs < newWarningEndTime) {
6430+
return (newWarningFlags & warningFlag); // filter out new warnings excluding older warnings
64456431
} else {
64466432
newWarningFlags = 0;
6433+
multiFunctionWarning.newWarningActive = false;
64476434
}
6448-
*warningsCount += 1;
6449-
} else if (osdWarningsFlags & warningFlag) {
6450-
osdWarningsFlags &= ~warningFlag;
6435+
return true;
6436+
} else if (multiFunctionWarning.osdWarningsFlags & warningFlag) {
6437+
multiFunctionWarning.osdWarningsFlags &= ~warningFlag;
64516438
}
64526439

64536440
return false;
@@ -6458,7 +6445,6 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
64586445
/* Message length limit 10 char max */
64596446

64606447
textAttributes_t elemAttr = TEXT_ATTRIBUTES_NONE;
6461-
static uint8_t warningsCount;
64626448
const char *message = NULL;
64636449

64646450
#ifdef USE_MULTI_FUNCTIONS
@@ -6471,12 +6457,9 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
64716457
switch (selectedFunction) {
64726458
case MULTI_FUNC_NONE:
64736459
case MULTI_FUNC_1:
6474-
message = warningsCount ? "WARNINGS !" : "0 WARNINGS";
6475-
break;
6476-
case MULTI_FUNC_2:
64776460
message = posControl.flags.manualEmergLandActive ? "ABORT LAND" : "EMERG LAND";
64786461
break;
6479-
case MULTI_FUNC_3:
6462+
case MULTI_FUNC_2:
64806463
#if defined(USE_SAFE_HOME)
64816464
if (navConfig()->general.flags.safehome_usage_mode != SAFEHOME_USAGE_OFF) {
64826465
message = MULTI_FUNC_FLAG(MF_SUSPEND_SAFEHOMES) ? "USE SFHOME" : "SUS SFHOME";
@@ -6485,14 +6468,14 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
64856468
#endif
64866469
activeFunction++;
64876470
FALLTHROUGH;
6488-
case MULTI_FUNC_4:
6471+
case MULTI_FUNC_3:
64896472
if (navConfig()->general.flags.rth_trackback_mode != RTH_TRACKBACK_OFF) {
64906473
message = MULTI_FUNC_FLAG(MF_SUSPEND_TRACKBACK) ? "USE TKBACK" : "SUS TKBACK";
64916474
break;
64926475
}
64936476
activeFunction++;
64946477
FALLTHROUGH;
6495-
case MULTI_FUNC_5:
6478+
case MULTI_FUNC_4:
64966479
#ifdef USE_DSHOT
64976480
if (STATE(MULTIROTOR)) {
64986481
message = MULTI_FUNC_FLAG(MF_TURTLE_MODE) ? "END TURTLE" : "USE TURTLE";
@@ -6501,7 +6484,7 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
65016484
#endif
65026485
activeFunction++;
65036486
FALLTHROUGH;
6504-
case MULTI_FUNC_6:
6487+
case MULTI_FUNC_5:
65056488
message = ARMING_FLAG(ARMED) ? "NOW ARMED " : "EMERG ARM ";
65066489
break;
65076490
case MULTI_FUNC_END:
@@ -6524,23 +6507,30 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
65246507
#endif // MULTIFUNCTION - functions only, warnings always defined
65256508

65266509
/* --- WARNINGS --- */
6527-
const char *messages[7];
6510+
const char *messages[8];
65286511
uint8_t messageCount = 0;
65296512
bool warningCondition = false;
6530-
warningsCount = 0;
65316513
uint8_t warningFlagID = 1;
65326514

6533-
// Low Battery
6534-
const batteryState_e batteryState = getBatteryState();
6535-
warningCondition = batteryState == BATTERY_CRITICAL || batteryState == BATTERY_WARNING;
6536-
if (osdCheckWarning(warningCondition, warningFlagID, &warningsCount)) {
6537-
messages[messageCount++] = batteryState == BATTERY_CRITICAL ? "BATT EMPTY" : "BATT LOW !";
6515+
// Low Battery Voltage
6516+
const batteryState_e batteryVoltageState = checkBatteryVoltageState();
6517+
warningCondition = batteryVoltageState == BATTERY_CRITICAL || batteryVoltageState == BATTERY_WARNING;
6518+
if (osdCheckWarning(warningCondition, warningFlagID)) {
6519+
messages[messageCount++] = batteryVoltageState == BATTERY_CRITICAL ? "VBATT LAND" : "VBATT LOW ";
65386520
}
65396521

6522+
// Low Battery Capacity
6523+
if (batteryUsesCapacityThresholds()) {
6524+
const batteryState_e batteryState = getBatteryState();
6525+
warningCondition = batteryState == BATTERY_CRITICAL || batteryState == BATTERY_WARNING;
6526+
if (osdCheckWarning(warningCondition, warningFlagID <<= 1)) {
6527+
messages[messageCount++] = batteryState == BATTERY_CRITICAL ? "BATT EMPTY" : "BATT DYING";
6528+
}
6529+
}
65406530
#if defined(USE_GPS)
65416531
// GPS Fix and Failure
65426532
if (feature(FEATURE_GPS)) {
6543-
if (osdCheckWarning(!STATE(GPS_FIX), warningFlagID <<= 1, &warningsCount)) {
6533+
if (osdCheckWarning(!STATE(GPS_FIX), warningFlagID <<= 1)) {
65446534
bool gpsFailed = getHwGPSStatus() == HW_SENSOR_UNAVAILABLE;
65456535
messages[messageCount++] = gpsFailed ? "GPS FAILED" : "NO GPS FIX";
65466536
}
@@ -6549,12 +6539,12 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
65496539
// RTH sanity (warning if RTH heads 200m further away from home than closest point)
65506540
warningCondition = NAV_Status.state == MW_NAV_STATE_RTH_ENROUTE && !posControl.flags.rthTrackbackActive &&
65516541
(posControl.homeDistance - posControl.rthSanityChecker.minimalDistanceToHome) > 20000;
6552-
if (osdCheckWarning(warningCondition, warningFlagID <<= 1, &warningsCount)) {
6542+
if (osdCheckWarning(warningCondition, warningFlagID <<= 1)) {
65536543
messages[messageCount++] = "RTH SANITY";
65546544
}
65556545

65566546
// Altitude sanity (warning if significant mismatch between estimated and GPS altitude)
6557-
if (osdCheckWarning(posControl.flags.gpsCfEstimatedAltitudeMismatch, warningFlagID <<= 1, &warningsCount)) {
6547+
if (osdCheckWarning(posControl.flags.gpsCfEstimatedAltitudeMismatch, warningFlagID <<= 1)) {
65586548
messages[messageCount++] = "ALT SANITY";
65596549
}
65606550
#endif
@@ -6563,7 +6553,7 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
65636553
// Magnetometer failure
65646554
if (requestedSensors[SENSOR_INDEX_MAG] != MAG_NONE) {
65656555
hardwareSensorStatus_e magStatus = getHwCompassStatus();
6566-
if (osdCheckWarning(magStatus == HW_SENSOR_UNAVAILABLE || magStatus == HW_SENSOR_UNHEALTHY, warningFlagID <<= 1, &warningsCount)) {
6556+
if (osdCheckWarning(magStatus == HW_SENSOR_UNAVAILABLE || magStatus == HW_SENSOR_UNHEALTHY, warningFlagID <<= 1)) {
65676557
messages[messageCount++] = "MAG FAILED";
65686558
}
65696559
}
@@ -6572,7 +6562,7 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
65726562
#if defined(USE_PITOT)
65736563
// Pitot sensor validation failure (blocked/failed pitot tube)
65746564
if (sensors(SENSOR_PITOT) && detectedSensors[SENSOR_INDEX_PITOT] != PITOT_VIRTUAL) {
6575-
if (osdCheckWarning(pitotHasFailed(), warningFlagID <<= 1, &warningsCount)) {
6565+
if (osdCheckWarning(pitotHasFailed(), warningFlagID <<= 1)) {
65766566
messages[messageCount++] = "PITOT FAIL";
65776567
}
65786568
}
@@ -6586,18 +6576,17 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
65866576
// }
65876577

65886578
#ifdef USE_DEV_TOOLS
6589-
if (osdCheckWarning(systemConfig()->groundTestMode, warningFlagID <<= 1, &warningsCount)) {
6579+
if (osdCheckWarning(systemConfig()->groundTestMode, warningFlagID <<= 1)) {
65906580
messages[messageCount++] = "GRD TEST !";
65916581
}
65926582
#endif
65936583

65946584
if (messageCount) {
65956585
message = messages[OSD_ALTERNATING_CHOICES(1000, messageCount)]; // display each warning on 1s cycle
65966586
strcpy(buff, message);
6597-
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
6598-
} else if (warningsCount) {
6599-
buff[0] = SYM_ALERT;
6600-
tfp_sprintf(buff + 1, "%u ", warningsCount);
6587+
if (multiFunctionWarning.newWarningActive) {
6588+
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
6589+
}
66016590
}
66026591

66036592
return elemAttr;

src/main/io/osd.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,6 @@ int osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bo
585585
// Returns a heading angle in degrees normalized to [0, 360).
586586
int osdGetHeadingAngle(int angle);
587587

588-
void osdResetWarningFlags(void);
589-
590588
int16_t osdGetPanServoOffset(void);
591589

592590
/**

src/main/sensors/battery.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static void updateBatteryVoltage(timeUs_t timeDelta, bool justConnected)
288288
}
289289
break;
290290
#endif
291-
291+
292292
#if defined(USE_FAKE_BATT_SENSOR)
293293
case VOLTAGE_SENSOR_FAKE:
294294
vbat = fakeBattSensorGetVBat();
@@ -328,30 +328,32 @@ static void updateBatteryVoltage(timeUs_t timeDelta, bool justConnected)
328328
batteryState_e checkBatteryVoltageState(void)
329329
{
330330
uint16_t stateVoltage = getBatteryVoltage();
331-
switch (batteryState)
331+
static batteryState_e currentBatteryVoltageState = BATTERY_OK;
332+
333+
switch (currentBatteryVoltageState)
332334
{
333335
case BATTERY_OK:
334336
if (stateVoltage <= (batteryWarningVoltage - VBATT_HYSTERESIS)) {
335-
return BATTERY_WARNING;
337+
currentBatteryVoltageState = BATTERY_WARNING;
336338
}
337339
break;
338340
case BATTERY_WARNING:
339341
if (stateVoltage <= (batteryCriticalVoltage - VBATT_HYSTERESIS)) {
340-
return BATTERY_CRITICAL;
342+
currentBatteryVoltageState = BATTERY_CRITICAL;
341343
} else if (stateVoltage > (batteryWarningVoltage + VBATT_HYSTERESIS)){
342-
return BATTERY_OK;
344+
currentBatteryVoltageState = BATTERY_OK;
343345
}
344346
break;
345347
case BATTERY_CRITICAL:
346348
if (stateVoltage > (batteryCriticalVoltage + VBATT_HYSTERESIS)) {
347-
return BATTERY_WARNING;
349+
currentBatteryVoltageState = BATTERY_WARNING;
348350
}
349351
break;
350352
default:
351353
break;
352354
}
353355

354-
return batteryState;
356+
return currentBatteryVoltageState;
355357
}
356358

357359
static void checkBatteryCapacityState(void)

0 commit comments

Comments
 (0)