From d5b79b58edf15aed14a8afce8a2820a24f190721 Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Fri, 20 Sep 2024 13:18:01 +0100 Subject: [PATCH 1/9] Undo unintended error count fix --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index b6953bc..300cac3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -806,7 +806,6 @@ void loop(void) // horizontal (x axis) Frequency loop osd_x = 1, osd_y = 2, col = 0, max_bin = 0; - int radio_error_count = 0; // x loop for (x = 0; x < STEPS * SCAN_RBW_FACTOR; x++) { @@ -836,6 +835,7 @@ void loop(void) #endif state = radio.setFrequency(freq, false); // false = no calibration need here + int radio_error_count = 0; if (state != RADIOLIB_ERR_NONE) { display.drawString(0, 64 - 10, "E:setFrequency:" + String(freq)); From 3b4dc0473c7dee4d95e04f20286b74b5ee6dfe75 Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Fri, 20 Sep 2024 13:35:22 +0100 Subject: [PATCH 2/9] Report error code --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 300cac3..47a844f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -838,9 +838,9 @@ void loop(void) int radio_error_count = 0; if (state != RADIOLIB_ERR_NONE) { - display.drawString(0, 64 - 10, "E:setFrequency:" + String(freq)); - // display.drawString(0, 64 - 10, "E:setFrequency:" + String(freq)); - Serial.println("E:setFrequency:" + String(freq)); + display.drawString( + 0, 64 - 10, "E(" + String(state) + "):setFrequency:" + String(freq)); + Serial.println("E(" + String(state) + "):setFrequency:" + String(freq)); display.display(); delay(2); radio_error_count++; From d9170811eb940a4c8a9f7929c1f98f9187cce131 Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Fri, 20 Sep 2024 19:11:30 +0100 Subject: [PATCH 3/9] Address review comments from PR 40 --- lib/scan/scan.cpp | 8 ++++---- lib/scan/scan.h | 14 ++++---------- src/main.cpp | 5 ++--- test/test_rssi.cpp | 13 +++++++------ 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/lib/scan/scan.cpp b/lib/scan/scan.cpp index bf8b416..c1f777f 100644 --- a/lib/scan/scan.cpp +++ b/lib/scan/scan.cpp @@ -6,17 +6,17 @@ #include #include -float Scan::getRSSI() { return 0.1; } - -uint16_t Scan::rssiMethod(uint16_t *result) +uint16_t Scan::rssiMethod(size_t samples, uint16_t *result, size_t res_size) { + float scale((float)res_size / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1)); + memset(result, 0, res_size * sizeof(uint16_t)); int result_index = 0; // uint16_t max_signal = 65535; // N of samples - for (int r = 0; r < SAMPLES_RSSI; r++) + for (int r = 0; r < samples; r++) { float rssi = getRSSI(); if (rssi < -65535) diff --git a/lib/scan/scan.h b/lib/scan/scan.h index 36f449c..1c8ca8e 100644 --- a/lib/scan/scan.h +++ b/lib/scan/scan.h @@ -30,17 +30,11 @@ constexpr float LO_RSSI_THRESHOLD = HI_RSSI_THRESHOLD - 66; struct Scan { - Scan(int sz) - : res_size(sz), scale((float)sz / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1)) - { - } + virtual float getRSSI() = 0; - virtual float getRSSI(); - - uint16_t rssiMethod(uint16_t *result); - - int res_size; - float scale; + // rssiMethod gets the data similar to the scan method, + // but uses getRSSI directly. + uint16_t rssiMethod(size_t samples, uint16_t *result, size_t res_size); }; #endif diff --git a/src/main.cpp b/src/main.cpp index 47a844f..6dcb633 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -706,8 +706,6 @@ void check_ranges() struct RadioScan : Scan { - RadioScan() : Scan(RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE) {} - float getRSSI() override; }; @@ -882,7 +880,8 @@ void loop(void) // Spectrum analyzer using getRSSI { LOG("METHOD RSSI"); - uint16_t max_rssi = r.rssiMethod(result); + uint16_t max_rssi = r.rssiMethod(SAMPLES_RSSI, result, + RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE); if (max_x_rssi[display_x] > max_rssi) { max_x_rssi[display_x] = max_rssi; diff --git a/test/test_rssi.cpp b/test/test_rssi.cpp index 9c4b023..b6ed9f3 100644 --- a/test/test_rssi.cpp +++ b/test/test_rssi.cpp @@ -9,7 +9,7 @@ void tearDown(void) {} struct TestScan : Scan { - TestScan(float *ctx, int sz) : Scan(sz), ctx(ctx), sz(sz), idx(0) {} + TestScan(float *ctx, int sz) : ctx(ctx), sz(sz), idx(0) {} float getRSSI() override; @@ -29,18 +29,19 @@ float TestScan::getRSSI() } constexpr int test_sz = 13; +constexpr int inputs_sz = 13; void test_rssi(void) { uint16_t samples[test_sz]; - float inputs[] = {-40.0, -100.0, -200.0, -50.0, -400.0, -60.0, -20, - -75.5, -70, -80, -90, -55.9, -110}; + float inputs[inputs_sz] = {-40.0, -100.0, -200.0, -50.0, -400.0, -60.0, -20, + -75.5, -70, -80, -90, -55.9, -110}; - TestScan t = TestScan(inputs, test_sz); + TestScan t = TestScan(inputs, inputs_sz); - uint16_t r = t.rssiMethod(samples); + uint16_t r = t.rssiMethod(inputs_sz, samples, test_sz); - uint16_t expect[test_sz] = {20, 50, 55, 60, 0, 70, 75, 80, 0, 90, 0, 100, 200}; + uint16_t expect[test_sz] = {20, 50, 55, 60, 0, 70, 75, 80, 0, 90, 0, 100, 110}; TEST_ASSERT_EQUAL_INT16(20, r); TEST_ASSERT_EQUAL_INT16_ARRAY(expect, samples, test_sz); From c5ac3896fb0f6d669031c3ea1ae99e1f06e23628 Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Sat, 21 Sep 2024 16:36:21 +0100 Subject: [PATCH 4/9] Factor out detection + display loop Refactor code that does not depend on y. Essentially, the following logic: Recall that some loops are folds, some are maps. Maps look at only elements with one index. The important property of maps is that map(f . g) = map(f) . map(g) - parts of the loop body can be split into separate loops. Another property of maps is that if map(f) does not depend on the output of map(g), then map(f) . map(g) = map(g) . map(f) - the loops can be reordered. --- lib/scan/scan.cpp | 67 +++++++++++++++- lib/scan/scan.h | 22 +++--- src/main.cpp | 148 +++++++++++++----------------------- src/radioScan/radioScan.cpp | 59 ++++++++++++++ src/radioScan/radioScan.h | 10 +++ 5 files changed, 197 insertions(+), 109 deletions(-) diff --git a/lib/scan/scan.cpp b/lib/scan/scan.cpp index bf8b416..bc58902 100644 --- a/lib/scan/scan.cpp +++ b/lib/scan/scan.cpp @@ -6,17 +6,17 @@ #include #include -float Scan::getRSSI() { return 0.1; } - -uint16_t Scan::rssiMethod(uint16_t *result) +uint16_t Scan::rssiMethod(size_t samples, uint16_t *result, size_t res_size) { + float scale((float)res_size / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1)); + memset(result, 0, res_size * sizeof(uint16_t)); int result_index = 0; // uint16_t max_signal = 65535; // N of samples - for (int r = 0; r < SAMPLES_RSSI; r++) + for (int r = 0; r < samples; r++) { float rssi = getRSSI(); if (rssi < -65535) @@ -66,4 +66,63 @@ uint16_t Scan::rssiMethod(uint16_t *result) return max_signal; } +size_t Scan::detect(uint16_t *result, bool *filtered_result, size_t result_size, + int samples) +{ + size_t max_rssi_x = 999; + + for (int y = 0; y < result_size; y++) + { + + LOG("%i:%i,", y, result[y]); +#if !defined(FILTER_SPECTRUM_RESULTS) || FILTER_SPECTRUM_RESULTS == false + if (result[y] && result[y] != 0) + { + filtered_result[y] = 1; + } + else + { + filtered_result[y] = 0; + } +#endif + +// if samples low ~1 filter removes all values +#if FILTER_SPECTRUM_RESULTS + + filtered_result[y] = 0; + // Filter Elements without neighbors + // if RSSI method actual value is -xxx dB + if (result[y] > 0 && samples > 1) + { + // do not process 'first' and 'last' row to avoid out of index + // access. + if ((y > 0) && (y < (result_size - 2))) + { + if (((result[y + 1] != 0) && (result[y + 2] != 0)) || + (result[y - 1] != 0)) + { + filtered_result[y] = 1; + // Fill empty pixel + result[y + 1] = 1; + } + else + { + LOG("Filtered::%i,", y); + } + } + } // not filtering if samples == 1 because it will be filtered + else if (result[y] > 0 && samples == 1) + { + filtered_result[y] = 1; + } +#endif + if (filtered_result[y] && max_rssi_x > y) + { + max_rssi_x = y; + } + } + + return max_rssi_x; +} + #endif diff --git a/lib/scan/scan.h b/lib/scan/scan.h index 36f449c..bfbdcf8 100644 --- a/lib/scan/scan.h +++ b/lib/scan/scan.h @@ -30,17 +30,21 @@ constexpr float LO_RSSI_THRESHOLD = HI_RSSI_THRESHOLD - 66; struct Scan { - Scan(int sz) - : res_size(sz), scale((float)sz / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1)) - { - } + virtual float getRSSI() = 0; - virtual float getRSSI(); + // rssiMethod gets the data similar to the scan method, + // but uses getRSSI directly. + uint16_t rssiMethod(size_t samples, uint16_t *result, size_t res_size); - uint16_t rssiMethod(uint16_t *result); - - int res_size; - float scale; + // detect method analyses result, and produces filtered_result, marking + // those values that represent a detection event. + // It returns index that represents strongest signal at which a detection event + // occurred. + static size_t detect(uint16_t *result, bool *filtered_result, size_t result_size, + int samples); }; +// Remove reading without neighbors +#define FILTER_SPECTRUM_RESULTS true + #endif diff --git a/src/main.cpp b/src/main.cpp index a7704e9..6f48c1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -144,8 +144,6 @@ bool ANIMATED_RELOAD = false; #define UP_FILTER 5 // Trim low signals - nose level #define START_LOW 6 -// Remove reading without neighbors -#define FILTER_SPECTRUM_RESULTS true #define FILTER_SAMPLES_MIN constexpr bool DRAW_DETECTION_TICKS = true; int16_t max_x_rssi[STEPS] = {999}; @@ -888,9 +886,7 @@ void loop(void) float step = (range * ((float)x / (STEPS * SCAN_RBW_FACTOR))); freq = fr_begin + step; -#ifdef PRINT_DEBUG - Serial.println("setFrequency:" + String(freq)); -#endif + LOG("setFrequency:%f\n", freq); #ifdef USING_SX1280PA state = radio.setFrequency(freq); // 1280 doesn't have calibration @@ -911,9 +907,7 @@ void loop(void) continue; } -#ifdef PRINT_DEBUG - Serial.printf("Step:%d Freq: %f\n", x, freq); -#endif + LOG("Step:%d Freq: %f\n", x, freq); // SpectralScan Method #ifdef METHOD_SPECTRAL { @@ -971,59 +965,21 @@ void loop(void) display.setColor(WHITE); } #endif - detected = false; - detected_y[display_x] = false; - max_rssi_x = 999; + size_t detected_at = r.detect( + result, filtered_result, RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE, samples); - for (y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++) + if (max_rssi_x > detected_at) { + // MAx bin Value not RSSI + max_rssi_x = detected_at; + } -#ifdef PRINT_DEBUG - Serial.print(String(y) + ":"); - Serial.print(String(result[y]) + ","); -#endif -#if !defined(FILTER_SPECTRUM_RESULTS) || FILTER_SPECTRUM_RESULTS == false - if (result[y] && result[y] != 0) - { - filtered_result[y] = 1; - } - else - { - filtered_result[y] = 0; - } -#endif + detected = detected_at < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; + detected_y[display_x] = false; -// if samples low ~1 filter removes all values #if FILTER_SPECTRUM_RESULTS - - filtered_result[y] = 0; - // Filter Elements without neighbors - // if RSSI method actual value is -xxx dB - if (result[y] > 0 && samples > 1) - { - // do not process 'first' and 'last' row to avoid out of index - // access. - if ((y > 0) && (y < (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 2))) - { - if (((result[y + 1] != 0) && (result[y + 2] != 0)) || - (result[y - 1] != 0)) - { - filtered_result[y] = 1; - // Fill empty pixel - result[y + 1] = 1; - } - else - { -#ifdef PRINT_DEBUG - Serial.print("Filtered:" + String(x) + ":" + String(y) + ","); -#endif - } - } - } // not filtering if samples == 1 because it will be filtered - else if (result[y] > 0 && samples == 1) - { - filtered_result[y] = 1; - } + for (int y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++) + { // calculating max window x RSSI after filters x_window = (int)(display_x / WINDOW_SIZE); int abs_result = abs(result[y]); @@ -1031,16 +987,15 @@ void loop(void) max_x_window[x_window] > abs_result) { max_x_window[x_window] = abs_result; -#ifdef PRINT_DEBUG - Serial.println("MAX x window: " + String(x_window) + " " + - String(abs_result)); -#endif + LOG("MAX x window: %i %i\n", x_window, abs_result); } + } #endif + + if (detected_at <= drone_detection_level) + { // check if we should alarm about a drone presence - if ((filtered_result[y] == 1) // we have some data and - && (y <= drone_detection_level) && - detected_y[display_x] == false) // detection threshold match + if (detected_y[display_x] == false) // detection threshold match { // Set LED to ON (filtered in UI component) UI_setLedFlag(true); @@ -1084,8 +1039,7 @@ void loop(void) } } #if (WATERFALL_ENABLED == true) - if ((filtered_result[y] == 1) && (y <= drone_detection_level) && - (single_page_scan) && (waterfall[display_x] != true) && new_pixel) + if ((single_page_scan) && (waterfall[display_x] != true) && new_pixel) { // If drone not found set dark pixel on the waterfall // TODO: make something like scrolling up if possible @@ -1095,44 +1049,46 @@ void loop(void) display.setColor(WHITE); } #endif - // next 2 If's ... adds !!!! 10ms of runtime ......tfk ??? + } + +#ifdef PRINT_DEBUG + for (int y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++) + { if (filtered_result[y] == 1) { -#ifdef PRINT_DEBUG - Serial.print("Pixel:" + String(display_x) + "(" + String(x) + ")" + - ":" + String(y) + ","); -#endif - if (max_rssi_x > y) - { - // MAx bin Value not RSSI - max_rssi_x = y; - } - // Set MAIN signal level pixel - if (y < MAX_POWER_LEVELS - START_LOW) - { - display.setPixel(display_x, y + START_LOW); - } - if (!detected) - { - detected = true; - } + LOG("Pixel:%i(%i):%i,", display_x, x, y); } + } +#endif - // ------------------------------------------------------------- - // Draw "Detection Level line" every 2 pixel - // ------------------------------------------------------------- - if ((y == drone_detection_level) && (display_x % 2 == 0)) + for (int y = 0; y < min(RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE, + MAX_POWER_LEVELS - START_LOW); + y++) + { + if (filtered_result[y] == 1) + { + // Set MAIN signal level pixel + display.setPixelColor(display_x, y + START_LOW, WHITE); + } + } + + // ------------------------------------------------------------- + // Draw "Detection Level line" every 2 pixel + // ------------------------------------------------------------- + if (display_x % 2 == 0) + { + if (filtered_result[drone_detection_level] == 1) + { + display.setColor(INVERSE); + } + else { display.setColor(WHITE); - if (filtered_result[y] == 1) - { - display.setColor(INVERSE); - } - display.setPixel(display_x, y + START_LOW); - // display.setPixel(display_x, y + START_LOW - 1); // 2 px wide - - display.setColor(WHITE); } + display.setPixel(display_x, drone_detection_level + START_LOW); + // display.setPixel(display_x, y + START_LOW - 1); // 2 px wide + + display.setColor(WHITE); } #ifdef JOYSTICK_ENABLED diff --git a/src/radioScan/radioScan.cpp b/src/radioScan/radioScan.cpp index 73150fc..a5a2332 100644 --- a/src/radioScan/radioScan.cpp +++ b/src/radioScan/radioScan.cpp @@ -66,4 +66,63 @@ uint16_t Scan::rssiMethod(size_t samples, uint16_t *result, size_t res_size) return max_signal; } +size_t Scan::detect(uint16_t *result, bool *filtered_result, size_t result_size, + int samples) +{ + size_t max_rssi_x = 999; + + for (int y = 0; y < result_size; y++) + { + + LOG("%i:%i,", y, result[y]); +#if !defined(FILTER_SPECTRUM_RESULTS) || FILTER_SPECTRUM_RESULTS == false + if (result[y] && result[y] != 0) + { + filtered_result[y] = 1; + } + else + { + filtered_result[y] = 0; + } +#endif + +// if samples low ~1 filter removes all values +#if FILTER_SPECTRUM_RESULTS + + filtered_result[y] = 0; + // Filter Elements without neighbors + // if RSSI method actual value is -xxx dB + if (result[y] > 0 && samples > 1) + { + // do not process 'first' and 'last' row to avoid out of index + // access. + if ((y > 0) && (y < (result_size - 2))) + { + if (((result[y + 1] != 0) && (result[y + 2] != 0)) || + (result[y - 1] != 0)) + { + filtered_result[y] = 1; + // Fill empty pixel + result[y + 1] = 1; + } + else + { + LOG("Filtered::%i,", y); + } + } + } // not filtering if samples == 1 because it will be filtered + else if (result[y] > 0 && samples == 1) + { + filtered_result[y] = 1; + } +#endif + if (filtered_result[y] && max_rssi_x > y) + { + max_rssi_x = y; + } + } + + return max_rssi_x; +} + #endif diff --git a/src/radioScan/radioScan.h b/src/radioScan/radioScan.h index 1c8ca8e..bfbdcf8 100644 --- a/src/radioScan/radioScan.h +++ b/src/radioScan/radioScan.h @@ -35,6 +35,16 @@ struct Scan // rssiMethod gets the data similar to the scan method, // but uses getRSSI directly. uint16_t rssiMethod(size_t samples, uint16_t *result, size_t res_size); + + // detect method analyses result, and produces filtered_result, marking + // those values that represent a detection event. + // It returns index that represents strongest signal at which a detection event + // occurred. + static size_t detect(uint16_t *result, bool *filtered_result, size_t result_size, + int samples); }; +// Remove reading without neighbors +#define FILTER_SPECTRUM_RESULTS true + #endif From 718ea408599c95e19daa6445319d093e506701fc Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Sun, 22 Sep 2024 09:57:34 +0100 Subject: [PATCH 5/9] Add test for detect() --- test/test_rssi.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/test_rssi.cpp b/test/test_rssi.cpp index 0215179..519f72f 100644 --- a/test/test_rssi.cpp +++ b/test/test_rssi.cpp @@ -47,11 +47,32 @@ void test_rssi(void) TEST_ASSERT_EQUAL_INT16_ARRAY(expect, samples, test_sz); } +void test_detect() +{ + uint16_t samples[test_sz] = {20, 50, 55, 60, 0, 70, 75, 80, 0, 90, 0, 100, 110}; + bool result[test_sz]; + + size_t r = Scan::detect(samples, result, test_sz, 1); + + bool expect[test_sz] = {1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1}; + + TEST_ASSERT_EQUAL_INT16(0, r); + TEST_ASSERT_EQUAL_INT8_ARRAY(expect, result, test_sz); + + r = Scan::detect(samples, result, test_sz, 2); + + bool expect2[test_sz] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}; + + TEST_ASSERT_EQUAL_INT16(1, r); + TEST_ASSERT_EQUAL_INT8_ARRAY(expect2, result, test_sz); +} + int main(int argc, char **argv) { UNITY_BEGIN(); RUN_TEST(test_rssi); + RUN_TEST(test_detect); UNITY_END(); } From 94c042a18698706e9a0b4729cd29c3152dbab9e2 Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Thu, 26 Sep 2024 21:35:32 +0100 Subject: [PATCH 6/9] LilyGO T3S3 works --- {include => lib/loraboards}/LoRaBoards.cpp | 0 {include => lib/loraboards}/LoRaBoards.h | 0 {include => lib/loraboards}/utilities.h | 0 platformio.ini | 2 + src/main.cpp | 10 +- src/radioScan/radioScan.cpp | 128 --------------------- src/radioScan/radioScan.h | 50 -------- test/test_rssi.cpp | 2 +- 8 files changed, 10 insertions(+), 182 deletions(-) rename {include => lib/loraboards}/LoRaBoards.cpp (100%) rename {include => lib/loraboards}/LoRaBoards.h (100%) rename {include => lib/loraboards}/utilities.h (100%) delete mode 100644 src/radioScan/radioScan.cpp delete mode 100644 src/radioScan/radioScan.h diff --git a/include/LoRaBoards.cpp b/lib/loraboards/LoRaBoards.cpp similarity index 100% rename from include/LoRaBoards.cpp rename to lib/loraboards/LoRaBoards.cpp diff --git a/include/LoRaBoards.h b/lib/loraboards/LoRaBoards.h similarity index 100% rename from include/LoRaBoards.h rename to lib/loraboards/LoRaBoards.h diff --git a/include/utilities.h b/lib/loraboards/utilities.h similarity index 100% rename from include/utilities.h rename to lib/loraboards/utilities.h diff --git a/platformio.ini b/platformio.ini index 5ff09ab..997258b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -63,6 +63,8 @@ board_build.f_cpu = 240000000 lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 RadioLib + U8g2 + XPowersLib build_flags = -DLILYGO -DT3_S3_V1_2_SX1280_PA diff --git a/src/main.cpp b/src/main.cpp index c4f3573..fdcd374 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,7 @@ https://jgromes.github.io/RadioLib/ */ -// #define HELTEC_NO_DISPLAY +// #define HELTEC_NO_DISPLAY #include @@ -36,7 +36,8 @@ // library internals. #define RADIOLIB_GODMODE (1) -#include "radioScan/radioScan.h" +#include +#include #ifndef LILYGO #include @@ -354,7 +355,6 @@ void init_radio() // initialize SX1262 FSK modem at the initial frequency both.println("Init radio"); #ifdef USING_SX1280PA - // radio.begin(); state = radio.beginGFSK(FREQ_BEGIN); #else state = radio.beginFSK(FREQ_BEGIN); @@ -423,6 +423,10 @@ void init_radio() void setup(void) { + setupBoards(); + delay(5000); + Serial.println("setup is done"); + // LED brightness heltec_led(25); #ifdef OSD_ENABLED diff --git a/src/radioScan/radioScan.cpp b/src/radioScan/radioScan.cpp deleted file mode 100644 index a5a2332..0000000 --- a/src/radioScan/radioScan.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef LORASA_CORE_CPP -#define LORASA_CORE_CPP - -#include "radioScan.h" -#include -#include -#include - -uint16_t Scan::rssiMethod(size_t samples, uint16_t *result, size_t res_size) -{ - float scale((float)res_size / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1)); - - memset(result, 0, res_size * sizeof(uint16_t)); - int result_index = 0; - - // - uint16_t max_signal = 65535; - // N of samples - for (int r = 0; r < samples; r++) - { - float rssi = getRSSI(); - if (rssi < -65535) - rssi = -65535; - - uint16_t abs_rssi = abs(rssi); - if (abs_rssi < max_signal) - { - max_signal = abs_rssi; - } - // ToDO: check if 4 is correct value for 33 power bins - // Now we have more space because we are ignoring low dB values - // we can / 3 default 4 - if (RSSI_OUTPUT_FORMULA == 1) - { - result_index = - /// still not clear formula but it works - uint8_t(abs(rssi) / 4); - } - else if (RSSI_OUTPUT_FORMULA == 2) - { - if (rssi > HI_RSSI_THRESHOLD) - { - rssi = HI_RSSI_THRESHOLD; - } - else if (rssi < LO_RSSI_THRESHOLD) - { - rssi = LO_RSSI_THRESHOLD; - } - - result_index = uint8_t((HI_RSSI_THRESHOLD - rssi) * scale); - } - - if (result_index >= res_size) - { - // Maximum index possible - result_index = res_size - 1; - } - - LOG("RSSI: %f IDX: %d\n", rssi, result_index); - if (result[result_index] == 0 || result[result_index] > abs_rssi) - { - result[result_index] = abs_rssi; - } - } - - return max_signal; -} - -size_t Scan::detect(uint16_t *result, bool *filtered_result, size_t result_size, - int samples) -{ - size_t max_rssi_x = 999; - - for (int y = 0; y < result_size; y++) - { - - LOG("%i:%i,", y, result[y]); -#if !defined(FILTER_SPECTRUM_RESULTS) || FILTER_SPECTRUM_RESULTS == false - if (result[y] && result[y] != 0) - { - filtered_result[y] = 1; - } - else - { - filtered_result[y] = 0; - } -#endif - -// if samples low ~1 filter removes all values -#if FILTER_SPECTRUM_RESULTS - - filtered_result[y] = 0; - // Filter Elements without neighbors - // if RSSI method actual value is -xxx dB - if (result[y] > 0 && samples > 1) - { - // do not process 'first' and 'last' row to avoid out of index - // access. - if ((y > 0) && (y < (result_size - 2))) - { - if (((result[y + 1] != 0) && (result[y + 2] != 0)) || - (result[y - 1] != 0)) - { - filtered_result[y] = 1; - // Fill empty pixel - result[y + 1] = 1; - } - else - { - LOG("Filtered::%i,", y); - } - } - } // not filtering if samples == 1 because it will be filtered - else if (result[y] > 0 && samples == 1) - { - filtered_result[y] = 1; - } -#endif - if (filtered_result[y] && max_rssi_x > y) - { - max_rssi_x = y; - } - } - - return max_rssi_x; -} - -#endif diff --git a/src/radioScan/radioScan.h b/src/radioScan/radioScan.h deleted file mode 100644 index bfbdcf8..0000000 --- a/src/radioScan/radioScan.h +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -#ifndef LORASA_CORE_H - -#define LORASA_CORE_H - -#ifdef PRINT_DEBUG -#define LOG(args...) Serial.printf(args...) -#define LOG_IF(cond, args...) \ - if (cond) \ - LOG(args...) -#elif !defined(LOG) -#define LOG(args...) -#define LOG_IF(cond, args...) -#endif - -// Output Pixel Formula -// 1 = rssi / 4, 2 = (rssi / 2) - 22 or 20 -constexpr int RSSI_OUTPUT_FORMULA = 2; - -// based on the formula for RSSI_OUTPUT_FORMULA == 2 -// -2 * (22 + RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE) < rssi =< -44 -// practice may require a better pair of thresholds -constexpr float HI_RSSI_THRESHOLD = -44.0; -constexpr float LO_RSSI_THRESHOLD = HI_RSSI_THRESHOLD - 66; - -// number of samples for RSSI method -#define SAMPLES_RSSI 12 // 21 // - -struct Scan -{ - virtual float getRSSI() = 0; - - // rssiMethod gets the data similar to the scan method, - // but uses getRSSI directly. - uint16_t rssiMethod(size_t samples, uint16_t *result, size_t res_size); - - // detect method analyses result, and produces filtered_result, marking - // those values that represent a detection event. - // It returns index that represents strongest signal at which a detection event - // occurred. - static size_t detect(uint16_t *result, bool *filtered_result, size_t result_size, - int samples); -}; - -// Remove reading without neighbors -#define FILTER_SPECTRUM_RESULTS true - -#endif diff --git a/test/test_rssi.cpp b/test/test_rssi.cpp index 519f72f..8a75b60 100644 --- a/test/test_rssi.cpp +++ b/test/test_rssi.cpp @@ -1,6 +1,6 @@ #include #define LOG(args...) printf(args) -#include "../src/radioScan/radioScan.cpp" +#include "../lib/scan/scan.cpp" #include void setUp(void) {} From 72b5d0b80d38d80dfa4cab8ca2146d30d657c74c Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 27 Sep 2024 00:57:26 -0700 Subject: [PATCH 7/9] fix Heltec boards --- lib/loraboards/LoRaBoards.cpp | 3 +++ lib/loraboards/utilities.h | 2 ++ lib/scan/scan.h | 3 +++ platformio.ini | 13 ++++++++++--- src/main.cpp | 20 ++++++++++++++------ src/ui.cpp | 2 +- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/loraboards/LoRaBoards.cpp b/lib/loraboards/LoRaBoards.cpp index 04c93a6..0331489 100644 --- a/lib/loraboards/LoRaBoards.cpp +++ b/lib/loraboards/LoRaBoards.cpp @@ -8,6 +8,8 @@ * */ +#ifdef LILYGO + #include "LoRaBoards.h" #if defined(HAS_SDCARD) @@ -927,3 +929,4 @@ bool beginGPS() return result; } #endif +#endif // #ifdef LILYGO diff --git a/lib/loraboards/utilities.h b/lib/loraboards/utilities.h index 1d1b3ef..32a804b 100644 --- a/lib/loraboards/utilities.h +++ b/lib/loraboards/utilities.h @@ -486,6 +486,8 @@ #define USING_DIO2_AS_RF_SWITCH +#elif defined(HELTEC) +// just to prevent error #elif defined(T_BEAM_S3_BPF) #ifndef USING_SX1278 diff --git a/lib/scan/scan.h b/lib/scan/scan.h index bfbdcf8..f5af2c6 100644 --- a/lib/scan/scan.h +++ b/lib/scan/scan.h @@ -27,6 +27,9 @@ constexpr float LO_RSSI_THRESHOLD = HI_RSSI_THRESHOLD - 66; // number of samples for RSSI method #define SAMPLES_RSSI 12 // 21 // +#ifdef USING_SX1280PA +#define SAMPLES_RSSI 20 +#endif struct Scan { diff --git a/platformio.ini b/platformio.ini index 997258b..84a0e9e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -28,7 +28,10 @@ monitor_speed = 115200 board_build.f_cpu = 240000000 lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 -build_flags = -DHELTEC_POWER_BUTTON +build_flags = + -DHELTEC_POWER_BUTTON + -DHELTEC + [env:lilygo-T3S3-v1-2-sx1262] platform = espressif32 @@ -88,7 +91,9 @@ board_build.f_cpu = 240000000 board_build.flash_size = 80000000L lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 -build_flags = -DLILYGO +build_flags = + -DHELTEC + -DHELTEC_POWER_BUTTON [env:vision-master-e290] platform = espressif32 @@ -97,7 +102,8 @@ framework = arduino monitor_speed = 115200 monitor_filters = esp32_exception_decoder board_upload.use_1200bps_touch = true -build_flags = +build_flags = + -DHELTEC -DHELTEC_BOARD=37 -DSLOW_CLK_TPYE=1 -DARDUINO_USB_CDC_ON_BOOT=1 @@ -130,6 +136,7 @@ monitor_speed = 115200 monitor_filters = esp32_exception_decoder board_upload.use_1200bps_touch = true build_flags = + -DHELTEC -DHELTEC_BOARD=38 -DSLOW_CLK_TPYE=1 -DARDUINO_USB_CDC_ON_BOOT=1 diff --git a/src/main.cpp b/src/main.cpp index fdcd374..dd891aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,22 +36,24 @@ // library internals. #define RADIOLIB_GODMODE (1) -#include #include #ifndef LILYGO #include // This file contains a binary patch for the SX1262 #include "modules/SX126x/patches/SX126x_patch_scan.h" -#endif // end LILYGO +#endif // end ifndef LILYGO + #if defined(LILYGO) // LiLyGO device does not support the auto download mode, you need to get into the // download mode manually. To do so, press and hold the BOOT button and then press the // RESET button once. After that release the BOOT button. Or OFF->ON together with BOOT // Default LilyGO code -#include "utilities.h" -// Our Code +#include + +// #include "utilities.h" +// Our Code #include "LiLyGo.h" #endif // end LILYGO @@ -134,6 +136,10 @@ uint64_t RANGE_PER_PAGE = FREQ_END - FREQ_BEGIN; // FREQ_END - FREQ_BEGIN // multiplies STEPS * N to increase scan resolution. #define SCAN_RBW_FACTOR 2 +#ifdef USING_SX1280PA +#define SCAN_RBW_FACTOR 2 +#endif + constexpr int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH; #define DEFAULT_RANGE_PER_PAGE 50 @@ -423,9 +429,11 @@ void init_radio() void setup(void) { +#ifdef LILYGO setupBoards(); - delay(5000); - Serial.println("setup is done"); + delay(3000); + Serial.println("setup LiLyGO board is done"); +#endif // LED brightness heltec_led(25); diff --git a/src/ui.cpp b/src/ui.cpp index 94342b7..ee8bc92 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -223,7 +223,7 @@ void UI_displayDecorate(int begin = 0, int end = 0, bool redraw = false) display_instance->setTextAlignment(TEXT_ALIGN_CENTER); // clear status line clearStatus(); - display_instance->drawString(start_scan_text, ROW_STATUS_TEXT, + display_instance->drawString(start_scan_text + 2, ROW_STATUS_TEXT, String(drone_detected_frequency_start) + ">RF<" + String(drone_detected_frequency_end)); } From 1c674701a1f395ec3352721fc350fe657468b6f1 Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 27 Sep 2024 01:19:01 -0700 Subject: [PATCH 8/9] mac os usb --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f04980e..23c36fe 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,9 @@ If less, ESP32 will turn off. Fast pressing(less than 0.5 second) P button chang 3. Connect ESP32 to USB. Install USB CP2101 drivers for Windows or other OS https://docs.heltec.org/general/establish_serial_connection.html#for-windows https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads + + ## NOTE: MACOS driver + https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads 5. Clone this Git Repo or download zip of the sources ![image](https://github.com/user-attachments/assets/971b6592-3b71-414c-971c-2ecd20f0f0b7) From 25053faf72cf1b1422b56be6bd218b3c062de51f Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 27 Sep 2024 01:20:18 -0700 Subject: [PATCH 9/9] legacy driver --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23c36fe..6885ced 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,9 @@ If less, ESP32 will turn off. Fast pressing(less than 0.5 second) P button chang https://docs.heltec.org/general/establish_serial_connection.html#for-windows https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads - ## NOTE: MACOS driver - https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads + ## NOTE: MACOS Heltec USB driver + https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads
+ I used legacy driver 5. Clone this Git Repo or download zip of the sources ![image](https://github.com/user-attachments/assets/971b6592-3b71-414c-971c-2ecd20f0f0b7)