diff --git a/src/Dispatcher.cpp b/src/Dispatcher.cpp index 6412b6a9..06c5e035 100644 --- a/src/Dispatcher.cpp +++ b/src/Dispatcher.cpp @@ -10,6 +10,10 @@ namespace mesh { #define MAX_RX_DELAY_MILLIS 32000 // 32 seconds +#ifndef NOISE_FLOOR_CALIB_INTERVAL + #define NOISE_FLOOR_CALIB_INTERVAL 2000 // 2 seconds +#endif + void Dispatcher::begin() { n_sent_flood = n_sent_direct = 0; n_recv_flood = n_recv_direct = 0; @@ -36,6 +40,10 @@ uint32_t Dispatcher::getCADFailMaxDuration() const { } void Dispatcher::loop() { + if (millisHasNowPassed(next_floor_calib_time)) { + _radio->triggerNoiseFloorCalibrate(); + next_floor_calib_time = futureMillis(NOISE_FLOOR_CALIB_INTERVAL); + } _radio->loop(); // check for radio 'stuck' in mode other than Rx diff --git a/src/Dispatcher.h b/src/Dispatcher.h index 7a48067d..37f327e3 100644 --- a/src/Dispatcher.h +++ b/src/Dispatcher.h @@ -61,6 +61,10 @@ public: */ virtual void loop() { } + virtual int getNoiseFloor() const { return 0; } + + virtual void triggerNoiseFloorCalibrate() { } + virtual bool isInRecvMode() const = 0; /** @@ -112,6 +116,7 @@ class Dispatcher { unsigned long next_tx_time; unsigned long cad_busy_start; unsigned long radio_nonrx_start; + unsigned long next_floor_calib_time; bool prev_isrecv_mode; uint32_t n_sent_flood, n_sent_direct; uint32_t n_recv_flood, n_recv_direct; @@ -129,6 +134,7 @@ protected: { outbound = NULL; total_air_time = 0; next_tx_time = 0; cad_busy_start = 0; + next_floor_calib_time = 0; _err_flags = 0; radio_nonrx_start = 0; prev_isrecv_mode = true; diff --git a/src/helpers/RadioLibWrappers.cpp b/src/helpers/RadioLibWrappers.cpp index d52d81ff..d7b93a2f 100644 --- a/src/helpers/RadioLibWrappers.cpp +++ b/src/helpers/RadioLibWrappers.cpp @@ -35,7 +35,7 @@ void RadioLibWrapper::begin() { setFlag(); // LoRa packet is already received } - _noise_floor = -140; + _noise_floor = 0; // start average out some samples _num_floor_samples = 0; @@ -47,13 +47,23 @@ void RadioLibWrapper::idle() { state = STATE_IDLE; // need another startReceive() } +void RadioLibWrapper::triggerNoiseFloorCalibrate() { + if (_num_floor_samples >= NUM_NOISE_FLOOR_SAMPLES) { // ignore trigger if currently sampling + _num_floor_samples = 0; + _floor_sample_sum = 0; + } +} + void RadioLibWrapper::loop() { if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) { if (!isReceivingPacket()) { - _num_floor_samples++; - _floor_sample_sum += getCurrentRSSI(); + int rssi = getCurrentRSSI(); + if (rssi < _noise_floor + INTERFERENCE_THRESHOLD_DB) { // only consider samples below current floor+THRESHOLD + _num_floor_samples++; + _floor_sample_sum += rssi; + } } - } else if (_floor_sample_sum != 0) { + } else if (_num_floor_samples >= NUM_NOISE_FLOOR_SAMPLES && _floor_sample_sum != 0) { _noise_floor = _floor_sample_sum / NUM_NOISE_FLOOR_SAMPLES; _floor_sample_sum = 0; diff --git a/src/helpers/RadioLibWrappers.h b/src/helpers/RadioLibWrappers.h index 211e0187..9ac7e72c 100644 --- a/src/helpers/RadioLibWrappers.h +++ b/src/helpers/RadioLibWrappers.h @@ -16,7 +16,6 @@ protected: void startRecv(); float packetScoreInt(float snr, int sf, int packet_len); virtual bool isReceivingPacket() =0; - virtual float getCurrentRSSI() =0; public: RadioLibWrapper(PhysicalLayer& radio, mesh::MainBoard& board) : _radio(&radio), _board(&board) { n_recv = n_sent = 0; } @@ -36,6 +35,11 @@ public: return isChannelActive(); } + virtual float getCurrentRSSI() =0; + + int getNoiseFloor() const override { return _noise_floor; } + void triggerNoiseFloorCalibrate() override; + void loop() override; uint32_t getPacketsRecv() const { return n_recv; }