mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-27 02:05:31 +03:00
Added RSNR to the OSD (#11062)
* Added RNSR to the OSD * filtering with pt1 * update pgconfig ver * rssi_smoothness and proper define wrapping * missing define wrap * smoothing moved to updateRSSI * minor comment update * fixed rx tests Co-authored-by: Tony Cabello <> Co-authored-by: J Blackman <blckmn@users.noreply.github.com>
This commit is contained in:
parent
b197d1d6bd
commit
22c5bf4eb3
17 changed files with 215 additions and 64 deletions
|
@ -745,6 +745,7 @@ const clivalue_t valueTable[] = {
|
||||||
{ "rssi_offset", VAR_INT8 | MASTER_VALUE, .config.minmax = { -100, 100 }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_offset) },
|
{ "rssi_offset", VAR_INT8 | MASTER_VALUE, .config.minmax = { -100, 100 }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_offset) },
|
||||||
{ "rssi_invert", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_invert) },
|
{ "rssi_invert", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_invert) },
|
||||||
{ "rssi_src_frame_lpf_period", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, UINT8_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_src_frame_lpf_period) },
|
{ "rssi_src_frame_lpf_period", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, UINT8_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_src_frame_lpf_period) },
|
||||||
|
{ "rssi_smoothing", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, UINT8_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rssi_smoothing) },
|
||||||
|
|
||||||
#ifdef USE_RC_SMOOTHING_FILTER
|
#ifdef USE_RC_SMOOTHING_FILTER
|
||||||
{ PARAM_NAME_RC_SMOOTHING, VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_mode) },
|
{ PARAM_NAME_RC_SMOOTHING, VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, rc_smoothing_mode) },
|
||||||
|
@ -773,11 +774,8 @@ const clivalue_t valueTable[] = {
|
||||||
#if defined(USE_SERIALRX_SBUS)
|
#if defined(USE_SERIALRX_SBUS)
|
||||||
{ "sbus_baud_fast", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, sbus_baud_fast) },
|
{ "sbus_baud_fast", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, sbus_baud_fast) },
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SERIALRX_CRSF)
|
|
||||||
{ "crsf_use_rx_snr", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, crsf_use_rx_snr) },
|
|
||||||
#if defined(USE_CRSF_V3)
|
#if defined(USE_CRSF_V3)
|
||||||
{ "crsf_use_negotiated_baud", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, crsf_use_negotiated_baud) },
|
{ "crsf_use_negotiated_baud", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_RX_CONFIG, offsetof(rxConfig_t, crsf_use_negotiated_baud) },
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
{ "airmode_start_throttle_percent", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_RX_CONFIG, offsetof(rxConfig_t, airModeActivateThreshold) },
|
{ "airmode_start_throttle_percent", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_RX_CONFIG, offsetof(rxConfig_t, airModeActivateThreshold) },
|
||||||
{ "rx_min_usec", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { PWM_PULSE_MIN, PWM_PULSE_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rx_min_usec) },
|
{ "rx_min_usec", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { PWM_PULSE_MIN, PWM_PULSE_MAX }, PG_RX_CONFIG, offsetof(rxConfig_t, rx_min_usec) },
|
||||||
|
@ -1315,7 +1313,10 @@ const clivalue_t valueTable[] = {
|
||||||
{ "osd_link_quality_alarm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_OSD_CONFIG, offsetof(osdConfig_t, link_quality_alarm) },
|
{ "osd_link_quality_alarm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_OSD_CONFIG, offsetof(osdConfig_t, link_quality_alarm) },
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
{ "osd_rssi_dbm_alarm", VAR_INT16 | MASTER_VALUE, .config.minmax = { CRSF_RSSI_MIN, CRSF_SNR_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, rssi_dbm_alarm) },
|
{ "osd_rssi_dbm_alarm", VAR_INT16 | MASTER_VALUE, .config.minmax = { CRSF_RSSI_MIN, CRSF_RSSI_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, rssi_dbm_alarm) },
|
||||||
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
{ "osd_rsnr_alarm", VAR_INT16 | MASTER_VALUE, .config.minmax = { CRSF_SNR_MIN, CRSF_SNR_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, rsnr_alarm) },
|
||||||
#endif
|
#endif
|
||||||
{ "osd_cap_alarm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 20000 }, PG_OSD_CONFIG, offsetof(osdConfig_t, cap_alarm) },
|
{ "osd_cap_alarm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 20000 }, PG_OSD_CONFIG, offsetof(osdConfig_t, cap_alarm) },
|
||||||
{ "osd_alt_alarm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_OSD_CONFIG, offsetof(osdConfig_t, alt_alarm) },
|
{ "osd_alt_alarm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_OSD_CONFIG, offsetof(osdConfig_t, alt_alarm) },
|
||||||
|
@ -1346,6 +1347,9 @@ const clivalue_t valueTable[] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
{ "osd_rssi_dbm_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_RSSI_DBM_VALUE]) },
|
{ "osd_rssi_dbm_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_RSSI_DBM_VALUE]) },
|
||||||
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
{ "osd_rsnr_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_RSNR_VALUE]) },
|
||||||
#endif
|
#endif
|
||||||
{ "osd_tim_1_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_ITEM_TIMER_1]) },
|
{ "osd_tim_1_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_ITEM_TIMER_1]) },
|
||||||
{ "osd_tim_2_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_ITEM_TIMER_2]) },
|
{ "osd_tim_2_pos", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, OSD_POSCFG_MAX }, PG_OSD_ELEMENT_CONFIG, offsetof(osdElementConfig_t, item_pos[OSD_ITEM_TIMER_2]) },
|
||||||
|
|
|
@ -80,6 +80,9 @@ const OSD_Entry menuOsdActiveElemsEntries[] =
|
||||||
{"RSSI", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSSI_VALUE]},
|
{"RSSI", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSSI_VALUE]},
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
{"RSSI DBM", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSSI_DBM_VALUE]},
|
{"RSSI DBM", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSSI_DBM_VALUE]},
|
||||||
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
{"RSNR", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSNR_VALUE]},
|
||||||
#endif
|
#endif
|
||||||
{"BATTERY VOLTAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAIN_BATT_VOLTAGE]},
|
{"BATTERY VOLTAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAIN_BATT_VOLTAGE]},
|
||||||
{"BATTERY USAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAIN_BATT_USAGE]},
|
{"BATTERY USAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAIN_BATT_USAGE]},
|
||||||
|
@ -184,6 +187,7 @@ static CMS_Menu menuOsdActiveElems = {
|
||||||
static uint8_t osdConfig_rssi_alarm;
|
static uint8_t osdConfig_rssi_alarm;
|
||||||
static uint16_t osdConfig_link_quality_alarm;
|
static uint16_t osdConfig_link_quality_alarm;
|
||||||
static int16_t osdConfig_rssi_dbm_alarm;
|
static int16_t osdConfig_rssi_dbm_alarm;
|
||||||
|
static int16_t osdConfig_rsnr_alarm;
|
||||||
static uint16_t osdConfig_cap_alarm;
|
static uint16_t osdConfig_cap_alarm;
|
||||||
static uint16_t osdConfig_alt_alarm;
|
static uint16_t osdConfig_alt_alarm;
|
||||||
static uint16_t osdConfig_distance_alarm;
|
static uint16_t osdConfig_distance_alarm;
|
||||||
|
@ -197,6 +201,7 @@ static const void *menuAlarmsOnEnter(displayPort_t *pDisp)
|
||||||
osdConfig_rssi_alarm = osdConfig()->rssi_alarm;
|
osdConfig_rssi_alarm = osdConfig()->rssi_alarm;
|
||||||
osdConfig_link_quality_alarm = osdConfig()->link_quality_alarm;
|
osdConfig_link_quality_alarm = osdConfig()->link_quality_alarm;
|
||||||
osdConfig_rssi_dbm_alarm = osdConfig()->rssi_dbm_alarm;
|
osdConfig_rssi_dbm_alarm = osdConfig()->rssi_dbm_alarm;
|
||||||
|
osdConfig_rsnr_alarm = osdConfig()->rsnr_alarm;
|
||||||
osdConfig_cap_alarm = osdConfig()->cap_alarm;
|
osdConfig_cap_alarm = osdConfig()->cap_alarm;
|
||||||
osdConfig_alt_alarm = osdConfig()->alt_alarm;
|
osdConfig_alt_alarm = osdConfig()->alt_alarm;
|
||||||
osdConfig_distance_alarm = osdConfig()->distance_alarm;
|
osdConfig_distance_alarm = osdConfig()->distance_alarm;
|
||||||
|
@ -214,6 +219,7 @@ static const void *menuAlarmsOnExit(displayPort_t *pDisp, const OSD_Entry *self)
|
||||||
osdConfigMutable()->rssi_alarm = osdConfig_rssi_alarm;
|
osdConfigMutable()->rssi_alarm = osdConfig_rssi_alarm;
|
||||||
osdConfigMutable()->link_quality_alarm = osdConfig_link_quality_alarm;
|
osdConfigMutable()->link_quality_alarm = osdConfig_link_quality_alarm;
|
||||||
osdConfigMutable()->rssi_dbm_alarm = osdConfig_rssi_dbm_alarm;
|
osdConfigMutable()->rssi_dbm_alarm = osdConfig_rssi_dbm_alarm;
|
||||||
|
osdConfigMutable()->rsnr_alarm = osdConfig_rsnr_alarm;
|
||||||
osdConfigMutable()->cap_alarm = osdConfig_cap_alarm;
|
osdConfigMutable()->cap_alarm = osdConfig_cap_alarm;
|
||||||
osdConfigMutable()->alt_alarm = osdConfig_alt_alarm;
|
osdConfigMutable()->alt_alarm = osdConfig_alt_alarm;
|
||||||
osdConfigMutable()->distance_alarm = osdConfig_distance_alarm;
|
osdConfigMutable()->distance_alarm = osdConfig_distance_alarm;
|
||||||
|
@ -229,6 +235,7 @@ const OSD_Entry menuAlarmsEntries[] =
|
||||||
{"RSSI", OME_UINT8, NULL, &(OSD_UINT8_t){&osdConfig_rssi_alarm, 5, 90, 5}},
|
{"RSSI", OME_UINT8, NULL, &(OSD_UINT8_t){&osdConfig_rssi_alarm, 5, 90, 5}},
|
||||||
{"LINK QUALITY", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_link_quality_alarm, 5, 300, 5}},
|
{"LINK QUALITY", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_link_quality_alarm, 5, 300, 5}},
|
||||||
{"RSSI DBM", OME_INT16, NULL, &(OSD_INT16_t){&osdConfig_rssi_dbm_alarm, CRSF_RSSI_MIN, CRSF_SNR_MAX, 5}},
|
{"RSSI DBM", OME_INT16, NULL, &(OSD_INT16_t){&osdConfig_rssi_dbm_alarm, CRSF_RSSI_MIN, CRSF_SNR_MAX, 5}},
|
||||||
|
{"RSNR", OME_INT16, NULL, &(OSD_INT16_t){&osdConfig_rsnr_alarm, CRSF_SNR_MIN, CRSF_SNR_MAX, 5}},
|
||||||
{"MAIN BAT", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_cap_alarm, 50, 30000, 50}},
|
{"MAIN BAT", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_cap_alarm, 50, 30000, 50}},
|
||||||
{"MAX ALT", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_alt_alarm, 1, 200, 1}},
|
{"MAX ALT", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_alt_alarm, 1, 200, 1}},
|
||||||
{"MAX DISTANCE", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_distance_alarm, 0, UINT16_MAX, 10}},
|
{"MAX DISTANCE", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_distance_alarm, 0, UINT16_MAX, 10}},
|
||||||
|
|
|
@ -149,7 +149,7 @@ escSensorData_t *osdEscDataCombined;
|
||||||
|
|
||||||
STATIC_ASSERT(OSD_POS_MAX == OSD_POS(31,31), OSD_POS_MAX_incorrect);
|
STATIC_ASSERT(OSD_POS_MAX == OSD_POS(31,31), OSD_POS_MAX_incorrect);
|
||||||
|
|
||||||
PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 10);
|
PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 11);
|
||||||
|
|
||||||
PG_REGISTER_WITH_RESET_FN(osdElementConfig_t, osdElementConfig, PG_OSD_ELEMENT_CONFIG, 1);
|
PG_REGISTER_WITH_RESET_FN(osdElementConfig_t, osdElementConfig, PG_OSD_ELEMENT_CONFIG, 1);
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
|
||||||
OSD_STAT_MIN_LINK_QUALITY,
|
OSD_STAT_MIN_LINK_QUALITY,
|
||||||
OSD_STAT_MAX_FFT,
|
OSD_STAT_MAX_FFT,
|
||||||
OSD_STAT_MIN_RSSI_DBM,
|
OSD_STAT_MIN_RSSI_DBM,
|
||||||
|
OSD_STAT_MIN_RSNR,
|
||||||
OSD_STAT_TOTAL_FLIGHTS,
|
OSD_STAT_TOTAL_FLIGHTS,
|
||||||
OSD_STAT_TOTAL_TIME,
|
OSD_STAT_TOTAL_TIME,
|
||||||
OSD_STAT_TOTAL_DIST,
|
OSD_STAT_TOTAL_DIST,
|
||||||
|
@ -344,6 +345,7 @@ void pgResetFn_osdConfig(osdConfig_t *osdConfig)
|
||||||
osdWarnSetState(OSD_WARNING_RSSI, false);
|
osdWarnSetState(OSD_WARNING_RSSI, false);
|
||||||
osdWarnSetState(OSD_WARNING_LINK_QUALITY, false);
|
osdWarnSetState(OSD_WARNING_LINK_QUALITY, false);
|
||||||
osdWarnSetState(OSD_WARNING_RSSI_DBM, false);
|
osdWarnSetState(OSD_WARNING_RSSI_DBM, false);
|
||||||
|
osdWarnSetState(OSD_WARNING_RSNR, false);
|
||||||
// turn off the over mah capacity warning
|
// turn off the over mah capacity warning
|
||||||
osdWarnSetState(OSD_WARNING_OVER_CAP, false);
|
osdWarnSetState(OSD_WARNING_OVER_CAP, false);
|
||||||
|
|
||||||
|
@ -370,6 +372,7 @@ void pgResetFn_osdConfig(osdConfig_t *osdConfig)
|
||||||
osdConfig->profile[i][0] = '\0';
|
osdConfig->profile[i][0] = '\0';
|
||||||
}
|
}
|
||||||
osdConfig->rssi_dbm_alarm = -60;
|
osdConfig->rssi_dbm_alarm = -60;
|
||||||
|
osdConfig->rsnr_alarm = 4;
|
||||||
osdConfig->gps_sats_show_hdop = false;
|
osdConfig->gps_sats_show_hdop = false;
|
||||||
|
|
||||||
for (int i = 0; i < OSD_RCCHANNELS_COUNT; i++) {
|
for (int i = 0; i < OSD_RCCHANNELS_COUNT; i++) {
|
||||||
|
@ -501,7 +504,8 @@ static void osdResetStats(void)
|
||||||
stats.max_esc_temp = 0;
|
stats.max_esc_temp = 0;
|
||||||
stats.max_esc_rpm = 0;
|
stats.max_esc_rpm = 0;
|
||||||
stats.min_link_quality = (linkQualitySource == LQ_SOURCE_NONE) ? 99 : 100; // percent
|
stats.min_link_quality = (linkQualitySource == LQ_SOURCE_NONE) ? 99 : 100; // percent
|
||||||
stats.min_rssi_dbm = CRSF_SNR_MAX;
|
stats.min_rssi_dbm = CRSF_RSSI_MAX;
|
||||||
|
stats.min_rsnr = CRSF_SNR_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_ESC_SENSOR) || defined(USE_DSHOT_TELEMETRY)
|
#if defined(USE_ESC_SENSOR) || defined(USE_DSHOT_TELEMETRY)
|
||||||
|
@ -581,6 +585,13 @@ static void osdUpdateStats(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
value = getRsnr();
|
||||||
|
if (stats.min_rsnr > value) {
|
||||||
|
stats.min_rsnr = value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_GPS
|
#ifdef USE_GPS
|
||||||
if (STATE(GPS_FIX) && STATE(GPS_FIX_HOME)) {
|
if (STATE(GPS_FIX) && STATE(GPS_FIX_HOME)) {
|
||||||
if (stats.max_distance < GPS_distanceToHome) {
|
if (stats.max_distance < GPS_distanceToHome) {
|
||||||
|
@ -876,6 +887,13 @@ static bool osdDisplayStat(int statistic, uint8_t displayRow)
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
case OSD_STAT_MIN_RSNR:
|
||||||
|
tfp_sprintf(buff, "%3d", stats.min_rsnr);
|
||||||
|
osdDisplayStatisticLabel(displayRow, "MIN RSNR", buff);
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PERSISTENT_STATS
|
#ifdef USE_PERSISTENT_STATS
|
||||||
case OSD_STAT_TOTAL_FLIGHTS:
|
case OSD_STAT_TOTAL_FLIGHTS:
|
||||||
itoa(statsConfig()->stats_total_flights, buff, 10);
|
itoa(statsConfig()->stats_total_flights, buff, 10);
|
||||||
|
|
|
@ -164,6 +164,7 @@ typedef enum {
|
||||||
OSD_WATT_HOURS_DRAWN,
|
OSD_WATT_HOURS_DRAWN,
|
||||||
OSD_AUX_VALUE,
|
OSD_AUX_VALUE,
|
||||||
OSD_READY_MODE,
|
OSD_READY_MODE,
|
||||||
|
OSD_RSNR_VALUE,
|
||||||
OSD_ITEM_COUNT // MUST BE LAST
|
OSD_ITEM_COUNT // MUST BE LAST
|
||||||
} osd_items_e;
|
} osd_items_e;
|
||||||
|
|
||||||
|
@ -204,6 +205,7 @@ typedef enum {
|
||||||
OSD_STAT_TOTAL_DIST,
|
OSD_STAT_TOTAL_DIST,
|
||||||
OSD_STAT_MIN_RSSI_DBM,
|
OSD_STAT_MIN_RSSI_DBM,
|
||||||
OSD_STAT_WATT_HOURS_DRAWN,
|
OSD_STAT_WATT_HOURS_DRAWN,
|
||||||
|
OSD_STAT_MIN_RSNR,
|
||||||
OSD_STAT_COUNT // MUST BE LAST
|
OSD_STAT_COUNT // MUST BE LAST
|
||||||
} osd_stats_e;
|
} osd_stats_e;
|
||||||
|
|
||||||
|
@ -249,6 +251,7 @@ typedef enum {
|
||||||
OSD_WARNING_LINK_QUALITY,
|
OSD_WARNING_LINK_QUALITY,
|
||||||
OSD_WARNING_RSSI_DBM,
|
OSD_WARNING_RSSI_DBM,
|
||||||
OSD_WARNING_OVER_CAP,
|
OSD_WARNING_OVER_CAP,
|
||||||
|
OSD_WARNING_RSNR,
|
||||||
OSD_WARNING_COUNT // MUST BE LAST
|
OSD_WARNING_COUNT // MUST BE LAST
|
||||||
} osdWarningsFlags_e;
|
} osdWarningsFlags_e;
|
||||||
|
|
||||||
|
@ -296,6 +299,7 @@ typedef struct osdConfig_s {
|
||||||
char profile[OSD_PROFILE_COUNT][OSD_PROFILE_NAME_LENGTH + 1];
|
char profile[OSD_PROFILE_COUNT][OSD_PROFILE_NAME_LENGTH + 1];
|
||||||
uint16_t link_quality_alarm;
|
uint16_t link_quality_alarm;
|
||||||
int16_t rssi_dbm_alarm;
|
int16_t rssi_dbm_alarm;
|
||||||
|
int16_t rsnr_alarm;
|
||||||
uint8_t gps_sats_show_hdop;
|
uint8_t gps_sats_show_hdop;
|
||||||
int8_t rcChannels[OSD_RCCHANNELS_COUNT]; // RC channel values to display, -1 if none
|
int8_t rcChannels[OSD_RCCHANNELS_COUNT]; // RC channel values to display, -1 if none
|
||||||
uint8_t displayPortDevice; // osdDisplayPortDevice_e
|
uint8_t displayPortDevice; // osdDisplayPortDevice_e
|
||||||
|
@ -338,6 +342,7 @@ typedef struct statistic_s {
|
||||||
int32_t max_esc_rpm;
|
int32_t max_esc_rpm;
|
||||||
uint16_t min_link_quality;
|
uint16_t min_link_quality;
|
||||||
int16_t min_rssi_dbm;
|
int16_t min_rssi_dbm;
|
||||||
|
int16_t min_rsnr;
|
||||||
} statistic_t;
|
} statistic_t;
|
||||||
|
|
||||||
extern timeUs_t resumeRefreshAt;
|
extern timeUs_t resumeRefreshAt;
|
||||||
|
|
|
@ -1384,6 +1384,13 @@ static void osdElementRssiDbm(osdElementParms_t *element)
|
||||||
}
|
}
|
||||||
#endif // USE_RX_RSSI_DBM
|
#endif // USE_RX_RSSI_DBM
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
static void osdElementRsnr(osdElementParms_t *element)
|
||||||
|
{
|
||||||
|
tfp_sprintf(element->buff, "%c%3d", SYM_RSSI, getRsnr());
|
||||||
|
}
|
||||||
|
#endif // USE_RX_RSNR
|
||||||
|
|
||||||
#ifdef USE_OSD_STICK_OVERLAY
|
#ifdef USE_OSD_STICK_OVERLAY
|
||||||
static void osdBackgroundStickOverlay(osdElementParms_t *element)
|
static void osdBackgroundStickOverlay(osdElementParms_t *element)
|
||||||
{
|
{
|
||||||
|
@ -1598,6 +1605,9 @@ static const uint8_t osdElementDisplayOrder[] = {
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
OSD_RSSI_DBM_VALUE,
|
OSD_RSSI_DBM_VALUE,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
OSD_RSNR_VALUE,
|
||||||
|
#endif
|
||||||
#ifdef USE_OSD_STICK_OVERLAY
|
#ifdef USE_OSD_STICK_OVERLAY
|
||||||
OSD_STICK_OVERLAY_LEFT,
|
OSD_STICK_OVERLAY_LEFT,
|
||||||
OSD_STICK_OVERLAY_RIGHT,
|
OSD_STICK_OVERLAY_RIGHT,
|
||||||
|
@ -1724,6 +1734,9 @@ const osdElementDrawFn osdElementDrawFunction[OSD_ITEM_COUNT] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
[OSD_RSSI_DBM_VALUE] = osdElementRssiDbm,
|
[OSD_RSSI_DBM_VALUE] = osdElementRssiDbm,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
[OSD_RSNR_VALUE] = osdElementRsnr,
|
||||||
#endif
|
#endif
|
||||||
[OSD_RC_CHANNELS] = osdElementRcChannels,
|
[OSD_RC_CHANNELS] = osdElementRcChannels,
|
||||||
#ifdef USE_GPS
|
#ifdef USE_GPS
|
||||||
|
|
|
@ -186,6 +186,15 @@ void renderOsdWarning(char *warningText, bool *blinking, uint8_t *displayAttr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif // USE_RX_RSSI_DBM
|
#endif // USE_RX_RSSI_DBM
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
// rsnr
|
||||||
|
if (osdWarnGetState(OSD_WARNING_RSNR) && (getRsnr() < osdConfig()->rsnr_alarm)) {
|
||||||
|
tfp_sprintf(warningText, "RSNR LOW");
|
||||||
|
*displayAttr = DISPLAYPORT_ATTR_WARNING;
|
||||||
|
*blinking = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // USE_RX_RSNR
|
||||||
|
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
// Link Quality
|
// Link Quality
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "rx/rx.h"
|
#include "rx/rx.h"
|
||||||
#include "rx/rx_spi.h"
|
#include "rx/rx_spi.h"
|
||||||
|
|
||||||
PG_REGISTER_WITH_RESET_FN(rxConfig_t, rxConfig, PG_RX_CONFIG, 3);
|
PG_REGISTER_WITH_RESET_FN(rxConfig_t, rxConfig, PG_RX_CONFIG, 4);
|
||||||
void pgResetFn_rxConfig(rxConfig_t *rxConfig)
|
void pgResetFn_rxConfig(rxConfig_t *rxConfig)
|
||||||
{
|
{
|
||||||
RESET_CONFIG_2(rxConfig_t, rxConfig,
|
RESET_CONFIG_2(rxConfig_t, rxConfig,
|
||||||
|
@ -56,6 +56,7 @@ void pgResetFn_rxConfig(rxConfig_t *rxConfig)
|
||||||
.rssi_offset = 0,
|
.rssi_offset = 0,
|
||||||
.rssi_invert = 0,
|
.rssi_invert = 0,
|
||||||
.rssi_src_frame_lpf_period = 30,
|
.rssi_src_frame_lpf_period = 30,
|
||||||
|
.rssi_smoothing = 125,
|
||||||
.fpvCamAngleDegrees = 0,
|
.fpvCamAngleDegrees = 0,
|
||||||
.airModeActivateThreshold = 25,
|
.airModeActivateThreshold = 25,
|
||||||
.max_aux_channel = DEFAULT_AUX_CHANNEL_COUNT,
|
.max_aux_channel = DEFAULT_AUX_CHANNEL_COUNT,
|
||||||
|
@ -69,7 +70,6 @@ void pgResetFn_rxConfig(rxConfig_t *rxConfig)
|
||||||
.srxl2_unit_id = 1,
|
.srxl2_unit_id = 1,
|
||||||
.srxl2_baud_fast = true,
|
.srxl2_baud_fast = true,
|
||||||
.sbus_baud_fast = false,
|
.sbus_baud_fast = false,
|
||||||
.crsf_use_rx_snr = false,
|
|
||||||
.msp_override_channels_mask = 0,
|
.msp_override_channels_mask = 0,
|
||||||
.crsf_use_negotiated_baud = false,
|
.crsf_use_negotiated_baud = false,
|
||||||
);
|
);
|
||||||
|
|
|
@ -57,10 +57,10 @@ typedef struct rxConfig_s {
|
||||||
uint8_t rc_smoothing_auto_factor_rpy; // Used to adjust the "smoothness" determined by the auto cutoff calculations
|
uint8_t rc_smoothing_auto_factor_rpy; // Used to adjust the "smoothness" determined by the auto cutoff calculations
|
||||||
uint8_t rc_smoothing_auto_factor_throttle; // Used to adjust the "smoothness" determined by the auto cutoff calculations
|
uint8_t rc_smoothing_auto_factor_throttle; // Used to adjust the "smoothness" determined by the auto cutoff calculations
|
||||||
uint8_t rssi_src_frame_lpf_period; // Period of the cutoff frequency for the source frame RSSI filter (in 0.1 s)
|
uint8_t rssi_src_frame_lpf_period; // Period of the cutoff frequency for the source frame RSSI filter (in 0.1 s)
|
||||||
|
uint8_t rssi_smoothing; // Smoothing factor to reduce jumpiness of rssi, rssiDbm and rsnr
|
||||||
uint8_t srxl2_unit_id; // Spektrum SRXL2 RX unit id
|
uint8_t srxl2_unit_id; // Spektrum SRXL2 RX unit id
|
||||||
uint8_t srxl2_baud_fast; // Select Spektrum SRXL2 fast baud rate
|
uint8_t srxl2_baud_fast; // Select Spektrum SRXL2 fast baud rate
|
||||||
uint8_t sbus_baud_fast; // Select SBus fast baud rate
|
uint8_t sbus_baud_fast; // Select SBus fast baud rate
|
||||||
uint8_t crsf_use_rx_snr; // Use RX SNR (in dB) instead of RSSI dBm for CRSF
|
|
||||||
uint32_t msp_override_channels_mask; // Channels to override when the MSP override mode is enabled
|
uint32_t msp_override_channels_mask; // Channels to override when the MSP override mode is enabled
|
||||||
uint8_t crsf_use_negotiated_baud; // Use negotiated baud rate for CRSF V3
|
uint8_t crsf_use_negotiated_baud; // Use negotiated baud rate for CRSF V3
|
||||||
} rxConfig_t;
|
} rxConfig_t;
|
||||||
|
|
|
@ -229,24 +229,17 @@ static void handleCrsfLinkStatisticsFrame(const crsfLinkStatistics_t* statsPtr,
|
||||||
lastLinkStatisticsFrameUs = currentTimeUs;
|
lastLinkStatisticsFrameUs = currentTimeUs;
|
||||||
int16_t rssiDbm = -1 * (stats.active_antenna ? stats.uplink_RSSI_2 : stats.uplink_RSSI_1);
|
int16_t rssiDbm = -1 * (stats.active_antenna ? stats.uplink_RSSI_2 : stats.uplink_RSSI_1);
|
||||||
if (rssiSource == RSSI_SOURCE_RX_PROTOCOL_CRSF) {
|
if (rssiSource == RSSI_SOURCE_RX_PROTOCOL_CRSF) {
|
||||||
if (rxConfig()->crsf_use_rx_snr) {
|
const uint16_t rssiPercentScaled = scaleRange(rssiDbm, CRSF_RSSI_MIN, CRSF_RSSI_MAX, 0, RSSI_MAX_VALUE);
|
||||||
// -10dB of SNR mapped to 0 RSSI (fail safe is likely to happen at this measure)
|
setRssi(rssiPercentScaled, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
||||||
// 0dB of SNR mapped to 20 RSSI (default alarm)
|
|
||||||
// 41dB of SNR mapped to 99 RSSI (SNR can climb to around 60, but showing that is not very meaningful)
|
|
||||||
const uint16_t rsnrPercentScaled = constrain((stats.uplink_SNR + 10) * 20, 0, RSSI_MAX_VALUE);
|
|
||||||
setRssi(rsnrPercentScaled, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
|
||||||
#ifdef USE_RX_RSSI_DBM
|
|
||||||
rssiDbm = stats.uplink_SNR;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
const uint16_t rssiPercentScaled = scaleRange(rssiDbm, CRSF_RSSI_MIN, 0, 0, RSSI_MAX_VALUE);
|
|
||||||
setRssi(rssiPercentScaled, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
setRssiDbm(rssiDbm, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
setRssiDbm(rssiDbm, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
setRsnr(stats.uplink_SNR);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
if (linkQualitySource == LQ_SOURCE_RX_PROTOCOL_CRSF) {
|
if (linkQualitySource == LQ_SOURCE_RX_PROTOCOL_CRSF) {
|
||||||
setLinkQualityDirect(stats.uplink_Link_quality);
|
setLinkQualityDirect(stats.uplink_Link_quality);
|
||||||
|
@ -284,12 +277,13 @@ static void handleCrsfLinkStatisticsTxFrame(const crsfLinkStatisticsTx_t* statsP
|
||||||
}
|
}
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
int16_t rssiDbm = -1 * stats.uplink_RSSI;
|
int16_t rssiDbm = -1 * stats.uplink_RSSI;
|
||||||
if (rxConfig()->crsf_use_rx_snr) {
|
|
||||||
rssiDbm = stats.uplink_SNR;
|
|
||||||
}
|
|
||||||
setRssiDbm(rssiDbm, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
setRssiDbm(rssiDbm, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
setRsnr(stats.uplink_SNR);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
if (linkQualitySource == LQ_SOURCE_RX_PROTOCOL_CRSF) {
|
if (linkQualitySource == LQ_SOURCE_RX_PROTOCOL_CRSF) {
|
||||||
setLinkQualityDirect(stats.uplink_Link_quality);
|
setLinkQualityDirect(stats.uplink_Link_quality);
|
||||||
|
@ -312,11 +306,10 @@ static void crsfCheckRssi(uint32_t currentTimeUs)
|
||||||
if (rssiSource == RSSI_SOURCE_RX_PROTOCOL_CRSF) {
|
if (rssiSource == RSSI_SOURCE_RX_PROTOCOL_CRSF) {
|
||||||
setRssiDirect(0, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
setRssiDirect(0, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
if (rxConfig()->crsf_use_rx_snr) {
|
setRssiDbmDirect(CRSF_RSSI_MIN, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
||||||
setRssiDbmDirect(CRSF_SNR_MIN, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
#endif
|
||||||
} else {
|
#ifdef USE_RX_RSNR
|
||||||
setRssiDbmDirect(CRSF_RSSI_MIN, RSSI_SOURCE_RX_PROTOCOL_CRSF);
|
setRsnrDirect(CRSF_SNR_MIN);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
|
|
|
@ -79,7 +79,10 @@ static uint8_t txPower = 0;
|
||||||
static uint8_t wideSwitchIndex = 0;
|
static uint8_t wideSwitchIndex = 0;
|
||||||
static uint8_t currTlmDenom = 1;
|
static uint8_t currTlmDenom = 1;
|
||||||
static simpleLowpassFilter_t rssiFilter;
|
static simpleLowpassFilter_t rssiFilter;
|
||||||
static meanAccumulator_t snrFilter;
|
#ifdef USE_RX_RSNR
|
||||||
|
static simpleLowpassFilter_t rsnrFilter;
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
static meanAccumulator_t snrFilter; //for dyn power purposes
|
||||||
|
|
||||||
static volatile DMA_DATA uint8_t dmaBuffer[ELRS_RX_TX_BUFF_SIZE];
|
static volatile DMA_DATA uint8_t dmaBuffer[ELRS_RX_TX_BUFF_SIZE];
|
||||||
static volatile DMA_DATA uint8_t telemetryPacket[ELRS_RX_TX_BUFF_SIZE];
|
static volatile DMA_DATA uint8_t telemetryPacket[ELRS_RX_TX_BUFF_SIZE];
|
||||||
|
@ -89,6 +92,9 @@ static volatile uint8_t *payload;
|
||||||
static void rssiFilterReset(void)
|
static void rssiFilterReset(void)
|
||||||
{
|
{
|
||||||
simpleLPFilterInit(&rssiFilter, 2, 5);
|
simpleLPFilterInit(&rssiFilter, 2, 5);
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
simpleLPFilterInit(&rsnrFilter, 2, 5);
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PACKET_HANDLING_TO_TOCK_ISR_DELAY_US 250
|
#define PACKET_HANDLING_TO_TOCK_ISR_DELAY_US 250
|
||||||
|
@ -568,6 +574,9 @@ static void initializeReceiver(void)
|
||||||
receiver.configChanged = false;
|
receiver.configChanged = false;
|
||||||
receiver.rssi = 0;
|
receiver.rssi = 0;
|
||||||
receiver.rssiFiltered = 0;
|
receiver.rssiFiltered = 0;
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
receiver.rsnrFiltered = 0;
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
receiver.snr = 0;
|
receiver.snr = 0;
|
||||||
receiver.uplinkLQ = 0;
|
receiver.uplinkLQ = 0;
|
||||||
receiver.rateIndex = receiver.inBindingMode ? bindingRateIndex : rxExpressLrsSpiConfig()->rateIndex;
|
receiver.rateIndex = receiver.inBindingMode ? bindingRateIndex : rxExpressLrsSpiConfig()->rateIndex;
|
||||||
|
@ -948,6 +957,9 @@ static void handleConnectionStateUpdate(const uint32_t timeStampMs)
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
setRssiDbmDirect(-130, RSSI_SOURCE_RX_PROTOCOL);
|
setRssiDbmDirect(-130, RSSI_SOURCE_RX_PROTOCOL);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
setRsnrDirect(-30);
|
||||||
|
#endif
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
setLinkQualityDirect(0);
|
setLinkQualityDirect(0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1015,6 +1027,10 @@ static void handleLinkStatsUpdate(const uint32_t timeStampMs)
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
setRssiDbm(receiver.rssiFiltered, RSSI_SOURCE_RX_PROTOCOL);
|
setRssiDbm(receiver.rssiFiltered, RSSI_SOURCE_RX_PROTOCOL);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
receiver.rsnrFiltered = simpleLPFilterUpdate(&rsnrFilter, receiver.snr/4);
|
||||||
|
setRsnr(receiver.rsnrFiltered);
|
||||||
|
#endif
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
setLinkQualityDirect(receiver.uplinkLQ);
|
setLinkQualityDirect(receiver.uplinkLQ);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1026,6 +1042,9 @@ static void handleLinkStatsUpdate(const uint32_t timeStampMs)
|
||||||
#ifdef USE_RX_RSSI_DBM
|
#ifdef USE_RX_RSSI_DBM
|
||||||
setRssiDbmDirect(-130, RSSI_SOURCE_RX_PROTOCOL);
|
setRssiDbmDirect(-130, RSSI_SOURCE_RX_PROTOCOL);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
setRsnrDirect(-30);
|
||||||
|
#endif
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
setLinkQualityDirect(0);
|
setLinkQualityDirect(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,6 +68,9 @@ typedef struct elrsReceiver_s {
|
||||||
int8_t rssi;
|
int8_t rssi;
|
||||||
int8_t snr;
|
int8_t snr;
|
||||||
int8_t rssiFiltered;
|
int8_t rssiFiltered;
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
int8_t rsnrFiltered;
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
|
||||||
uint8_t uplinkLQ;
|
uint8_t uplinkLQ;
|
||||||
|
|
||||||
|
|
119
src/main/rx/rx.c
119
src/main/rx/rx.c
|
@ -76,10 +76,26 @@
|
||||||
const char rcChannelLetters[] = "AERT12345678abcdefgh";
|
const char rcChannelLetters[] = "AERT12345678abcdefgh";
|
||||||
|
|
||||||
static uint16_t rssi = 0; // range: [0;1023]
|
static uint16_t rssi = 0; // range: [0;1023]
|
||||||
static int16_t rssiDbm = CRSF_RSSI_MIN; // range: [-130,20]
|
static uint16_t rssiRaw = 0; // range: [0;1023]
|
||||||
|
static timeUs_t lastRssiSmoothingUs = 0;
|
||||||
|
#ifdef USE_RX_RSSI_DBM
|
||||||
|
static int16_t rssiDbm = CRSF_RSSI_MIN; // range: [-130,0]
|
||||||
|
static int16_t rssiDbmRaw = CRSF_RSSI_MIN; // range: [-130,0]
|
||||||
|
#endif //USE_RX_RSSI_DBM
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
static int16_t rsnr = CRSF_SNR_MIN; // range: [-30,20]
|
||||||
|
static int16_t rsnrRaw = CRSF_SNR_MIN; // range: [-30,20]
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
static timeUs_t lastMspRssiUpdateUs = 0;
|
static timeUs_t lastMspRssiUpdateUs = 0;
|
||||||
|
|
||||||
static pt1Filter_t frameErrFilter;
|
static pt1Filter_t frameErrFilter;
|
||||||
|
static pt1Filter_t rssiFilter;
|
||||||
|
#ifdef USE_RX_RSSI_DBM
|
||||||
|
static pt1Filter_t rssiDbmFilter;
|
||||||
|
#endif //USE_RX_RSSI_DBM
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
static pt1Filter_t rsnrFilter;
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
static uint16_t linkQuality = 0;
|
static uint16_t linkQuality = 0;
|
||||||
|
@ -362,6 +378,19 @@ void rxInit(void)
|
||||||
// Setup source frame RSSI filtering to take averaged values every FRAME_ERR_RESAMPLE_US
|
// Setup source frame RSSI filtering to take averaged values every FRAME_ERR_RESAMPLE_US
|
||||||
pt1FilterInit(&frameErrFilter, pt1FilterGain(GET_FRAME_ERR_LPF_FREQUENCY(rxConfig()->rssi_src_frame_lpf_period), FRAME_ERR_RESAMPLE_US/1000000.0));
|
pt1FilterInit(&frameErrFilter, pt1FilterGain(GET_FRAME_ERR_LPF_FREQUENCY(rxConfig()->rssi_src_frame_lpf_period), FRAME_ERR_RESAMPLE_US/1000000.0));
|
||||||
|
|
||||||
|
// Configurable amount of filtering to remove excessive jumpiness of the values on the osd
|
||||||
|
float k = (256.0f - rxConfig()->rssi_smoothing) / 256.0f;
|
||||||
|
|
||||||
|
pt1FilterInit(&rssiFilter, k);
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSSI_DBM
|
||||||
|
pt1FilterInit(&rssiDbmFilter, k);
|
||||||
|
#endif //USE_RX_RSSI_DBM
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
pt1FilterInit(&rsnrFilter, k);
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
|
||||||
rxChannelCount = MIN(rxConfig()->max_aux_channel + NON_AUX_CHANNEL_COUNT, rxRuntimeState.channelCount);
|
rxChannelCount = MIN(rxConfig()->max_aux_channel + NON_AUX_CHANNEL_COUNT, rxRuntimeState.channelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,20 +793,7 @@ void setRssiDirect(uint16_t newRssi, rssiSource_e source)
|
||||||
}
|
}
|
||||||
|
|
||||||
rssi = newRssi;
|
rssi = newRssi;
|
||||||
}
|
rssiRaw = newRssi;
|
||||||
|
|
||||||
#define RSSI_SAMPLE_COUNT 16
|
|
||||||
|
|
||||||
static uint16_t updateRssiSamples(uint16_t value)
|
|
||||||
{
|
|
||||||
static uint16_t samples[RSSI_SAMPLE_COUNT];
|
|
||||||
static uint8_t sampleIndex = 0;
|
|
||||||
static unsigned sum = 0;
|
|
||||||
|
|
||||||
sum += value - samples[sampleIndex];
|
|
||||||
samples[sampleIndex] = value;
|
|
||||||
sampleIndex = (sampleIndex + 1) % RSSI_SAMPLE_COUNT;
|
|
||||||
return sum / RSSI_SAMPLE_COUNT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRssi(uint16_t rssiValue, rssiSource_e source)
|
void setRssi(uint16_t rssiValue, rssiSource_e source)
|
||||||
|
@ -788,10 +804,9 @@ void setRssi(uint16_t rssiValue, rssiSource_e source)
|
||||||
|
|
||||||
// Filter RSSI value
|
// Filter RSSI value
|
||||||
if (source == RSSI_SOURCE_FRAME_ERRORS) {
|
if (source == RSSI_SOURCE_FRAME_ERRORS) {
|
||||||
rssi = pt1FilterApply(&frameErrFilter, rssiValue);
|
rssiRaw = pt1FilterApply(&frameErrFilter, rssiValue);
|
||||||
} else {
|
} else {
|
||||||
// calculate new sample mean
|
rssiRaw = rssiValue;
|
||||||
rssi = updateRssiSamples(rssiValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,6 +867,37 @@ void updateRSSI(timeUs_t currentTimeUs)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmpTimeUs(currentTimeUs, lastRssiSmoothingUs) > 250000) { // 0.25s
|
||||||
|
lastRssiSmoothingUs = currentTimeUs;
|
||||||
|
} else {
|
||||||
|
if (lastRssiSmoothingUs != currentTimeUs) { // avoid div by 0
|
||||||
|
float k = (256.0f - rxConfig()->rssi_smoothing) / 256.0f;
|
||||||
|
float factor = ((currentTimeUs - lastRssiSmoothingUs) / 1000000.0f) / (1.0f / 4.0f);
|
||||||
|
float k2 = (k * factor) / ((k * factor) - k + 1);
|
||||||
|
|
||||||
|
if (rssi != rssiRaw) {
|
||||||
|
pt1FilterUpdateCutoff(&rssiFilter, k2);
|
||||||
|
rssi = pt1FilterApply(&rssiFilter, rssiRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSSI_DBM
|
||||||
|
if (rssiDbm != rssiDbmRaw) {
|
||||||
|
pt1FilterUpdateCutoff(&rssiDbmFilter, k2);
|
||||||
|
rssiDbm = pt1FilterApply(&rssiDbmFilter, rssiDbmRaw);
|
||||||
|
}
|
||||||
|
#endif //USE_RX_RSSI_DBM
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
if (rsnr != rsnrRaw) {
|
||||||
|
pt1FilterUpdateCutoff(&rsnrFilter, k2);
|
||||||
|
rsnr = pt1FilterApply(&rsnrFilter, rsnrRaw);
|
||||||
|
}
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
|
||||||
|
lastRssiSmoothingUs = currentTimeUs;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getRssi(void)
|
uint16_t getRssi(void)
|
||||||
|
@ -871,32 +917,19 @@ uint8_t getRssiPercent(void)
|
||||||
return scaleRange(getRssi(), 0, RSSI_MAX_VALUE, 0, 100);
|
return scaleRange(getRssi(), 0, RSSI_MAX_VALUE, 0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSSI_DBM
|
||||||
int16_t getRssiDbm(void)
|
int16_t getRssiDbm(void)
|
||||||
{
|
{
|
||||||
return rssiDbm;
|
return rssiDbm;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RSSI_SAMPLE_COUNT_DBM 16
|
|
||||||
|
|
||||||
static int16_t updateRssiDbmSamples(int16_t value)
|
|
||||||
{
|
|
||||||
static int16_t samplesdbm[RSSI_SAMPLE_COUNT_DBM];
|
|
||||||
static uint8_t sampledbmIndex = 0;
|
|
||||||
static int sumdbm = 0;
|
|
||||||
|
|
||||||
sumdbm += value - samplesdbm[sampledbmIndex];
|
|
||||||
samplesdbm[sampledbmIndex] = value;
|
|
||||||
sampledbmIndex = (sampledbmIndex + 1) % RSSI_SAMPLE_COUNT_DBM;
|
|
||||||
return sumdbm / RSSI_SAMPLE_COUNT_DBM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRssiDbm(int16_t rssiDbmValue, rssiSource_e source)
|
void setRssiDbm(int16_t rssiDbmValue, rssiSource_e source)
|
||||||
{
|
{
|
||||||
if (source != rssiSource) {
|
if (source != rssiSource) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rssiDbm = updateRssiDbmSamples(rssiDbmValue);
|
rssiDbmRaw = rssiDbmValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRssiDbmDirect(int16_t newRssiDbm, rssiSource_e source)
|
void setRssiDbmDirect(int16_t newRssiDbm, rssiSource_e source)
|
||||||
|
@ -906,7 +939,27 @@ void setRssiDbmDirect(int16_t newRssiDbm, rssiSource_e source)
|
||||||
}
|
}
|
||||||
|
|
||||||
rssiDbm = newRssiDbm;
|
rssiDbm = newRssiDbm;
|
||||||
|
rssiDbmRaw = newRssiDbm;
|
||||||
}
|
}
|
||||||
|
#endif //USE_RX_RSSI_DBM
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
int16_t getRsnr(void)
|
||||||
|
{
|
||||||
|
return rsnr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRsnr(int16_t rsnrValue)
|
||||||
|
{
|
||||||
|
rsnrRaw = rsnrValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRsnrDirect(int16_t newRsnr)
|
||||||
|
{
|
||||||
|
rsnr = newRsnr;
|
||||||
|
rsnrRaw = newRsnr;
|
||||||
|
}
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
|
||||||
#ifdef USE_RX_LINK_QUALITY_INFO
|
#ifdef USE_RX_LINK_QUALITY_INFO
|
||||||
uint16_t rxGetLinkQuality(void)
|
uint16_t rxGetLinkQuality(void)
|
||||||
|
|
|
@ -201,9 +201,17 @@ uint16_t rxGetLinkQuality(void);
|
||||||
void setLinkQualityDirect(uint16_t linkqualityValue);
|
void setLinkQualityDirect(uint16_t linkqualityValue);
|
||||||
uint16_t rxGetLinkQualityPercent(void);
|
uint16_t rxGetLinkQualityPercent(void);
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSSI_DBM
|
||||||
int16_t getRssiDbm(void);
|
int16_t getRssiDbm(void);
|
||||||
void setRssiDbm(int16_t newRssiDbm, rssiSource_e source);
|
void setRssiDbm(int16_t newRssiDbm, rssiSource_e source);
|
||||||
void setRssiDbmDirect(int16_t newRssiDbm, rssiSource_e source);
|
void setRssiDbmDirect(int16_t newRssiDbm, rssiSource_e source);
|
||||||
|
#endif //USE_RX_RSSI_DBM
|
||||||
|
|
||||||
|
#ifdef USE_RX_RSNR
|
||||||
|
int16_t getRsnr(void);
|
||||||
|
void setRsnr(int16_t newRsnr);
|
||||||
|
void setRsnrDirect(int16_t newRsnr);
|
||||||
|
#endif //USE_RX_RSNR
|
||||||
|
|
||||||
void rxSetRfMode(uint8_t rfModeValue);
|
void rxSetRfMode(uint8_t rfModeValue);
|
||||||
uint8_t rxGetRfMode(void);
|
uint8_t rxGetRfMode(void);
|
||||||
|
|
|
@ -362,6 +362,7 @@ extern uint8_t _dmaram_end__;
|
||||||
#define USE_RX_MSP
|
#define USE_RX_MSP
|
||||||
#define USE_ESC_SENSOR_INFO
|
#define USE_ESC_SENSOR_INFO
|
||||||
#define USE_RX_RSSI_DBM
|
#define USE_RX_RSSI_DBM
|
||||||
|
#define USE_RX_RSNR
|
||||||
|
|
||||||
#if !defined(CLOUD_BUILD)
|
#if !defined(CLOUD_BUILD)
|
||||||
#define USE_CRSF_CMS_TELEMETRY
|
#define USE_CRSF_CMS_TELEMETRY
|
||||||
|
|
|
@ -606,6 +606,12 @@ extern "C" {
|
||||||
UNUSED(k);
|
UNUSED(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pt1FilterUpdateCutoff(pt1Filter_t *filter, float k)
|
||||||
|
{
|
||||||
|
UNUSED(filter);
|
||||||
|
UNUSED(k);
|
||||||
|
}
|
||||||
|
|
||||||
float pt1FilterApply(pt1Filter_t *filter, float input)
|
float pt1FilterApply(pt1Filter_t *filter, float input)
|
||||||
{
|
{
|
||||||
UNUSED(filter);
|
UNUSED(filter);
|
||||||
|
|
|
@ -253,6 +253,12 @@ void pt1FilterInit(pt1Filter_t *filter, float k)
|
||||||
UNUSED(k);
|
UNUSED(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pt1FilterUpdateCutoff(pt1Filter_t *filter, float k)
|
||||||
|
{
|
||||||
|
UNUSED(filter);
|
||||||
|
UNUSED(k);
|
||||||
|
}
|
||||||
|
|
||||||
float pt1FilterApply(pt1Filter_t *filter, float input)
|
float pt1FilterApply(pt1Filter_t *filter, float input)
|
||||||
{
|
{
|
||||||
UNUSED(filter);
|
UNUSED(filter);
|
||||||
|
|
|
@ -259,6 +259,12 @@ extern "C" {
|
||||||
UNUSED(k);
|
UNUSED(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pt1FilterUpdateCutoff(pt1Filter_t *filter, float k)
|
||||||
|
{
|
||||||
|
UNUSED(filter);
|
||||||
|
UNUSED(k);
|
||||||
|
}
|
||||||
|
|
||||||
float pt1FilterApply(pt1Filter_t *filter, float input)
|
float pt1FilterApply(pt1Filter_t *filter, float input)
|
||||||
{
|
{
|
||||||
UNUSED(filter);
|
UNUSED(filter);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue