Skip to content

dynpower: describe the adaptive SNR thresholds - #548

Draft
MUSTARDTIGERFPV wants to merge 1 commit into
ExpressLRS:masterfrom
MUSTARDTIGERFPV:dynpower-4x
Draft

dynpower: describe the adaptive SNR thresholds#548
MUSTARDTIGERFPV wants to merge 1 commit into
ExpressLRS:masterfrom
MUSTARDTIGERFPV:dynpower-4x

Conversation

@MUSTARDTIGERFPV

Copy link
Copy Markdown
Member

The Dynamic Power and Signal Health pages both present the fixed per-rate SNR thresholds as the whole algorithm. Since 4.0 those values are only the starting point, so both pages describe behavior the firmware no longer has.

The algorithm

The TX keeps a 48 sample window (StdevAccumulator.h, WINDOW_SIZE = 48) of the SNR reported by the receiver and derives both thresholds from its mean and standard deviation.

Behavior Source
Lower power at mean + 0.5 x stdev dynpower.cpp, (snr_stat_mean + (snr_stat_stdev / 2)) / 16
Raise power at mean - (scale x stdev) dynpower.cpp, (snr_stat_mean - (snr_stat_stdev * scale_factor_numerator) / 4) / 16
scale is 3.25 at 100% LQ, floors at 0.25 from 85% LQ down numerator 13 to 1 across LQ 100 to 85, std::max(..., 1), over 4
Raise threshold held at least 1dB below the lower threshold snr_thre_up_limit = snr_thre_dn_scaled - SNR1dB
Samples only collected while instantaneous LQ >= 99% if (lq_current >= 99) dynpower_stat_snr.add(snrScaled)
Window cleared on packet rate change dynpower_stat_snr.reset() on RF index change
Raising on SNR also requires a weak signal rssi <= sens + 21 || lq_avg <= 95
More than one level can be added per update, ~2dB each while loop with snrScaled += SNR_SCALE(2)

The 0.5 coefficient is 4.1 specific; 4.0 used 1.5. The page is worded to scope this.

Signal Health table corrections

Two cells did not match the rate tables in common.cpp:

  • 2.4GHz 250Hz lower power 8.5 -> 9.5dB. Rate index 6 is SNR_SCALE(9.5). The Dynamic Power page already said 9.5dB, so the two pages contradicted each other.
  • 900MHz 50Hz raise power 1.0 -> -1.0dB. Rate index 3 is SNR_SCALE(-1).

The other ten cells were checked against the rate tables and are correct. The table intro now says these are starting thresholds and links to the algorithm.

Starting Power

The existing claim is correct but incomplete. Dropping to minimum power is done by ResetPower(), which also runs after a committed configuration change, not only at power up. It deliberately does not lower the power while armed, and with Dynamic Power disabled it applies the configured Max Power instead.

Receiver overload protection

Not previously documented. An RSSI of -5dBm or higher lowers the power one level, and this check sits above the if (!config.GetDynamicPower()) return; guard, so it runs even with Dynamic Power disabled. This is a common source of confusion on the bench.

Smaller fixes

Three boundary conditions were written as strict inequalities but are inclusive in code: the 50% LQ hard limit, the 85% LQ top up, and the FLRC lower power RSSI limit.

The Dynamic Power and Signal Health pages both described the fixed
per-rate SNR thresholds as the whole algorithm. Since 4.0 those values
are only the starting point. The TX keeps a 48 sample window of the
SNR reported by the RX and derives both thresholds from its mean and
standard deviation.

- Lower power at mean + 0.5 x standard deviation in 4.1.
- Raise power at mean - (scale x standard deviation), where scale runs
  from 3.25 at 100% LQ down to a floor of 0.25 at 85% LQ, and the raise
  threshold is held at least 1dB below the lower threshold.
- Samples are only collected while instantaneous LQ is 99% or higher,
  and the window is cleared on a packet rate change.
- Raising on SNR also requires the signal to be weak, and can add more
  than one power level per telemetry update.

Expand Starting Power. Dropping to the minimum power is done by
ResetPower(), which also runs after a committed configuration change,
not only at power up. It deliberately does not lower the power while
armed, and with Dynamic Power disabled it sets the configured Max
Power instead.

Document the receiver overload protection. An RSSI of -5dBm or higher
lowers the power one level, and this runs even when Dynamic Power is
disabled, which is a common source of confusion on the bench.

Also correct two values in the Signal Health tables that did not match
the rate tables in common.cpp:

- 2.4GHz 250Hz lower power is 9.5dB, not 8.5dB. The Dynamic Power page
  already said 9.5dB, so the two pages disagreed.
- 900MHz 50Hz raise power is -1.0dB, not 1.0dB.

Three boundary conditions were stated as strict inequalities but are
inclusive in the code: the 50% LQ hard limit, the 85% LQ top up, and
the FLRC lower power RSSI limit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant