diff --git a/Boards.h b/Boards.h index eaee2d5..ef2b8c5 100644 --- a/Boards.h +++ b/Boards.h @@ -417,6 +417,8 @@ const int pin_tcxo_enable = -1; #define HAS_BUSY true #define DIO2_AS_RF_SWITCH true + #define LNA_GD_THRSHLD (-109) + #define LNA_GD_LIMIT (-89) #define LORA_LNA_GAIN 17 #define LORA_LNA_GVT 12 diff --git a/Config.h b/Config.h index 2ada4a7..dec0063 100644 --- a/Config.h +++ b/Config.h @@ -151,7 +151,7 @@ uint8_t model = 0x00; uint8_t hwrev = 0x00; - #define NOISE_FLOOR_SAMPLES 64 + #define NOISE_FLOOR_SAMPLES 128 int noise_floor = -292; int current_rssi = -292; int last_rssi = -292; diff --git a/Display.h b/Display.h index 59c5133..7d903b9 100644 --- a/Display.h +++ b/Display.h @@ -152,6 +152,7 @@ bool device_firmware_ok(); #define WATERFALL_SIZE 46 int waterfall[WATERFALL_SIZE]; +int waterfall_meta[WATERFALL_SIZE]; int waterfall_head = 0; int p_ad_x = 0; @@ -722,6 +723,9 @@ void draw_signal_bars(int px, int py) { #define WF_RSSI_MIN -135 #define WF_RSSI_SPAN (WF_RSSI_MAX-WF_RSSI_MIN) #define WF_PIXEL_WIDTH 10 +#define WF_M_RX 0x00 +#define WF_M_TX 0x01 +#define WF_M_NTFR 0x02 void draw_waterfall(int px, int py) { int rssi_val = current_rssi; if (rssi_val < WF_RSSI_MIN) rssi_val = WF_RSSI_MIN; @@ -729,11 +733,14 @@ void draw_waterfall(int px, int py) { int rssi_normalised = ((rssi_val - WF_RSSI_MIN)*(1.0/WF_RSSI_SPAN))*WF_PIXEL_WIDTH; if (display_tx) { for (uint8_t i = 0; i < WF_TX_SIZE; i++) { + waterfall_meta[waterfall_head] = WF_M_TX; waterfall[waterfall_head++] = -1; if (waterfall_head >= WATERFALL_SIZE) waterfall_head = 0; } display_tx = false; } else { + if (interference_detected) { waterfall_meta[waterfall_head] = WF_M_NTFR; } + else { waterfall_meta[waterfall_head] = WF_M_RX; } waterfall[waterfall_head++] = rssi_normalised; if (waterfall_head >= WATERFALL_SIZE) waterfall_head = 0; } @@ -742,8 +749,13 @@ void draw_waterfall(int px, int py) { for (int i = 0; i < WATERFALL_SIZE; i++){ int wi = (waterfall_head+i)%WATERFALL_SIZE; int ws = waterfall[wi]; + int wm = waterfall_meta[wi]; if (ws > 0) { - stat_area.drawLine(px, py+i, px+ws-1, py+i, SSD1306_WHITE); + if (wm == WF_M_RX) { stat_area.drawLine(px, py+i, px+ws-1, py+i, SSD1306_WHITE); } + else if (wm == WF_M_NTFR) { + uint8_t o = 0; + for (uint8_t ti = 0; ti < WF_PIXEL_WIDTH/2; ti++) { stat_area.drawPixel(px+ti*2+o, py+i, SSD1306_WHITE); } + } } else if (ws == -1) { uint8_t o = i%2; for (uint8_t ti = 0; ti < WF_PIXEL_WIDTH/2; ti++) { diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index 5d2eb6a..5649206 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -1358,20 +1358,26 @@ int noise_floor_buffer[NOISE_FLOOR_SAMPLES] = {0}; void update_noise_floor() { #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52 if (!dcd) { + #if BOARD_MODEL != BOARD_HELTEC32_V4 if (!noise_floor_sampled || current_rssi < noise_floor + CSMA_INFR_THRESHOLD_DB) { + #else + if ((!noise_floor_sampled || current_rssi < noise_floor + CSMA_INFR_THRESHOLD_DB) || (noise_floor_sampled && (noise_floor < LNA_GD_THRSHLD && current_rssi <= LNA_GD_LIMIT))) { + #endif #if HAS_LORA_LNA // Discard invalid samples due to gain variance // during LoRa LNA re-calibration if (current_rssi < noise_floor-LORA_LNA_GVT) { return; } #endif + bool sum_noise_floor = false; noise_floor_buffer[noise_floor_sample] = current_rssi; noise_floor_sample = noise_floor_sample+1; if (noise_floor_sample >= NOISE_FLOOR_SAMPLES) { noise_floor_sample %= NOISE_FLOOR_SAMPLES; noise_floor_sampled = true; + sum_noise_floor = true; } - if (noise_floor_sampled) { + if (noise_floor_sampled && sum_noise_floor) { noise_floor = 0; for (int ni = 0; ni < NOISE_FLOOR_SAMPLES; ni++) { noise_floor += noise_floor_buffer[ni]; } noise_floor /= NOISE_FLOOR_SAMPLES; @@ -1402,7 +1408,13 @@ void update_modem_status() { portEXIT_CRITICAL(); #endif - interference_detected = !carrier_detected && (current_rssi > (noise_floor+CSMA_INFR_THRESHOLD_DB)); + #if BOARD_MODEL == BOARD_HELTEC32_V4 + if (noise_floor > LNA_GD_THRSHLD) { interference_detected = !carrier_detected && (current_rssi > (noise_floor+CSMA_INFR_THRESHOLD_DB)); } + else { interference_detected = !carrier_detected && (current_rssi > LNA_GD_LIMIT); } + #else + interference_detected = !carrier_detected && (current_rssi > (noise_floor+CSMA_INFR_THRESHOLD_DB)); + #endif + if (interference_detected) { if (led_id_filter < LED_ID_TRIG) { led_id_filter += 1; } } else { if (led_id_filter > 0) {led_id_filter -= 1; } } @@ -1410,14 +1422,11 @@ void update_modem_status() { // LNA recalibration, antenna swap, moving into new RF // environment or similar. if (interference_detected && current_rssi < CSMA_RFENV_RECAL_LIMIT_DB) { - if (!interference_persists) { - interference_persists = true; interference_start = millis(); - } else { + if (!interference_persists) { interference_persists = true; interference_start = millis(); } + else { if (millis()-interference_start >= CSMA_RFENV_RECAL_MS) { noise_floor_sampled = false; interference_persists = false; } } - } else { - interference_persists = false; - } + } else { interference_persists = false; } if (carrier_detected) { dcd = true; } else { dcd = false; }