mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 06:15:16 +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:
parent
bfc5832149
commit
3cc398e23e
1 changed files with 45 additions and 2 deletions
|
@ -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,12 +121,38 @@ 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) {
|
||||
if(rssi_channel != 0 && spekChannel != rssi_channel) {
|
||||
spekChannelData[spekChannel] = ((uint32_t)(spekFrame[b - 1] & spek_chan_mask) << 8) + spekFrame[b];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RX_FRAME_COMPLETE;
|
||||
}
|
||||
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue