Skip to content

Commit d019eeb

Browse files
authored
Merge pull request #6598 from OptimusTi/stats-pages
Add OSD Stats pages and some crsf formatting fixes
2 parents 3ea4cba + 4aef37d commit d019eeb

File tree

2 files changed

+125
-57
lines changed

2 files changed

+125
-57
lines changed

src/main/drivers/osd_symbols.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@
243243
#define SYM_2RSS 0xEA // RSSI 2
244244
#define SYM_DB 0xEB // dB
245245
#define SYM_DBM 0xEC // dBm
246-
#define SYM_SRN 0xEE // SNR
246+
#define SYM_SNR 0xEE // SNR
247247
#define SYM_MW 0xED // mW
248248

249249
#else

src/main/io/osd.c

100755100644
Lines changed: 124 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ FILE_COMPILE_FOR_SPEED
117117
#define GFORCE_FILTER_TC 0.2
118118

119119
#define DELAYED_REFRESH_RESUME_COMMAND (checkStickPosition(THR_HI) || checkStickPosition(PIT_HI))
120+
#define STATS_PAGE2 (checkStickPosition(ROL_HI))
121+
#define STATS_PAGE1 (checkStickPosition(ROL_LO))
120122

121123
#define SPLASH_SCREEN_DISPLAY_TIME 4000 // ms
122124
#define ARMED_SCREEN_DISPLAY_TIME 1500 // ms
@@ -156,6 +158,8 @@ typedef struct statistic_s {
156158
int16_t max_current; // /100
157159
int16_t max_power; // /100
158160
int16_t min_rssi;
161+
int16_t min_lq; // for CRSF
162+
int16_t min_rssi_dbm; // for CRSF
159163
int32_t max_altitude;
160164
uint32_t max_distance;
161165
} statistic_t;
@@ -168,6 +172,7 @@ static bool refreshWaitForResumeCmdRelease;
168172
static bool fullRedraw = false;
169173

170174
static uint8_t armState;
175+
static uint8_t statsPagesCheck = 0;
171176

172177
typedef struct osdMapData_s {
173178
uint32_t scale;
@@ -528,6 +533,21 @@ static uint16_t osdConvertRSSI(void)
528533
return constrain(getRSSI() * 100 / RSSI_MAX_VALUE, 0, 99);
529534
}
530535

