mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 00:05:33 +03:00
Merge pull request #3133 from DanNixon/osd_stats
Allow customisation of the OSD stats screen
This commit is contained in:
commit
29917db6f2
4 changed files with 114 additions and 32 deletions
|
@ -775,6 +775,9 @@ static bool mspCommonProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProce
|
||||||
for (int i = 0; i < OSD_ITEM_COUNT; i++) {
|
for (int i = 0; i < OSD_ITEM_COUNT; i++) {
|
||||||
sbufWriteU16(dst, osdConfig()->item_pos[i]);
|
sbufWriteU16(dst, osdConfig()->item_pos[i]);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < OSD_STAT_COUNT; i++ ) {
|
||||||
|
sbufWriteU8(dst, osdConfig()->enabled_stats[i]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2039,8 +2042,9 @@ static mspResult_e mspCommonProcessInCommand(uint8_t cmdMSP, sbuf_t *src)
|
||||||
case MSP_SET_OSD_CONFIG:
|
case MSP_SET_OSD_CONFIG:
|
||||||
{
|
{
|
||||||
const uint8_t addr = sbufReadU8(src);
|
const uint8_t addr = sbufReadU8(src);
|
||||||
// set all the other settings
|
|
||||||
if ((int8_t)addr == -1) {
|
if ((int8_t)addr == -1) {
|
||||||
|
/* Set general OSD settings */
|
||||||
#ifdef USE_MAX7456
|
#ifdef USE_MAX7456
|
||||||
vcdProfileMutable()->video_system = sbufReadU8(src);
|
vcdProfileMutable()->video_system = sbufReadU8(src);
|
||||||
#else
|
#else
|
||||||
|
@ -2055,10 +2059,17 @@ static mspResult_e mspCommonProcessInCommand(uint8_t cmdMSP, sbuf_t *src)
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if defined(OSD)
|
#if defined(OSD)
|
||||||
// set a position setting
|
const uint16_t value = sbufReadU16(src);
|
||||||
const uint16_t pos = sbufReadU16(src);
|
|
||||||
if (addr < OSD_ITEM_COUNT) {
|
/* Get screen index, 0 is post flight statsitsics, 1 and above are in flight OSD screens */
|
||||||
osdConfigMutable()->item_pos[addr] = pos;
|
const uint8_t screen = (sbufBytesRemaining(src) >= 1) ? sbufReadU8(src) : 1;
|
||||||
|
|
||||||
|
if (screen == 0 && addr < OSD_STAT_COUNT) {
|
||||||
|
/* Set statistic item enable */
|
||||||
|
osdConfigMutable()->enabled_stats[addr] = value;
|
||||||
|
} else if (addr < OSD_ITEM_COUNT) {
|
||||||
|
/* Set element positions */
|
||||||
|
osdConfigMutable()->item_pos[addr] = value;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return MSP_RESULT_ERROR;
|
return MSP_RESULT_ERROR;
|
||||||
|
|
|
@ -657,6 +657,16 @@ const clivalue_t valueTable[] = {
|
||||||
{ "osd_rol_ang_pos", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 0, OSD_POSCFG_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, item_pos[OSD_ROLL_ANGLE]) },
|
{ "osd_rol_ang_pos", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 0, OSD_POSCFG_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, item_pos[OSD_ROLL_ANGLE]) },
|
||||||
{ "osd_battery_usage_pos", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 0, OSD_POSCFG_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, item_pos[OSD_MAIN_BATT_USAGE]) },
|
{ "osd_battery_usage_pos", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 0, OSD_POSCFG_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, item_pos[OSD_MAIN_BATT_USAGE]) },
|
||||||
|
|
||||||
|
{ "osd_stat_max_spd", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_SPEED])},
|
||||||
|
{ "osd_stat_min_batt", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MIN_BATTERY])},
|
||||||
|
{ "osd_stat_min_rssi", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MIN_RSSI])},
|
||||||
|
{ "osd_stat_max_curr", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_CURRENT])},
|
||||||
|
{ "osd_stat_used_mah", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_USED_MAH])},
|
||||||
|
{ "osd_stat_max_alt", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_ALTITUDE])},
|
||||||
|
{ "osd_stat_bbox", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_BLACKBOX])},
|
||||||
|
{ "osd_stat_endbatt", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_END_BATTERY])},
|
||||||
|
{ "osd_stat_flytime", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_FLYTIME])},
|
||||||
|
{ "osd_stat_armtime", VAR_UINT8 | MASTER_VALUE, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_ARMEDTIME])},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PG_SYSTEM_CONFIG
|
// PG_SYSTEM_CONFIG
|
||||||
|
|
|
@ -120,6 +120,7 @@ typedef struct statistic_s {
|
||||||
int16_t max_current; // /10
|
int16_t max_current; // /10
|
||||||
int16_t min_rssi;
|
int16_t min_rssi;
|
||||||
int16_t max_altitude;
|
int16_t max_altitude;
|
||||||
|
uint16_t armed_time;
|
||||||
} statistic_t;
|
} statistic_t;
|
||||||
|
|
||||||
static statistic_t stats;
|
static statistic_t stats;
|
||||||
|
@ -274,6 +275,13 @@ static void osdDrawSingleElement(uint8_t item)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OSD_ARMED_TIME:
|
||||||
|
{
|
||||||
|
buff[0] = SYM_FLY_M;
|
||||||
|
tfp_sprintf(buff + 1, "%02d:%02d", stats.armed_time / 60, stats.armed_time % 60);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case OSD_FLYMODE:
|
case OSD_FLYMODE:
|
||||||
{
|
{
|
||||||
char *p = "ACRO";
|
char *p = "ACRO";
|
||||||
|
@ -564,6 +572,7 @@ void osdDrawElements(void)
|
||||||
osdDrawSingleElement(OSD_PITCH_ANGLE);
|
osdDrawSingleElement(OSD_PITCH_ANGLE);
|
||||||
osdDrawSingleElement(OSD_ROLL_ANGLE);
|
osdDrawSingleElement(OSD_ROLL_ANGLE);
|
||||||
osdDrawSingleElement(OSD_MAIN_BATT_USAGE);
|
osdDrawSingleElement(OSD_MAIN_BATT_USAGE);
|
||||||
|
osdDrawSingleElement(OSD_ARMED_TIME);
|
||||||
|
|
||||||
#ifdef GPS
|
#ifdef GPS
|
||||||
#ifdef CMS
|
#ifdef CMS
|
||||||
|
@ -608,13 +617,23 @@ void pgResetFn_osdConfig(osdConfig_t *osdProfile)
|
||||||
osdProfile->item_pos[OSD_DEBUG] = OSD_POS(7, 12) | VISIBLE_FLAG;
|
osdProfile->item_pos[OSD_DEBUG] = OSD_POS(7, 12) | VISIBLE_FLAG;
|
||||||
osdProfile->item_pos[OSD_PITCH_ANGLE] = OSD_POS(1, 8) | VISIBLE_FLAG;
|
osdProfile->item_pos[OSD_PITCH_ANGLE] = OSD_POS(1, 8) | VISIBLE_FLAG;
|
||||||
osdProfile->item_pos[OSD_ROLL_ANGLE] = OSD_POS(1, 9) | VISIBLE_FLAG;
|
osdProfile->item_pos[OSD_ROLL_ANGLE] = OSD_POS(1, 9) | VISIBLE_FLAG;
|
||||||
|
|
||||||
osdProfile->item_pos[OSD_GPS_LAT] = OSD_POS(18, 14) | VISIBLE_FLAG;
|
osdProfile->item_pos[OSD_GPS_LAT] = OSD_POS(18, 14) | VISIBLE_FLAG;
|
||||||
osdProfile->item_pos[OSD_GPS_LON] = OSD_POS(18, 15) | VISIBLE_FLAG;
|
osdProfile->item_pos[OSD_GPS_LON] = OSD_POS(18, 15) | VISIBLE_FLAG;
|
||||||
osdProfile->item_pos[OSD_MAIN_BATT_USAGE] = OSD_POS(15, 10) | VISIBLE_FLAG;
|
osdProfile->item_pos[OSD_MAIN_BATT_USAGE] = OSD_POS(15, 10) | VISIBLE_FLAG;
|
||||||
|
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_MAX_SPEED] = true;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_MIN_BATTERY] = true;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_MIN_RSSI] = true;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_MAX_CURRENT] = true;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_USED_MAH] = true;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_MAX_ALTITUDE] = false;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_BLACKBOX] = true;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_END_BATTERY] = false;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_FLYTIME] = false;
|
||||||
|
osdProfile->enabled_stats[OSD_STAT_ARMEDTIME] = true;
|
||||||
|
|
||||||
osdProfile->units = OSD_UNIT_METRIC;
|
osdProfile->units = OSD_UNIT_METRIC;
|
||||||
|
|
||||||
osdProfile->rssi_alarm = 20;
|
osdProfile->rssi_alarm = 20;
|
||||||
osdProfile->cap_alarm = 2200;
|
osdProfile->cap_alarm = 2200;
|
||||||
osdProfile->time_alarm = 10; // in minutes
|
osdProfile->time_alarm = 10; // in minutes
|
||||||
|
@ -736,6 +755,7 @@ static void osdResetStats(void)
|
||||||
stats.max_current = 0;
|
stats.max_current = 0;
|
||||||
stats.min_rssi = 99;
|
stats.min_rssi = 99;
|
||||||
stats.max_altitude = 0;
|
stats.max_altitude = 0;
|
||||||
|
stats.armed_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void osdUpdateStats(void)
|
static void osdUpdateStats(void)
|
||||||
|
@ -804,6 +824,13 @@ static void osdGetBlackboxStatusString(char * buff, uint8_t len)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void osdDisplayStatisticLabel(uint8_t y, const char * text, const char * value)
|
||||||
|
{
|
||||||
|
displayWrite(osdDisplayPort, 2, y, text);
|
||||||
|
displayWrite(osdDisplayPort, 20, y, ":");
|
||||||
|
displayWrite(osdDisplayPort, 22, y, value);
|
||||||
|
}
|
||||||
|
|
||||||
static void osdShowStats(void)
|
static void osdShowStats(void)
|
||||||
{
|
{
|
||||||
uint8_t top = 2;
|
uint8_t top = 2;
|
||||||
|
@ -812,43 +839,60 @@ static void osdShowStats(void)
|
||||||
displayClearScreen(osdDisplayPort);
|
displayClearScreen(osdDisplayPort);
|
||||||
displayWrite(osdDisplayPort, 2, top++, " --- STATS ---");
|
displayWrite(osdDisplayPort, 2, top++, " --- STATS ---");
|
||||||
|
|
||||||
if (STATE(GPS_FIX)) {
|
if (osdConfig()->enabled_stats[OSD_STAT_ARMEDTIME]) {
|
||||||
displayWrite(osdDisplayPort, 2, top, "MAX SPEED :");
|
tfp_sprintf(buff, "%02d:%02d", stats.armed_time / 60, stats.armed_time % 60);
|
||||||
itoa(stats.max_speed, buff, 10);
|
osdDisplayStatisticLabel(top++, "ARMED TIME", buff);
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
displayWrite(osdDisplayPort, 2, top, "MIN BATTERY :");
|
if (osdConfig()->enabled_stats[OSD_STAT_FLYTIME]) {
|
||||||
tfp_sprintf(buff, "%d.%1dV", stats.min_voltage / 10, stats.min_voltage % 10);
|
tfp_sprintf(buff, "%02d:%02d", flyTime / 60, flyTime % 60);
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
osdDisplayStatisticLabel(top++, "FLY TIME", buff);
|
||||||
|
}
|
||||||
|
|
||||||
displayWrite(osdDisplayPort, 2, top, "MIN RSSI :");
|
if (osdConfig()->enabled_stats[OSD_STAT_MAX_SPEED] && STATE(GPS_FIX)) {
|
||||||
itoa(stats.min_rssi, buff, 10);
|
itoa(stats.max_speed, buff, 10);
|
||||||
strcat(buff, "%");
|
osdDisplayStatisticLabel(top++, "MAX SPEED", buff);
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
}
|
||||||
|
|
||||||
|
if (osdConfig()->enabled_stats[OSD_STAT_MIN_BATTERY]) {
|
||||||
|
tfp_sprintf(buff, "%d.%1dV", stats.min_voltage / 10, stats.min_voltage % 10);
|
||||||
|
osdDisplayStatisticLabel(top++, "MIN BATTERY", buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (osdConfig()->enabled_stats[OSD_STAT_END_BATTERY]) {
|
||||||
|
tfp_sprintf(buff, "%d.%1dV", getBatteryVoltage() / 10, getBatteryVoltage() % 10);
|
||||||
|
osdDisplayStatisticLabel(top++, "END BATTERY", buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (osdConfig()->enabled_stats[OSD_STAT_MIN_RSSI]) {
|
||||||
|
itoa(stats.min_rssi, buff, 10);
|
||||||
|
strcat(buff, "%");
|
||||||
|
osdDisplayStatisticLabel(top++, "MIN RSSI", buff);
|
||||||
|
}
|
||||||
|
|
||||||
if (batteryConfig()->currentMeterSource != CURRENT_METER_NONE) {
|
if (batteryConfig()->currentMeterSource != CURRENT_METER_NONE) {
|
||||||
displayWrite(osdDisplayPort, 2, top, "MAX CURRENT :");
|
if (osdConfig()->enabled_stats[OSD_STAT_MAX_CURRENT]) {
|
||||||
itoa(stats.max_current, buff, 10);
|
itoa(stats.max_current, buff, 10);
|
||||||
strcat(buff, "A");
|
strcat(buff, "A");
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
osdDisplayStatisticLabel(top++, "MAX CURRENT", buff);
|
||||||
|
}
|
||||||
|
|
||||||
displayWrite(osdDisplayPort, 2, top, "USED MAH :");
|
if (osdConfig()->enabled_stats[OSD_STAT_USED_MAH]) {
|
||||||
itoa(getMAhDrawn(), buff, 10);
|
tfp_sprintf(buff, "%d%c", getMAhDrawn(), SYM_MAH);
|
||||||
strcat(buff, "\x07");
|
osdDisplayStatisticLabel(top++, "USED MAH", buff);
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
displayWrite(osdDisplayPort, 2, top, "MAX ALTITUDE :");
|
if (osdConfig()->enabled_stats[OSD_STAT_MAX_ALTITUDE]) {
|
||||||
int32_t alt = osdGetAltitude(stats.max_altitude);
|
int32_t alt = osdGetAltitude(stats.max_altitude);
|
||||||
tfp_sprintf(buff, "%c%d.%01d%c", alt < 0 ? '-' : ' ', abs(alt / 100), abs((alt % 100) / 10), osdGetAltitudeSymbol());
|
tfp_sprintf(buff, "%c%d.%01d%c", alt < 0 ? '-' : ' ', abs(alt / 100), abs((alt % 100) / 10), osdGetAltitudeSymbol());
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
osdDisplayStatisticLabel(top++, "MAX ALTITUDE", buff);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BLACKBOX
|
#ifdef BLACKBOX
|
||||||
if (blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) {
|
if (osdConfig()->enabled_stats[OSD_STAT_BLACKBOX] && blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) {
|
||||||
displayWrite(osdDisplayPort, 2, top, "BLACKBOX :");
|
|
||||||
osdGetBlackboxStatusString(buff, 10);
|
osdGetBlackboxStatusString(buff, 10);
|
||||||
displayWrite(osdDisplayPort, 22, top++, buff);
|
osdDisplayStatisticLabel(top++, "BLACKBOX", buff);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -884,6 +928,7 @@ static void osdRefresh(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
if (ARMING_FLAG(ARMED) && sec != lastSec) {
|
if (ARMING_FLAG(ARMED) && sec != lastSec) {
|
||||||
flyTime++;
|
flyTime++;
|
||||||
|
stats.armed_time++;
|
||||||
lastSec = sec;
|
lastSec = sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,24 @@ typedef enum {
|
||||||
OSD_PITCH_ANGLE,
|
OSD_PITCH_ANGLE,
|
||||||
OSD_ROLL_ANGLE,
|
OSD_ROLL_ANGLE,
|
||||||
OSD_MAIN_BATT_USAGE,
|
OSD_MAIN_BATT_USAGE,
|
||||||
|
OSD_ARMED_TIME,
|
||||||
OSD_ITEM_COUNT // MUST BE LAST
|
OSD_ITEM_COUNT // MUST BE LAST
|
||||||
} osd_items_e;
|
} osd_items_e;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OSD_STAT_MAX_SPEED,
|
||||||
|
OSD_STAT_MIN_BATTERY,
|
||||||
|
OSD_STAT_MIN_RSSI,
|
||||||
|
OSD_STAT_MAX_CURRENT,
|
||||||
|
OSD_STAT_USED_MAH,
|
||||||
|
OSD_STAT_MAX_ALTITUDE,
|
||||||
|
OSD_STAT_BLACKBOX,
|
||||||
|
OSD_STAT_END_BATTERY,
|
||||||
|
OSD_STAT_FLYTIME,
|
||||||
|
OSD_STAT_ARMEDTIME,
|
||||||
|
OSD_STAT_COUNT // MUST BE LAST
|
||||||
|
} osd_states_e;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OSD_UNIT_IMPERIAL,
|
OSD_UNIT_IMPERIAL,
|
||||||
OSD_UNIT_METRIC
|
OSD_UNIT_METRIC
|
||||||
|
@ -66,6 +81,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct osdConfig_s {
|
typedef struct osdConfig_s {
|
||||||
uint16_t item_pos[OSD_ITEM_COUNT];
|
uint16_t item_pos[OSD_ITEM_COUNT];
|
||||||
|
bool enabled_stats[OSD_STAT_COUNT];
|
||||||
|
|
||||||
// Alarms
|
// Alarms
|
||||||
uint8_t rssi_alarm;
|
uint8_t rssi_alarm;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue