1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-19 14:25:20 +03:00

Add Synthetic Spektrum RSSI from fade counter

The Spektrum satellites, when in "slave" or "external"
mode, continously output a counter of lost frames.
By keeping track of how quickly this counter is incrementing,
a pseudo-RSSI can be generated.

This patch:
- Adds a calculation method for generating an RSSI figure from
  the Spektrum fade counter.
- Adds a new configuration option, spektrum_rssi_enabled, which
  takes over rssi_channel and feeds the synthetic RSSI into it
  (on Spektrum RX's only)

Known Limitations:
- The fade counter only works with the satellite is in external mode,
   which is *not* the case when it is bound to the TX via the FC. You
   *must* bind the satellite the old-school way using another RX.
- Total signal loss freezes the RSSI figure (it will not indicate 0%)
- Spektrum RSSI is more "sensitive" than other RSSI figures due to
   the fact it is based on packet loss. What this means is that you will
   generally be flying at 100% signal, even near the boundaries of signal
   loss. Signal loss will occur quickly such that if you see anything below
   75% or so you should immediately turn back.

Testing Instructions:
- Bind a speksat using an external RC RX, not via the FC.
- Configure FC using following commands:
set rssi_channel = 9
save
- Fly quadcopter with whatever RSSI reporting mechanism you use.
This commit is contained in:
James Betker 2016-09-10 13:57:42 -07:00
parent bfc5832149
commit 3cc398e23e

View file

@ -55,11 +55,21 @@
#define SPEKTRUM_BAUDRATE 115200
#define SPEKTRUM_MAX_FADE_PER_SEC 40
#define SPEKTRUM_FADE_REPORTS_PER_SEC 2
static uint8_t spek_chan_shift;
static uint8_t spek_chan_mask;
static bool rcFrameComplete = false;
static bool spekHiRes = false;
// Variables used for calculating a signal strength from satellite fade.
// This is time-variant and computed every second based on the fade
// count over the last second.
static uint32_t spek_fade_last_sec = 0; // Stores the timestamp of the last second.
static uint16_t spek_fade_last_sec_count = 0; // Stores the fade count at the last second.
static uint8_t rssi_channel; // Stores the RX RSSI channel.
static volatile uint8_t spekFrame[SPEK_FRAME_SIZE];
static rxRuntimeConfig_t *rxRuntimeConfigPtr;
@ -102,6 +112,8 @@ static uint32_t spekChannelData[SPEKTRUM_MAX_SUPPORTED_CHANNEL_COUNT];
uint8_t spektrumFrameStatus(void)
{
uint8_t b;
uint16_t fade;
uint32_t current_secs;
if (!rcFrameComplete) {
return RX_FRAME_PENDING;
@ -109,10 +121,36 @@ uint8_t spektrumFrameStatus(void)
rcFrameComplete = false;
// Fetch the fade count
fade = (spekFrame[0] << 8) + spekFrame[1];
current_secs = micros() / 1000 / (1000 / SPEKTRUM_FADE_REPORTS_PER_SEC);
if (spek_fade_last_sec == 0) {
// This is the first frame status received.
spek_fade_last_sec_count = fade;
spek_fade_last_sec = current_secs;
} else if(spek_fade_last_sec != current_secs) {
// If the difference is > 1, then we missed several seconds worth of frames and
// should just throw out the fade calc (as it's likely a full signal loss).
if((current_secs - spek_fade_last_sec) == 1) {
if(rssi_channel != 0) {
if (spekHiRes)
spekChannelData[rssi_channel] = 2048 - ((fade - spek_fade_last_sec_count) * 2048 / (SPEKTRUM_MAX_FADE_PER_SEC / SPEKTRUM_FADE_REPORTS_PER_SEC));
else
spekChannelData[rssi_channel] = 1024 - ((fade - spek_fade_last_sec_count) * 1024 / (SPEKTRUM_MAX_FADE_PER_SEC / SPEKTRUM_FADE_REPORTS_PER_SEC));
}
}
spek_fade_last_sec_count = fade;
spek_fade_last_sec = current_secs;
}
for (b = 3; b < SPEK_FRAME_SIZE; b += 2) {
uint8_t spekChannel = 0x0F & (spekFrame[b - 1] >> spek_chan_shift);
if (spekChannel < rxRuntimeConfigPtr->channelCount && spekChannel < SPEKTRUM_MAX_SUPPORTED_CHANNEL_COUNT) {
spekChannelData[spekChannel] = ((uint32_t)(spekFrame[b - 1] & spek_chan_mask) << 8) + spekFrame[b];
if(rssi_channel != 0 && spekChannel != rssi_channel) {
spekChannelData[spekChannel] = ((uint32_t)(spekFrame[b - 1] & spek_chan_mask) << 8) + spekFrame[b];
}
}
}
@ -257,6 +295,11 @@ bool spektrumInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig
}
#endif
rssi_channel = rxConfig->rssi_channel - 1; // -1 because rxConfig->rssi_channel is 1-based and rssi_channel is 0-based.
if (rssi_channel >= rxRuntimeConfig->channelCount) {
rssi_channel = 0;
}
return spektrumPort != NULL;
}
#endif // SERIAL_RX