536+
static uint16_t osdGetLQ(void)
537+
{
538+
int16_t statsLQ = rxLinkStatistics.uplinkLQ;
539+
int16_t scaledLQ = scaleRange(constrain(statsLQ, 0, 100), 0, 100, 170, 300);
540+
if (rxLinkStatistics.rfMode == 2) {
541+
return scaledLQ;
542+
} else {
543+
return statsLQ;
544+
}
545+
}
546+
547+
static uint16_t osdGetdBm(void)
548+
{
549+
return rxLinkStatistics.uplinkRSSI;
550+
}
531551
/**
532552
* Displays a temperature postfixed with a symbol depending on the current unit system
533553
* @param label to display
@@ -1714,7 +1734,9 @@ static bool osdDrawSingleElement(uint8_t item)
17141734
return true;
17151735
}
17161736

1737+
#if defined(USE_SERIALRX_CRSF)
17171738
case OSD_CRSF_RSSI_DBM:
1739+
{
17181740
if (rxLinkStatistics.activeAnt == 0) {
17191741
buff[0] = SYM_RSSI;
17201742
tfp_sprintf(buff + 1, "%4d%c", rxLinkStatistics.uplinkRSSI, SYM_DBM);
@@ -1729,12 +1751,12 @@ static bool osdDrawSingleElement(uint8_t item)
17291751
}
17301752
}
17311753
break;
1732-
1733-
#if defined(USE_SERIALRX_CRSF)
1734-
case OSD_CRSF_LQ: {
1735-
buff[0] = SYM_BLANK;
1736-
int16_t statsLQ = rxLinkStatistics.uplinkLQ;
1737-
int16_t scaledLQ = scaleRange(constrain(statsLQ, 0, 100), 0, 100, 170, 300);
1754+
}
1755+
case OSD_CRSF_LQ:
1756+
{
1757+
buff[0] = SYM_BLANK;
1758+
int16_t statsLQ = rxLinkStatistics.uplinkLQ;
1759+
int16_t scaledLQ = scaleRange(constrain(statsLQ, 0, 100), 0, 100, 170, 300);
17381760
if (rxLinkStatistics.rfMode == 2) {
17391761
if (osdConfig()->crsf_lq_format == OSD_CRSF_LQ_TYPE1) {
17401762
tfp_sprintf(buff, "%5d%s", scaledLQ, "%");
@@ -1744,9 +1766,9 @@ static bool osdDrawSingleElement(uint8_t item)
17441766
} else {
17451767
if (osdConfig()->crsf_lq_format == OSD_CRSF_LQ_TYPE1) {
17461768
tfp_sprintf(buff, "%5d%s", rxLinkStatistics.uplinkLQ, "%");
1747-
} else {
1769+
} else {
17481770
tfp_sprintf(buff, "%d:%3d%s", rxLinkStatistics.rfMode, rxLinkStatistics.uplinkLQ, "%");
1749-
}
1771+
}
17501772
}
17511773
if (!failsafeIsReceivingRxData()){
17521774
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
@@ -1756,31 +1778,32 @@ static bool osdDrawSingleElement(uint8_t item)
17561778
break;
17571779
}
17581780

1759-
case OSD_CRSF_SNR_DB: {
1760-
const char* showsnr = "-20";
1761-
const char* hidesnr = " ";
1762-
int16_t osdSNR_Alarm = rxLinkStatistics.uplinkSNR;
1763-
if (osdSNR_Alarm <= osdConfig()->snr_alarm) {
1764-
buff[0] = SYM_SRN;
1765-
tfp_sprintf(buff + 1, "%3d%c", rxLinkStatistics.uplinkSNR, SYM_DB);
1766-
}
1767-
else if (osdSNR_Alarm > osdConfig()->snr_alarm) {
1768-
if (cmsInMenu) {
1769-
buff[0] = SYM_SRN;
1770-
tfp_sprintf(buff + 1, "%s%c", showsnr, SYM_DB);
1771-
} else {
1772-
buff[0] = SYM_BLANK;
1773-
tfp_sprintf(buff + 1, "%s%c", hidesnr, SYM_BLANK);
1781+
case OSD_CRSF_SNR_DB:
1782+
{
1783+
const char* showsnr = "-20";
1784+
const char* hidesnr = " ";
1785+
int16_t osdSNR_Alarm = rxLinkStatistics.uplinkSNR;
1786+
if (osdSNR_Alarm > osdConfig()->snr_alarm) {
1787+
if (cmsInMenu) {
1788+
buff[0] = SYM_SNR;
1789+
tfp_sprintf(buff + 1, "%s%c", showsnr, SYM_DB);
1790+
} else {
1791+
buff[0] = SYM_BLANK;
1792+
tfp_sprintf(buff + 1, "%s%c", hidesnr, SYM_BLANK);
1793+
}
1794+
} else if (osdSNR_Alarm <= osdConfig()->snr_alarm) {
1795+
buff[0] = SYM_SNR;
1796+
tfp_sprintf(buff + 1, "%3d%c", rxLinkStatistics.uplinkSNR, SYM_DB);
17741797
}
1798+
break;
17751799
}
1776-
break;
1777-
}
1778-
#endif
17791800

1780-
case OSD_CRSF_TX_POWER: {
1781-
tfp_sprintf(buff, "%4d%c", rxLinkStatistics.uplinkTXPower, SYM_MW);
1782-
break;
1783-
}
1801+
case OSD_CRSF_TX_POWER:
1802+
{
1803+
tfp_sprintf(buff, "%4d%c", rxLinkStatistics.uplinkTXPower, SYM_MW);
1804+
break;
1805+
}
1806+
#endif
17841807

17851808
case OSD_CROSSHAIRS: // Hud is a sub-element of the crosshair
17861809

@@ -2987,6 +3010,8 @@ static void osdResetStats(void)
29873010
stats.max_speed = 0;
29883011
stats.min_voltage = 5000;
29893012
stats.min_rssi = 99;
3013+
stats.min_lq = 300;
3014+
stats.min_rssi_dbm = 0;
29903015
stats.max_altitude = 0;
29913016
}
29923017

@@ -3019,22 +3044,30 @@ static void osdUpdateStats(void)
30193044
if (stats.min_rssi > value)
30203045
stats.min_rssi = value;
30213046

3047+
value = osdGetLQ();
3048+
if (stats.min_lq > value)
3049+
stats.min_lq = value;
3050+
3051+
value = osdGetdBm();
3052+
if (stats.min_rssi_dbm > value)
3053+
stats.min_rssi_dbm = value;
3054+
30223055
stats.max_altitude = MAX(stats.max_altitude, osdGetAltitude());
30233056
}
30243057

3025-
/* Attention: NTSC screen only has 12 fully visible lines - it is FULL now! */
3026-
static void osdShowStats(void)
3058+
static void osdShowStatsPage1(void)
30273059
{
30283060
const char * disarmReasonStr[DISARM_REASON_COUNT] = { "UNKNOWN", "TIMEOUT", "STICKS", "SWITCH", "SWITCH", "KILLSW", "FAILSAFE", "NAV SYS" };
30293061
uint8_t top = 1; /* first fully visible line */
30303062
const uint8_t statNameX = 1;
30313063
const uint8_t statValuesX = 20;
30323064
char buff[10];
3065+
statsPagesCheck = 1;
30333066

30343067
displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING);
30353068
displayClearScreen(osdDisplayPort);
3036-
if (osdDisplayIsPAL())
3037-
displayWrite(osdDisplayPort, statNameX, top++, " --- STATS ---");
3069+
3070+
displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 1/2");
30383071

30393072
if (feature(FEATURE_GPS)) {
30403073
displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :");
@@ -3055,26 +3088,64 @@ static void osdShowStats(void)
30553088
osdFormatAltitudeStr(buff, stats.max_altitude);
30563089
displayWrite(osdDisplayPort, statValuesX, top++, buff);
30573090

3058-
displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :");
3059-
osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2);
3060-
strcat(buff, "V");
3061-
osdLeftAlignString(buff);
3091+
#if defined(USE_SERIALRX_CRSF)
3092+
displayWrite(osdDisplayPort, statNameX, top, "MIN LQ :");
3093+
itoa(stats.min_lq, buff, 10);
3094+
strcat(buff, "%");
30623095
displayWrite(osdDisplayPort, statValuesX, top++, buff);
30633096

3097+
displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI :");
3098+
itoa(stats.min_rssi_dbm, buff, 10);
3099+
tfp_sprintf(buff, "%s%c", buff, SYM_DBM);
3100+
displayWrite(osdDisplayPort, statValuesX, top++, buff);
3101+
#else
30643102
displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI :");
30653103
itoa(stats.min_rssi, buff, 10);
30663104
strcat(buff, "%");
30673105
displayWrite(osdDisplayPort, statValuesX, top++, buff);
3106+
#endif
3107+
3108+
displayWrite(osdDisplayPort, statNameX, top, "FLY TIME :");
3109+
uint16_t flySeconds = getFlightTime();
3110+
uint16_t flyMinutes = flySeconds / 60;
3111+
flySeconds %= 60;
3112+
uint16_t flyHours = flyMinutes / 60;
3113+
flyMinutes %= 60;
3114+
tfp_sprintf(buff, "%02u:%02u:%02u", flyHours, flyMinutes, flySeconds);
3115+
displayWrite(osdDisplayPort, statValuesX, top++, buff);
3116+
3117+
displayWrite(osdDisplayPort, statNameX, top, "DISARMED BY :");
3118+
displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]);
3119+
displayCommitTransaction(osdDisplayPort);
3120+
}
3121+
3122+
static void osdShowStatsPage2(void)
3123+
{
3124+
uint8_t top = 1; /* first fully visible line */
3125+
const uint8_t statNameX = 1;
3126+
const uint8_t statValuesX = 20;
3127+
char buff[10];
3128+
statsPagesCheck = 1;
3129+
3130+
displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING);
3131+
displayClearScreen(osdDisplayPort);
3132+
3133+
displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 2/2");
3134+
3135+
displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :");
3136+
osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2);
3137+
tfp_sprintf(buff, "%s%c", buff, SYM_VOLT);
3138+
displayWrite(osdDisplayPort, statValuesX, top++, buff);
30683139

