* dynamic noise floor sampling
This commit is contained in:
@@ -10,6 +10,10 @@ namespace mesh {
|
|||||||
|
|
||||||
#define MAX_RX_DELAY_MILLIS 32000 // 32 seconds
|
#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() {
|
void Dispatcher::begin() {
|
||||||
n_sent_flood = n_sent_direct = 0;
|
n_sent_flood = n_sent_direct = 0;
|
||||||
n_recv_flood = n_recv_direct = 0;
|
n_recv_flood = n_recv_direct = 0;
|
||||||
@@ -36,6 +40,10 @@ uint32_t Dispatcher::getCADFailMaxDuration() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Dispatcher::loop() {
|
void Dispatcher::loop() {
|
||||||
|
if (millisHasNowPassed(next_floor_calib_time)) {
|
||||||
|
_radio->triggerNoiseFloorCalibrate();
|
||||||
|
next_floor_calib_time = futureMillis(NOISE_FLOOR_CALIB_INTERVAL);
|
||||||
|
}
|
||||||
_radio->loop();
|
_radio->loop();
|
||||||
|
|
||||||
// check for radio 'stuck' in mode other than Rx
|
// check for radio 'stuck' in mode other than Rx
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void loop() { }
|
virtual void loop() { }
|
||||||
|
|
||||||
|
virtual int getNoiseFloor() const { return 0; }
|
||||||
|
|
||||||
|
virtual void triggerNoiseFloorCalibrate() { }
|
||||||
|
|
||||||
virtual bool isInRecvMode() const = 0;
|
virtual bool isInRecvMode() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,6 +116,7 @@ class Dispatcher {
|
|||||||
unsigned long next_tx_time;
|
unsigned long next_tx_time;
|
||||||
unsigned long cad_busy_start;
|
unsigned long cad_busy_start;
|
||||||
unsigned long radio_nonrx_start;
|
unsigned long radio_nonrx_start;
|
||||||
|
unsigned long next_floor_calib_time;
|
||||||
bool prev_isrecv_mode;
|
bool prev_isrecv_mode;
|
||||||
uint32_t n_sent_flood, n_sent_direct;
|
uint32_t n_sent_flood, n_sent_direct;
|
||||||
uint32_t n_recv_flood, n_recv_direct;
|
uint32_t n_recv_flood, n_recv_direct;
|
||||||
@@ -129,6 +134,7 @@ protected:
|
|||||||
{
|
{
|
||||||
outbound = NULL; total_air_time = 0; next_tx_time = 0;
|
outbound = NULL; total_air_time = 0; next_tx_time = 0;
|
||||||
cad_busy_start = 0;
|
cad_busy_start = 0;
|
||||||
|
next_floor_calib_time = 0;
|
||||||
_err_flags = 0;
|
_err_flags = 0;
|
||||||
radio_nonrx_start = 0;
|
radio_nonrx_start = 0;
|
||||||
prev_isrecv_mode = true;
|
prev_isrecv_mode = true;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void RadioLibWrapper::begin() {
|
|||||||
setFlag(); // LoRa packet is already received
|
setFlag(); // LoRa packet is already received
|
||||||
}
|
}
|
||||||
|
|
||||||
_noise_floor = -140;
|
_noise_floor = 0;
|
||||||
|
|
||||||
// start average out some samples
|
// start average out some samples
|
||||||
_num_floor_samples = 0;
|
_num_floor_samples = 0;
|
||||||
@@ -47,13 +47,23 @@ void RadioLibWrapper::idle() {
|
|||||||
state = STATE_IDLE; // need another startReceive()
|
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() {
|
void RadioLibWrapper::loop() {
|
||||||
if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
|
if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
|
||||||
if (!isReceivingPacket()) {
|
if (!isReceivingPacket()) {
|
||||||
_num_floor_samples++;
|
int rssi = getCurrentRSSI();
|
||||||
_floor_sample_sum += 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;
|
_noise_floor = _floor_sample_sum / NUM_NOISE_FLOOR_SAMPLES;
|
||||||
_floor_sample_sum = 0;
|
_floor_sample_sum = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ protected:
|
|||||||
void startRecv();
|
void startRecv();
|
||||||
float packetScoreInt(float snr, int sf, int packet_len);
|
float packetScoreInt(float snr, int sf, int packet_len);
|
||||||
virtual bool isReceivingPacket() =0;
|
virtual bool isReceivingPacket() =0;
|
||||||
virtual float getCurrentRSSI() =0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RadioLibWrapper(PhysicalLayer& radio, mesh::MainBoard& board) : _radio(&radio), _board(&board) { n_recv = n_sent = 0; }
|
RadioLibWrapper(PhysicalLayer& radio, mesh::MainBoard& board) : _radio(&radio), _board(&board) { n_recv = n_sent = 0; }
|
||||||
@@ -36,6 +35,11 @@ public:
|
|||||||
return isChannelActive();
|
return isChannelActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual float getCurrentRSSI() =0;
|
||||||
|
|
||||||
|
int getNoiseFloor() const override { return _noise_floor; }
|
||||||
|
void triggerNoiseFloorCalibrate() override;
|
||||||
|
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
uint32_t getPacketsRecv() const { return n_recv; }
|
uint32_t getPacketsRecv() const { return n_recv; }
|
||||||
|
|||||||
Reference in New Issue
Block a user