|
|
|
@ -14,10 +14,11 @@ |
|
|
|
// ambient CAD auto-calibration: probe CAD periodically while idle, and raise/lower detPeak
|
|
|
|
// so ambient activity (sub-decode-threshold distant traffic, interference) stops tripping LBT
|
|
|
|
#define CAD_PROBE_INTERVAL 4000 // millis between ambient CAD probes
|
|
|
|
#define CAD_PROBE_WINDOW 32 // probes per evaluation window
|
|
|
|
#define CAD_PROBE_RAISE_HITS 10 // >= ~30% ambient detect rate -> desensitize
|
|
|
|
#define CAD_PROBE_LOWER_HITS 3 // <= ~10% ambient detect rate -> re-sensitize
|
|
|
|
#define CAD_PEAK_OFFSET_MAX 10 |
|
|
|
#define CAD_PROBE_INTERVAL_QUIET 16000 // slower probing while offset is 0 and channel is clean
|
|
|
|
#define CAD_PROBE_WINDOW 16 // probes per evaluation window
|
|
|
|
#define CAD_PROBE_RAISE_HITS 5 // >= ~30% ambient detect rate -> desensitize
|
|
|
|
#define CAD_PROBE_LOWER_HITS 2 // <= ~12% ambient detect rate -> re-sensitize
|
|
|
|
#define CAD_PEAK_OFFSET_MAX 6 |
|
|
|
|
|
|
|
static volatile uint8_t state = STATE_IDLE; |
|
|
|
|
|
|
|
@ -49,6 +50,7 @@ void RadioLibWrapper::begin() { |
|
|
|
_cad_probe_count = _cad_probe_hits = 0; |
|
|
|
_cad_last_count = _cad_last_hits = 0; |
|
|
|
_last_cad_probe = 0; |
|
|
|
_cad_probe_interval = CAD_PROBE_INTERVAL; |
|
|
|
|
|
|
|
// start average out some samples
|
|
|
|
_num_floor_samples = 0; |
|
|
|
@ -116,7 +118,7 @@ void RadioLibWrapper::loop() { |
|
|
|
} |
|
|
|
|
|
|
|
if (_cad_enabled && state == STATE_RX && getCADDetPeakBase() > 0 |
|
|
|
&& millis() - _last_cad_probe >= CAD_PROBE_INTERVAL) { |
|
|
|
&& millis() - _last_cad_probe >= _cad_probe_interval) { |
|
|
|
_last_cad_probe = millis(); |
|
|
|
if (!isReceivingPacket()) { |
|
|
|
int16_t result = performChannelScan(); |
|
|
|
@ -130,6 +132,7 @@ void RadioLibWrapper::loop() { |
|
|
|
} else if (result == RADIOLIB_LORA_DETECTED || result == RADIOLIB_PREAMBLE_DETECTED) { |
|
|
|
_cad_probe_count++; |
|
|
|
_cad_probe_hits++; |
|
|
|
_cad_probe_interval = CAD_PROBE_INTERVAL; // activity -> resume fast probing
|
|
|
|
} |
|
|
|
// else: scan error, don't count the sample
|
|
|
|
|
|
|
|
@ -143,10 +146,14 @@ void RadioLibWrapper::loop() { |
|
|
|
_cad_probe_count = _cad_probe_hits = 0; |
|
|
|
} else if (_cad_probe_count >= CAD_PROBE_WINDOW) { |
|
|
|
if (_cad_probe_hits <= CAD_PROBE_LOWER_HITS && _cad_peak_offset > 0) { |
|
|
|
_cad_peak_offset--; |
|
|
|
// step down twice as fast when the window was completely clean
|
|
|
|
_cad_peak_offset -= (_cad_probe_hits == 0 && _cad_peak_offset >= 2) ? 2 : 1; |
|
|
|
MESH_DEBUG_PRINTLN("RadioLibWrapper: CAD ambient %d/%d, detPeak offset -> %d", |
|
|
|
(int)_cad_probe_hits, (int)_cad_probe_count, (int)_cad_peak_offset); |
|
|
|
} |
|
|
|
if (_cad_probe_hits == 0 && _cad_peak_offset == 0) { |
|
|
|
_cad_probe_interval = CAD_PROBE_INTERVAL_QUIET; // idle channel, probe less often
|
|
|
|
} |
|
|
|
_cad_last_hits = _cad_probe_hits; _cad_last_count = _cad_probe_count; |
|
|
|
_cad_probe_count = _cad_probe_hits = 0; |
|
|
|
} |
|
|
|
|