30693140
if (feature(FEATURE_CURRENT_METER)) {
30703141
displayWrite(osdDisplayPort, statNameX, top, "MAX CURRENT :");
30713142
itoa(stats.max_current, buff, 10);
3072-
strcat(buff, "A");
3143+
tfp_sprintf(buff, "%s%c", buff, SYM_AMP);
30733144
displayWrite(osdDisplayPort, statValuesX, top++, buff);
30743145

30753146
displayWrite(osdDisplayPort, statNameX, top, "MAX POWER :");
30763147
itoa(stats.max_power, buff, 10);
3077-
strcat(buff, "W");
3148+
tfp_sprintf(buff, "%s%c", buff, SYM_WATT);
30783149
displayWrite(osdDisplayPort, statValuesX, top++, buff);
30793150

30803151
if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) {
@@ -3083,7 +3154,7 @@ static void osdShowStats(void)
30833154
} else {
30843155
displayWrite(osdDisplayPort, statNameX, top, "USED WH :");
30853156
osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3);
3086-
strcat(buff, "\xAB"); // SYM_WH
3157+
tfp_sprintf(buff, "%s%c", buff, SYM_WH);
30873158
}
30883159
displayWrite(osdDisplayPort, statValuesX, top++, buff);
30893160

@@ -3116,15 +3187,6 @@ static void osdShowStats(void)
31163187
}
31173188
}
31183189

3119-
displayWrite(osdDisplayPort, statNameX, top, "FLY TIME :");
3120-
uint16_t flySeconds = getFlightTime();
3121-
uint16_t flyMinutes = flySeconds / 60;
3122-
flySeconds %= 60;
3123-
uint16_t flyHours = flyMinutes / 60;
3124-
flyMinutes %= 60;
3125-
tfp_sprintf(buff, "%02u:%02u:%02u", flyHours, flyMinutes, flySeconds);
3126-
displayWrite(osdDisplayPort, statValuesX, top++, buff);
3127-
31283190
const float max_gforce = accGetMeasuredMaxG();
31293191
displayWrite(osdDisplayPort, statNameX, top, "MAX G-FORCE :");
31303192
osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3);
@@ -3134,12 +3196,9 @@ static void osdShowStats(void)
31343196
displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:");
31353197
osdFormatCentiNumber(buff, acc_extremes[Z].min * 100, 0, 2, 0, 4);
31363198
strcat(buff,"/");
3137-
displayWrite(osdDisplayPort, statValuesX, top, buff);
3199+
displayWrite(osdDisplayPort, statValuesX - 1, top, buff);
31383200
osdFormatCentiNumber(buff, acc_extremes[Z].max * 100, 0, 2, 0, 3);
3139-
displayWrite(osdDisplayPort, statValuesX + 5, top++, buff);
3140-
3141-
displayWrite(osdDisplayPort, statNameX, top, "DISARMED BY :");
3142-
displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]);
3201+
displayWrite(osdDisplayPort, statValuesX + 4, top++, buff);
31433202
displayCommitTransaction(osdDisplayPort);
31443203
}
31453204

@@ -3257,13 +3316,14 @@ static void osdRefresh(timeUs_t currentTimeUs)
32573316
osdResetStats();
32583317
osdShowArmed(); // reset statistic etc
32593318
uint32_t delay = ARMED_SCREEN_DISPLAY_TIME;
3319+
statsPagesCheck = 0;
32603320
#if defined(USE_SAFE_HOME)
32613321
if (isSafeHomeInUse())
32623322
delay *= 3;
32633323
#endif
32643324
osdSetNextRefreshIn(delay);
32653325
} else {
3266-
osdShowStats(); // show statistic
3326+
osdShowStatsPage1(); // show first page of statistic
32673327
osdSetNextRefreshIn(STATS_SCREEN_DISPLAY_TIME);
32683328
}
32693329

@@ -3282,6 +3342,14 @@ static void osdRefresh(timeUs_t currentTimeUs)
32823342
if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && DELAYED_REFRESH_RESUME_COMMAND)) {
32833343
displayClearScreen(osdDisplayPort);
32843344
resumeRefreshAt = 0;
3345+
} else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE1)) {
3346+
if (statsPagesCheck == 1) {
3347+
osdShowStatsPage1();
3348+
}
3349+
} else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE2)) {
3350+
if (statsPagesCheck == 1) {
3351+
osdShowStatsPage2();
3352+
}
32853353
} else {
32863354
displayHeartbeat(osdDisplayPort);
32873355
}

0 commit comments

Comments
 (0)