From 36e6f8f2a81715420f0d40d4c1131913c5b2aeba Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Sun, 18 Aug 2024 23:21:29 -0700 Subject: [PATCH 01/15] OSD + BT + WF --- include/BT_WIFI_scan.h | 7 + include/DFRobot_OSD.h | 4 +- include/OSD.h | 6 + include/ui.h | 2 + platformio.ini | 4 + src/BT_WIFI_scan.cpp | 112 ++++++++++++ src/OSD.cpp | 108 +++++++++++ src/main.cpp | 401 +++++++++++++++++++++-------------------- trans_src/main.cpp | 120 ++++++++++++ 9 files changed, 562 insertions(+), 202 deletions(-) create mode 100644 include/BT_WIFI_scan.h create mode 100644 include/OSD.h create mode 100644 src/BT_WIFI_scan.cpp create mode 100644 src/OSD.cpp create mode 100644 trans_src/main.cpp diff --git a/include/BT_WIFI_scan.h b/include/BT_WIFI_scan.h new file mode 100644 index 0000000..bbafb39 --- /dev/null +++ b/include/BT_WIFI_scan.h @@ -0,0 +1,7 @@ +#ifndef _BT_WIFI_SCAN_H_ +#define _BT_WIFI_SCAN_H_ + +extern void scanWiFiWithOSDOut(); +extern void scanBTWithOSDOut(); + +#endif diff --git a/include/DFRobot_OSD.h b/include/DFRobot_OSD.h index d446a86..869bffb 100644 --- a/include/DFRobot_OSD.h +++ b/include/DFRobot_OSD.h @@ -146,10 +146,10 @@ class DFRobot_OSD /** * @fn DFRobot_OSD * @brief Constructor - * @param CS - CS selection pin + * @param OSD_CS - CS selection pin * @return None */ - DFRobot_OSD(int CS); + DFRobot_OSD(int OSD_CS); ~DFRobot_OSD(); /** diff --git a/include/OSD.h b/include/OSD.h new file mode 100644 index 0000000..e87600e --- /dev/null +++ b/include/OSD.h @@ -0,0 +1,6 @@ +#ifndef _OSD_H_ +#define _OSD_H_ +extern void osd_spectrum(); +extern void osdPrintSignalLevelChart(int col, int signal_value); +extern unsigned short selectFreqChar(int bin, int start_level = 0); +#endif diff --git a/include/ui.h b/include/ui.h index 055b8ed..9563ad7 100644 --- a/include/ui.h +++ b/include/ui.h @@ -13,6 +13,8 @@ #define MINOR_TICKS 5 #define ONE_MILLISEC 1 +#define ONE_SEC 1000 +#define ONE_MINUTE 60 * 1000 // Prints debug information and the scan measurement bins from the SX1262 in // hex Change spectrum plot values at once or by line diff --git a/platformio.ini b/platformio.ini index 5c24979..7632ec6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,6 +8,10 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html +[platformio] +default_envs = heltec_wifi_lora_32_V3 +;src_dir = trans_src ;transmitter test project + [env:heltec_wifi_lora_32_V3] platform = espressif32 board = heltec_wifi_lora_32_V3 diff --git a/src/BT_WIFI_scan.cpp b/src/BT_WIFI_scan.cpp new file mode 100644 index 0000000..b3191d1 --- /dev/null +++ b/src/BT_WIFI_scan.cpp @@ -0,0 +1,112 @@ +#ifdef WIFI_SCANNING_ENABLED +#include "WiFi.h" +#endif + +// #define BT_SCANNING_ENABLED true +#ifdef BT_SCANNING_ENABLED +#include +#include +#include +#include +#endif + +#ifdef WIFI_SCANNING_ENABLED +// WiFi Scan +// TODO: Make Async Scan +// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html#async-scan +void scanWiFiWithOSDOut() +{ + osd.clear(); + osd.displayString(14, 2, "Scanning WiFi.."); + int n = WiFi.scanNetworks(); +#ifdef PRINT_DEBUG + Serial.println("scan done"); + if (n == 0) + { + Serial.println("no networks found"); + } +#endif + if (n > 0) + { +#ifdef PRINT_DEBUG + Serial.print(n); + Serial.println(" networks found"); +#endif + for (int i = 0; i < n; ++i) + { +// Print SSID and RSSI for each network found +#ifdef PRINT_DEBUG + Serial.print(i + 1); + Serial.print(": "); + Serial.print(WiFi.SSID(i)); + Serial.print(" ("); + Serial.print(WiFi.RSSI(i)); + Serial.print(")"); + Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*"); +#endif + osd.displayString(i + 1, 1, + "WF:" + String((WiFi.SSID(i) + ":" + WiFi.RSSI(i)))); + } + } + osd.displayChar(14, 1, 0x10f); +} +#endif + +#ifdef BT_SCANNING_ENABLED +//********************** +// BLE devices scan. +//*********************** +// TODO: Make Async Scan +// https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleAsyncScan.cpp +void scanBTWithOSDOut() +{ + osd.clear(); + osd.displayString(14, 2, "Scanning BT..."); + cycleCnt++; + + BLEDevice::init(""); + BLEScan *pBLEScan = BLEDevice::getScan(); + // active scan uses more power, but get results faster + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(0x50); + pBLEScan->setWindow(0x30); + +#ifdef SERIAL_PRINT + Serial.printf("Start BLE scan for %d seconds...\n", BT_SCAN_TIME); +#endif + + BLEScanResults foundDevices = pBLEScan->start(BT_SCAN_TIME); + int count = foundDevices.getCount(); +#ifdef PRINT_DEBUG + Serial.printf("Found devices: %d \n", count); +#endif + present = false; + for (int i = 0; i < count; i++) + { + BLEAdvertisedDevice device = foundDevices.getDevice(i); + String currDevAddr = device.getAddress().toString().c_str(); + String deviceName; + if (device.haveName()) + { + deviceName = device.getName().c_str(); + } + else + { + deviceName = currDevAddr; + } + +#ifdef PRINT_DEBUG + Serial.printf("Found device #%s/%s with RSSI: %d \n", currDevAddr, deviceName, + device.getRSSI()); +#endif + osd.displayString(i + 1, 1, + "BT:" + deviceName + ":" + String(device.getRSSI()) + " \n"); + } +#ifdef PRINT_DEBUG + Serial.println("Scan done!"); + Serial.printf("Cycle counter: %d, Free heap: %d \n", cycleCnt, ESP.getFreeHeap()); +#endif + osd.displayChar(14, 1, 0x10f); + scanFinished = true; +} +#endif diff --git a/src/OSD.cpp b/src/OSD.cpp new file mode 100644 index 0000000..cdee0f4 --- /dev/null +++ b/src/OSD.cpp @@ -0,0 +1,108 @@ + + +#ifdef OSD_ENABLED +void osd_spectrum() +{ // OSD enabled + + for (int i = 0; i < OSD_WIDTH; i++) + { + max_bins_array[i] = 33; + max_bins_array_value[i] = 0; + } + // memset(max_bins_array, 33, 30); + max_bin = 0; + + osd.displayString(12, 1, String(FREQ_BEGIN)); + osd.displayString(12, 30 - 8, String(FREQ_END)); + // Finding biggest in result + // Skiping 0 to avoid overflow + for (int i = 1; i < 32; i++) + { + // filter + if (result[i] > 0 && ((result[i - 1] != 0))) + { + max_bin = i; +#ifdef PRINT_DEBUG + Serial.print("MAX in bin:" + String(max_bin)); + Serial.println(); +#endif + break; + } + } + if (max_bins_array[col] > max_bin) + { + max_bins_array[col] = max_bin; +// Store RSSI value for RSSI Method +#ifdef METHOD_RSSI + max_bins_array_value[col] = result[max_bin]; +#endif + } + // Going to the next OSD step + if (x % osd_steps == 0 && col < 30) + { + // OSD SIDE BAR with frequency log +#ifdef OSD_SIDE_BAR + { + osd.displayString(col, 30 - 7, + String(FREQ_BEGIN + (col * osd_mhz_in_bin)) + ":" + + String(max_bins_array[col])); + } +#endif + // Test with Random Result... + // max_bins_array[s] = rand() % 32; +#ifdef METHOD_RSSI + // With THe RSSI method we can get real RSSI value not just a bin +#endif + // PRINT SIGNAL CHAR ROW, COL, VALUE + osdPrintSignalLevelChart(col, max_bins_array[col]); + +#ifdef PRINT_DEBUG + Serial.println("MAX:" + String(max_bins_array[col])); +#endif + col++; + } +} + +#ifdef OSD_ENABLED +unsigned short selectFreqChar(int bin, int start_level = 0) +{ + if (bin > start_level) + { + // level when we are starting show levels symbols + // you can override with your own character for example 0x100 = " " empty char + return power_level[33]; + } + else if (bin >= 0 && bin < MAX_POWER_LEVELS) + return power_level[bin]; + // when wrong bin number or noc har assigned we are showing "!" char + return 0x121; +} +#endif +#ifdef OSD_ENABLED +void osdPrintSignalLevelChart(int col, int signal_value) +{ + // Third line + if (signal_value <= 9) + { + osd.displayChar(13, col + 2, 0x100); + osd.displayChar(14, col + 2, 0x100); + osd.displayChar(12, col + 2, selectFreqChar(signal_value, drone_detection_level)); + } + // Second line + else if (max_bins_array[col] < 19) + { + osd.displayChar(12, col + 2, 0x100); + osd.displayChar(14, col + 2, 0x100); + osd.displayChar(13, col + 2, selectFreqChar(signal_value, drone_detection_level)); + } + // First line + else + { + // Clean Up symbol + osd.displayChar(12, col + 2, 0x100); + osd.displayChar(13, col + 2, 0x100); + osd.displayChar(14, col + 2, selectFreqChar(signal_value, drone_detection_level)); + } +} +#endif +#endif // END OSD ENABLED diff --git a/src/main.cpp b/src/main.cpp index 456892e..94b23f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,14 +25,26 @@ #include // This file contains a binary patch for the SX1262 #include "modules/SX126x/patches/SX126x_patch_scan.h" -#define OSD_ENABLED true +// #define OSD_ENABLED true +// #define WIFI_SCANNING_ENABLED true + +#define BT_SCAN_DELAY 60 * 1 * 1000 +#define WF_SCAN_DELAY 60 * 2 * 1000 +long noDevicesMillis = 0, cycleCnt = 0; +bool present = false; +bool scanFinished = true; + +// time to scan BT +#define BT_SCAN_TIME 10 + +uint64_t wf_start = 0; +uint64_t bt_start = 0; -#ifdef OSD_ENABLED #include "DFRobot_OSD.h" #define MAX_POWER_LEVELS 33 #define OSD_SIDE_BAR true -static const uint16_t power_level[MAX_POWER_LEVELS] = { +static const uint16_t power_level[MAX_POWER_LEVELS + 1] = { 0x10E, // 0 0x10E, // 1 0x10D, // 2 @@ -42,7 +54,7 @@ static const uint16_t power_level[MAX_POWER_LEVELS] = { 0x109, // 6 0x108, // 7 0x107, // 8 - 0x106, // 9 + 0x107, // 9 not using 106 // new line 0x10E, // 10 0x10D, // 11 @@ -52,7 +64,7 @@ static const uint16_t power_level[MAX_POWER_LEVELS] = { 0x109, // 15 0x108, // 16 0x107, // 17 - 0x106, // 18 + 0x107, // 18 not using 106 // new line 0x10E, // 19 0x10D, // 20 @@ -67,11 +79,12 @@ static const uint16_t power_level[MAX_POWER_LEVELS] = { 0x105, // 29 0x105, // 30 0x105, // 31 - 0x105 // 32 + 0x105, // 32 + 0x105 // 33 }; -#endif + // SPI pins -#define CS 47 +#define OSD_CS 47 #define OSD_MISO 33 #define OSD_MOSI 34 #define OSD_SCK 26 @@ -90,7 +103,7 @@ int osd_steps = 12; int global_counter = 0; #ifdef OSD_ENABLED -DFRobot_OSD osd(CS); +DFRobot_OSD osd(OSD_CS); #endif /*Define Custom characters Example*/ @@ -99,6 +112,9 @@ static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00, 0x49, 0x20, 0x5A, 0xA0, 0x44, 0x60, 0x88, 0x20}; // project components +#if defined(WIFI_SCANNING_ENABLED) && defined(BT_SCANNING_ENABLED) +#include "BT_WIFI_scan.h" +#endif #include "global_config.h" #include "ui.h" @@ -125,9 +141,9 @@ int SCAN_RANGES[] = {}; uint64_t RANGE_PER_PAGE = FREQ_END - FREQ_BEGIN; // FREQ_END - FREQ_BEGIN // multiplies STEPS * N to increase scan resolution. -#define SCAN_RBW_RFACTOR 2 +#define SCAN_RBW_FACTOR 2 -int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_RFACTOR) / OSD_CHART_WIDTH; +int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH; // To Enable Multi Screen scan // uint64_t RANGE_PER_PAGE = 50; @@ -144,13 +160,13 @@ int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_RFACTOR) / OSD_CHART_WIDTH; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez -#define SAMPLES 100 //(scan time = 1294) +#define SAMPLES 200 //(scan time = 1294) // number of samples for RSSI method -#define SAMPLES_RSSI 21 // 21 // +#define SAMPLES_RSSI 20 // 21 // #define RANGE (int)(FREQ_END - FREQ_BEGIN) -#define SINGLE_STEP (float)(RANGE / (STEPS * SCAN_RBW_RFACTOR)) +#define SINGLE_STEP (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)) uint64_t range = (int)(FREQ_END - FREQ_BEGIN); uint64_t fr_begin = FREQ_BEGIN; @@ -210,18 +226,16 @@ uint8_t button_pressed_counter = 0; uint64_t loop_cnt = 0; -unsigned short selectFreqChar(int bin) -{ - if (bin >= 0 && bin < MAX_POWER_LEVELS) - return power_level[bin]; - return 0x121; -} +#include "OSD.h" void setup(void) { + // LED brightness + heltec_led(25); #ifdef OSD_ENABLED osd.init(OSD_SCK, OSD_MISO, OSD_MOSI); osd.clear(); + /* Write the custom character to the OSD, replacing the original character*/ /* Expand 0xe0 to 0x0e0, the high 8 bits indicate page number and the low 8 bits * indicate the inpage address.*/ @@ -236,6 +250,8 @@ void setup(void) float vbat; float resolution; loop_cnt = 0; + bt_start = millis(); + wf_start = millis(); pinMode(LED, OUTPUT); pinMode(BUZZER_PIN, OUTPUT); @@ -278,10 +294,17 @@ void setup(void) both.println("Starting scanning..."); vbat = heltec_vbat(); both.printf("V battery: %.2fV (%d%%)\n", vbat, heltec_battery_percent(vbat)); +#ifdef WIFI_SCANNING_ENABLED + WiFi.mode(WIFI_STA); + WiFi.disconnect(); +#endif +#ifdef BT_SCANNING_ENABLED + +#endif delay(400); display.clear(); - resolution = RANGE / (STEPS * SCAN_RBW_RFACTOR); + resolution = RANGE / (STEPS * SCAN_RBW_FACTOR); single_page_scan = (RANGE_PER_PAGE == range); @@ -299,12 +322,12 @@ void setup(void) both.println("Multi Screen View Press P - button"); both.println("Multi Screan Res: " + String(resolution) + "Mhz/tick"); both.println( - "Resolution: " + String((float)RANGE_PER_PAGE / (STEPS * SCAN_RBW_RFACTOR)) + + "Resolution: " + String((float)RANGE_PER_PAGE / (STEPS * SCAN_RBW_FACTOR)) + "Mhz/tick"); for (int i = 0; i < 500; i++) { button.update(); - delay(10); + delay(5); both.print("."); if (button.pressed()) { @@ -323,7 +346,7 @@ void setup(void) both.println("Single screen View Press P - button"); both.println("Single screen Resol: " + String(resolution) + "Mhz/tick"); both.println( - "Resolution: " + String((float)RANGE_PER_PAGE / (STEPS * SCAN_RBW_RFACTOR)) + + "Resolution: " + String((float)RANGE_PER_PAGE / (STEPS * SCAN_RBW_FACTOR)) + "Mhz/tick"); for (int i = 0; i < 500; i++) { @@ -345,8 +368,10 @@ void setup(void) // calibrate only once ,,, at startup // TODO: check documentation (9.2.1) if we must calibrate in certain ranges radio.setFrequency(FREQ_BEGIN, true); + delay(50); #ifdef METHOD_RSSI + // TODO: try RADIOLIB_SX126X_RX_TIMEOUT_INF state = radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_NONE); if (state != RADIOLIB_ERR_NONE) { @@ -356,36 +381,17 @@ void setup(void) #endif // waterfall start line y-axis w = WATERFALL_START; -} - -void osdPrintSignalLevelChart(int col, int signal_value) -{ - // Third line - if (signal_value <= 7) - { - osd.displayChar(13, col + 2, 0x100); - osd.displayChar(14, col + 2, 0x100); - osd.displayChar(12, col + 2, selectFreqChar(signal_value)); - } - // Second line - else if (max_bins_array[col] < 17) - { - osd.displayChar(12, col + 2, 0x100); - osd.displayChar(14, col + 2, 0x100); - osd.displayChar(13, col + 2, selectFreqChar(signal_value)); - } - // First line - else - { - // Clean Up symbol - osd.displayChar(12, col + 2, 0x100); - osd.displayChar(13, col + 2, 0x100); - osd.displayChar(14, col + 2, selectFreqChar(signal_value)); - } +#ifdef OSD_ENABLED + osd.clear(); +#endif } // Formula to translate 33 bin to aproximate RSSI value -int binToRSSI(int bin) { return bin * 4; } +int binToRSSI(int bin) +{ + // the first the strongest RSSI in bin value is 0 + return 11 + (bin * 4); +} void loop(void) { @@ -404,11 +410,13 @@ void loop(void) loop_start = millis(); #endif +#ifdef DISABLED_CODE if (!ANIMATED_RELOAD || !single_page_scan) { // clear the scan plot rectangle UI_clearPlotter(); } +#endif // do the scan range = FREQ_END - FREQ_BEGIN; @@ -468,11 +476,13 @@ void loop(void) range = fr_end - fr_begin; } +#ifdef DISABLED_CODE if (!ANIMATED_RELOAD || !single_page_scan) { // clear the scan plot rectangle UI_clearPlotter(); } +#endif if (single_page_scan == false) { @@ -485,26 +495,30 @@ void loop(void) // horizontal (x axis) Frequency loop int osd_x = 1, osd_y = 1, col = 0, max_bin = 0; // x loop - for (x = 0; x < STEPS * SCAN_RBW_RFACTOR; x++) + for (x = 0; x < STEPS * SCAN_RBW_FACTOR; x++) { - if (x % SCAN_RBW_RFACTOR == 0) + if (x % SCAN_RBW_FACTOR == 0) new_pixel = true; else new_pixel = false; #if ANIMATED_RELOAD UI_drawCursor(x); #endif + if (new_pixel) + { + UI_drawCursor((int)(x / SCAN_RBW_FACTOR)); + } #ifdef PRINT_PROFILE_TIME scan_start_time = millis(); #endif // Real display pixel x - axis. - // Because of the SCAN_RBW_RFACTOR x is not a display coordinate anymore - // x > STEPS on SCAN_RBW_RFACTOR - int dispaly_x = x / SCAN_RBW_RFACTOR; + // Because of the SCAN_RBW_FACTOR x is not a display coordinate anymore + // x > STEPS on SCAN_RBW_FACTOR + int dispaly_x = x / SCAN_RBW_FACTOR; waterfall[dispaly_x] = false; - float step = (range * ((float)x / (STEPS * SCAN_RBW_RFACTOR))); + float step = (range * ((float)x / (STEPS * SCAN_RBW_FACTOR))); freq = fr_begin + step; @@ -523,7 +537,7 @@ void loop(void) { Serial.print("radio.spectralScanGetStatus ERROR: "); Serial.println(radio.spectralScanGetStatus()); - heltec_delay(ONE_MILLISEC); + heltec_delay(ONE_MILLISEC * 50); } // read the results Array to which the results will be saved radio.spectralScanGetResult(result); @@ -572,64 +586,17 @@ void loop(void) } #endif // SCAN_METHOD == METHOD_RSSI + // if this code is not executed LORA radio doesn't work + // basicaly SX1262 requers delay + // osd.displayString(12, 1, String(FREQ_BEGIN)); + // osd.displayString(12, 30 - 8, String(FREQ_END)); + // delay(2); + #ifdef OSD_ENABLED - { // OSD enabled + void osd_spectrum() +#endif - for (int i = 0; i < OSD_WIDTH; i++) - { - max_bins_array[i] = 33; - max_bins_array_value[i] = 0; - } - // memset(max_bins_array, 33, 30); - max_bin = 0; - - osd.displayString(12, 1, String(FREQ_BEGIN)); - osd.displayString(12, 30 - 8, String(FREQ_END)); - for (int i = 1; i < 32; i++) - { - if (result[i] > 0 && (result[i + 1] > 0)) - { - max_bin = i; -#ifdef PRINT_DEBUG - Serial.print("MAX in bin:" + String(max_bin)); - Serial.println(); -#endif - break; - } - } - if (max_bins_array[col] > max_bin) - { - max_bins_array[col] = max_bin; - // Store RSSI value for RSSI Method - max_bins_array_value[col] = result[max_bin]; - } - // Going to the next OSD step - if (x % osd_steps == 0 && col < 30) - { - // OSD SIDE BAR with frequency log -#ifdef OSD_SIDE_BAR - { - osd.displayString(col, 30 - 7, - String(FREQ_BEGIN + (col * osd_mhz_in_bin)) + - ":" + String(max_bins_array[col])); - } -#endif - // Test with Random Result... - // max_bins_array[s] = rand() % 32; -#ifdef METHOD_RSSI - // With THe RSSI method we can get real RSSI value not just a bin -#endif - // PRINT SIGNAL CHAR ROW, COL, VALUE - osdPrintSignalLevelChart(col, max_bins_array[col]); - -#ifdef PRINT_DEBUG - Serial.println("MAX:" + String(max_bins_array[s])); -#endif - col++; - } - } -#endif // END OSD ENABLED - detected = false; + detected = false; detected_y[dispaly_x] = false; for (y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++) @@ -670,117 +637,113 @@ void loop(void) } #endif - // if (result[y] || y == 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[dispaly_x] == false) // detection threshold match { - // 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[dispaly_x] == false) // detection threshold match - { - - // Set LED to ON (filtered in UI component) - UI_setLedFlag(true); + // Set LED to ON (filtered in UI component) + UI_setLedFlag(true); #if (WATERFALL_ENABLED == true) - if (single_page_scan) + if (single_page_scan) + { + // Drone detection true for waterfall + if (!waterfall[dispaly_x]) { - // Drone detection true for waterfall - if (!waterfall[dispaly_x]) - { - waterfall[dispaly_x] = true; - display.setColor(WHITE); - display.setPixel(dispaly_x, w); - } + waterfall[dispaly_x] = true; + display.setColor(WHITE); + display.setPixel(dispaly_x, w); } + } #endif - if (drone_detected_frequency_start == 0) - { - // mark freq start - drone_detected_frequency_start = freq; - } + if (drone_detected_frequency_start == 0) + { + // mark freq start + drone_detected_frequency_start = freq; + } - // mark freq end ... will shift right to last detected range - drone_detected_frequency_end = freq; + // mark freq end ... will shift right to last detected range + drone_detected_frequency_end = freq; - // If level is set to sensitive, - // start beeping every 10th frequency and shorter - // it improves performance less short beep delays... - if (drone_detection_level <= 25) + // If level is set to sensitive, + // start beeping every 10th frequency and shorter + // it improves performance less short beep delays... + if (drone_detection_level <= 25) + { + if (detection_count == 1 && SOUND_ON) { - if (detection_count == 1 && SOUND_ON) - { - tone(BUZZER_PIN, 205, - 10); // same action ??? but first time - } - if (detection_count % 5 == 0 && SOUND_ON) - { - tone(BUZZER_PIN, 205, - 10); // same action ??? but everey 5th time - } + tone(BUZZER_PIN, 205, + 10); // same action ??? but first time } - else + if (detection_count % 5 == 0 && SOUND_ON) { - if (detection_count % 20 == 0 && SOUND_ON) - { - tone(BUZZER_PIN, 205, - 10); // same action ??? but everey 20th detection - } + tone(BUZZER_PIN, 205, + 10); // same action ??? but everey 5th time } + } + else + { + if (detection_count % 20 == 0 && SOUND_ON) + { + tone(BUZZER_PIN, 205, + 10); // same action ??? but everey 20th detection + } + } #if (DRAW_DETECTION_TICKS == true) - // draw vertical line on top of display for "drone detected" - // frequencies - if (!detected_y[dispaly_x]) - { - display.drawLine(dispaly_x, 1, dispaly_x, 6); - detected_y[dispaly_x] = true; - } -#endif + // draw vertical line on top of display for "drone detected" + // frequencies + if (!detected_y[dispaly_x]) + { + display.drawLine(dispaly_x, 1, dispaly_x, 6); + detected_y[dispaly_x] = true; } +#endif + } #if (WATERFALL_ENABLED == true) - if ((filtered_result[y] == 1) && (y < drone_detection_level) && - (single_page_scan) && (waterfall[dispaly_x] != true) && new_pixel) - { - // If drone not found set dark pixel on the waterfall - // TODO: make something like scrolling up if possible - waterfall[dispaly_x] = false; - display.setColor(BLACK); - display.setPixel(dispaly_x, w); - display.setColor(WHITE); - } + if ((filtered_result[y] == 1) && (y < drone_detection_level) && + (single_page_scan) && (waterfall[dispaly_x] != true) && new_pixel) + { + // If drone not found set dark pixel on the waterfall + // TODO: make something like scrolling up if possible + waterfall[dispaly_x] = false; + display.setColor(BLACK); + display.setPixel(dispaly_x, w); + display.setColor(WHITE); + } #endif #if 0 #endif // If 0 - // next 2 If's ... adds !!!! 10ms of runtime ......tfk ??? + // next 2 If's ... adds !!!! 10ms of runtime ......tfk ??? + if (filtered_result[y] == 1) + { + // Set signal level pixel + display.setPixel(dispaly_x, y); + if (!detected) + { + detected = true; + } + } + + // ------------------------------------------------------------- + // Draw "Detection Level line" every 2 pixel + // ------------------------------------------------------------- + if ((y == drone_detection_level) && (dispaly_x % 2 == 0)) + { + display.setColor(WHITE); if (filtered_result[y] == 1) { - // Set signal level pixel - display.setPixel(dispaly_x, y); - if (!detected) - { - detected = true; - } + display.setColor(INVERSE); } + display.setPixel(dispaly_x, y); + display.setPixel(dispaly_x, y - 1); // 2 px wide - // ------------------------------------------------------------- - // Draw "Detection Level line" every 2 pixel - // ------------------------------------------------------------- - if ((y == drone_detection_level) && (dispaly_x % 2 == 0)) - { - display.setColor(WHITE); - if (filtered_result[y] == 1) - { - display.setColor(INVERSE); - } - display.setPixel(dispaly_x, y); - display.setPixel(dispaly_x, y - 1); // 2 px wide - - display.setColor(WHITE); - } + display.setColor(WHITE); } } @@ -859,7 +822,24 @@ void loop(void) // wait a little bit before the next scan, // otherwise the SX1262 hangs // Add more logic before insead of long delay... - // heltec_delay(1); + int delay_cnt = 1; + while (radio.spectralScanGetStatus() != RADIOLIB_ERR_NONE) + { + if (delay_cnt == 1) + { + // trying to use display as delay.. + display.display(); + } + else + { + Serial.println("spectralScanGetStatus ERROR(" + + String(radio.spectralScanGetStatus()) + + ") hard delay(1) - " + String(delay_cnt)); + heltec_delay(1); + } + delay_cnt++; + } + // TODO: move osd logic here as a dalay ;) // Loop is needed if heltec_delay(1) not used heltec_loop(); } @@ -877,15 +857,16 @@ void loop(void) display.setColor(WHITE); } #endif - // Render display data here display.display(); #ifdef OSD_ENABLED if (global_counter != 0 && global_counter % 50 == 0) { +#if !defined(BT_SCANNING_ENABLED) && !defined(WIFI_SCANNING_ENABLED) osd.clear(); osd.displayChar(14, 1, 0x10f); global_counter = 0; +#endif } global_counter++; #endif @@ -900,4 +881,24 @@ void loop(void) #ifdef PRINT_PROFILE_TIME Serial.printf("LOOP: %lld ms; SCAN: %lld ms;\n ", loop_time, scan_time); #endif +// No WiFi and BT Scan Without OSD +#ifdef OSD_ENABLED +#ifdef WIFI_SCANNING_ENABLED + if ((millis() - wf_start) > WF_SCAN_DELAY) + { + scanWiFiWithOSDOut(); + wf_start = millis(); + // prevent BT scanning after scanning WF + bt_start = millis(); + } +#endif +#ifdef BT_SCANNING_ENABLED + if ((millis() - bt_start) > BT_SCAN_DELAY) + { + + scanBTWithOSDOut(); + bt_start = millis(); + } +#endif +#endif } diff --git a/trans_src/main.cpp b/trans_src/main.cpp new file mode 100644 index 0000000..2010f48 --- /dev/null +++ b/trans_src/main.cpp @@ -0,0 +1,120 @@ +/** + * Send and receive LoRa-modulation packets with a sequence number, showing RSSI + * and SNR for received packets on the little display. + * + * Note that while this send and received using LoRa modulation, it does not do + * LoRaWAN. For that, see the LoRaWAN_TTN example. + * + * This works on the stick, but the output on the screen gets cut off. + */ + +// Turns the 'PRG' button into the power button, long press is off +#define HELTEC_POWER_BUTTON // must be before "#include " +#include + +// Pause between transmited packets in mseconds. +// Set to zero to only transmit a packet when pressing the user button +// Will not exceed 1% duty cycle, even if you set a lower value. +#define PAUSE 20 + +// Frequency in MHz. Keep the decimal point to designate float. +// Check your own rules and regulations to see what is legal where you are. +#define FREQUENCY 866.3 // for Europe +// #define FREQUENCY 905.2 // for US + +// LoRa bandwidth. Keep the decimal point to designate float. +// Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 +// kHz. +#define BANDWIDTH 250.0 + +// Number from 5 to 12. Higher means slower but higher "processor gain", +// meaning (in nutshell) longer range and more robust against interference. +#define SPREADING_FACTOR 9 + +// Transmit power in dBm. 0 dBm = 1 mW, enough for tabletop-testing. This value can be +// set anywhere between -9 dBm (0.125 mW) to 22 dBm (158 mW). Note that the maximum ERP +// (which is what your antenna maximally radiates) on the EU ISM band is 25 mW, and that +// transmissting without an antenna can damage your hardware. +#define TRANSMIT_POWER -9 + +String rxdata; +volatile bool rxFlag = false; +long counter = 0; +uint64_t last_tx = 0; +uint64_t tx_time; +uint64_t minimum_pause; + +// Can't do Serial or display things here, takes too much time for the interrupt +void rx() { rxFlag = true; } + +void setup() +{ + heltec_setup(); + both.println("Radio init"); + RADIOLIB_OR_HALT(radio.begin()); + // Set the callback function for received packets + radio.setDio1Action(rx); + // Set radio parameters + both.printf("Frequency: %.2f MHz\n", FREQUENCY); + RADIOLIB_OR_HALT(radio.setFrequency(FREQUENCY)); + both.printf("Bandwidth: %.1f kHz\n", BANDWIDTH); + RADIOLIB_OR_HALT(radio.setBandwidth(BANDWIDTH)); + both.printf("Spreading Factor: %i\n", SPREADING_FACTOR); + RADIOLIB_OR_HALT(radio.setSpreadingFactor(SPREADING_FACTOR)); + both.printf("TX power: %i dBm\n", TRANSMIT_POWER); + RADIOLIB_OR_HALT(radio.setOutputPower(TRANSMIT_POWER)); + // Start receiving + RADIOLIB_OR_HALT(radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF)); +} + +void loop() +{ + heltec_loop(); + + bool tx_legal = millis() > last_tx + minimum_pause; + // Transmit a packet every PAUSE seconds or when the button is pressed + if ((PAUSE && tx_legal && millis() - last_tx > (PAUSE)) || button.isSingleClick()) + { + // In case of button click, tell user to wait + if (!tx_legal) + { + both.printf("Legal limit, wait %i sec.\n", + (int)((minimum_pause - (millis() - last_tx)) / 1000) + 1); + return; + } + both.printf("TX [%s] ", String(counter).c_str()); + radio.clearDio1Action(); + heltec_led(50); // 50% brightness is plenty for this LED + tx_time = millis(); + RADIOLIB(radio.transmit(String(counter++).c_str())); + tx_time = millis() - tx_time; + heltec_led(0); + if (_radiolib_status == RADIOLIB_ERR_NONE) + { + both.printf("OK (%i ms)\n", (int)tx_time); + } + else + { + both.printf("fail (%i)\n", _radiolib_status); + } + // Maximum 1% duty cycle + minimum_pause = tx_time * 100; + last_tx = millis(); + radio.setDio1Action(rx); + RADIOLIB_OR_HALT(radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF)); + } + + // If a packet was received, display it and the RSSI and SNR + if (rxFlag) + { + rxFlag = false; + radio.readData(rxdata); + if (_radiolib_status == RADIOLIB_ERR_NONE) + { + both.printf("RX [%s]\n", rxdata.c_str()); + both.printf(" RSSI: %.2f dBm\n", radio.getRSSI()); + both.printf(" SNR: %.2f dB\n", radio.getSNR()); + } + RADIOLIB_OR_HALT(radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF)); + } +} From 385053235b5618d7a9c9b869d63fe03f62757536 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Tue, 20 Aug 2024 03:33:32 -0700 Subject: [PATCH 02/15] Revert "OSD + BT + WF" This reverts commit 36e6f8f2a81715420f0d40d4c1131913c5b2aeba. --- include/DFRobot_OSD.h | 4 +- include/global_config.h | 2 +- include/ui.h | 4 - platformio.ini | 4 - src/BT_WIFI_scan.cpp | 112 -------------- src/OSD.cpp | 108 -------------- src/main.cpp | 319 +++++++++++++++++++++++++++++++++++----- src/ui.cpp | 3 +- 8 files changed, 287 insertions(+), 269 deletions(-) delete mode 100644 src/BT_WIFI_scan.cpp delete mode 100644 src/OSD.cpp diff --git a/include/DFRobot_OSD.h b/include/DFRobot_OSD.h index 869bffb..d446a86 100644 --- a/include/DFRobot_OSD.h +++ b/include/DFRobot_OSD.h @@ -146,10 +146,10 @@ class DFRobot_OSD /** * @fn DFRobot_OSD * @brief Constructor - * @param OSD_CS - CS selection pin + * @param CS - CS selection pin * @return None */ - DFRobot_OSD(int OSD_CS); + DFRobot_OSD(int CS); ~DFRobot_OSD(); /** diff --git a/include/global_config.h b/include/global_config.h index b2bff67..115bf4a 100644 --- a/include/global_config.h +++ b/include/global_config.h @@ -12,7 +12,7 @@ #define BANDWIDTH 467.0 // Detection level from the 33 levels. The higher number is more sensitive -#define DEFAULT_DRONE_DETECTION_LEVEL 21 +#define DEFAULT_DRONE_DETECTION_LEVEL 20 #define BUZZER_PIN 41 diff --git a/include/ui.h b/include/ui.h index 9563ad7..1cbdba2 100644 --- a/include/ui.h +++ b/include/ui.h @@ -16,10 +16,6 @@ #define ONE_SEC 1000 #define ONE_MINUTE 60 * 1000 -// Prints debug information and the scan measurement bins from the SX1262 in -// hex Change spectrum plot values at once or by line -#define ANIMATED_RELOAD false - #define MAJOR_TICK_LENGTH 2 #define MINOR_TICK_LENGTH 1 // WEIGHT of the x-axis line diff --git a/platformio.ini b/platformio.ini index 7632ec6..5c24979 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,10 +8,6 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html -[platformio] -default_envs = heltec_wifi_lora_32_V3 -;src_dir = trans_src ;transmitter test project - [env:heltec_wifi_lora_32_V3] platform = espressif32 board = heltec_wifi_lora_32_V3 diff --git a/src/BT_WIFI_scan.cpp b/src/BT_WIFI_scan.cpp deleted file mode 100644 index b3191d1..0000000 --- a/src/BT_WIFI_scan.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifdef WIFI_SCANNING_ENABLED -#include "WiFi.h" -#endif - -// #define BT_SCANNING_ENABLED true -#ifdef BT_SCANNING_ENABLED -#include -#include -#include -#include -#endif - -#ifdef WIFI_SCANNING_ENABLED -// WiFi Scan -// TODO: Make Async Scan -// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html#async-scan -void scanWiFiWithOSDOut() -{ - osd.clear(); - osd.displayString(14, 2, "Scanning WiFi.."); - int n = WiFi.scanNetworks(); -#ifdef PRINT_DEBUG - Serial.println("scan done"); - if (n == 0) - { - Serial.println("no networks found"); - } -#endif - if (n > 0) - { -#ifdef PRINT_DEBUG - Serial.print(n); - Serial.println(" networks found"); -#endif - for (int i = 0; i < n; ++i) - { -// Print SSID and RSSI for each network found -#ifdef PRINT_DEBUG - Serial.print(i + 1); - Serial.print(": "); - Serial.print(WiFi.SSID(i)); - Serial.print(" ("); - Serial.print(WiFi.RSSI(i)); - Serial.print(")"); - Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*"); -#endif - osd.displayString(i + 1, 1, - "WF:" + String((WiFi.SSID(i) + ":" + WiFi.RSSI(i)))); - } - } - osd.displayChar(14, 1, 0x10f); -} -#endif - -#ifdef BT_SCANNING_ENABLED -//********************** -// BLE devices scan. -//*********************** -// TODO: Make Async Scan -// https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleAsyncScan.cpp -void scanBTWithOSDOut() -{ - osd.clear(); - osd.displayString(14, 2, "Scanning BT..."); - cycleCnt++; - - BLEDevice::init(""); - BLEScan *pBLEScan = BLEDevice::getScan(); - // active scan uses more power, but get results faster - pBLEScan->setActiveScan(true); - pBLEScan->setInterval(0x50); - pBLEScan->setWindow(0x30); - -#ifdef SERIAL_PRINT - Serial.printf("Start BLE scan for %d seconds...\n", BT_SCAN_TIME); -#endif - - BLEScanResults foundDevices = pBLEScan->start(BT_SCAN_TIME); - int count = foundDevices.getCount(); -#ifdef PRINT_DEBUG - Serial.printf("Found devices: %d \n", count); -#endif - present = false; - for (int i = 0; i < count; i++) - { - BLEAdvertisedDevice device = foundDevices.getDevice(i); - String currDevAddr = device.getAddress().toString().c_str(); - String deviceName; - if (device.haveName()) - { - deviceName = device.getName().c_str(); - } - else - { - deviceName = currDevAddr; - } - -#ifdef PRINT_DEBUG - Serial.printf("Found device #%s/%s with RSSI: %d \n", currDevAddr, deviceName, - device.getRSSI()); -#endif - osd.displayString(i + 1, 1, - "BT:" + deviceName + ":" + String(device.getRSSI()) + " \n"); - } -#ifdef PRINT_DEBUG - Serial.println("Scan done!"); - Serial.printf("Cycle counter: %d, Free heap: %d \n", cycleCnt, ESP.getFreeHeap()); -#endif - osd.displayChar(14, 1, 0x10f); - scanFinished = true; -} -#endif diff --git a/src/OSD.cpp b/src/OSD.cpp deleted file mode 100644 index cdee0f4..0000000 --- a/src/OSD.cpp +++ /dev/null @@ -1,108 +0,0 @@ - - -#ifdef OSD_ENABLED -void osd_spectrum() -{ // OSD enabled - - for (int i = 0; i < OSD_WIDTH; i++) - { - max_bins_array[i] = 33; - max_bins_array_value[i] = 0; - } - // memset(max_bins_array, 33, 30); - max_bin = 0; - - osd.displayString(12, 1, String(FREQ_BEGIN)); - osd.displayString(12, 30 - 8, String(FREQ_END)); - // Finding biggest in result - // Skiping 0 to avoid overflow - for (int i = 1; i < 32; i++) - { - // filter - if (result[i] > 0 && ((result[i - 1] != 0))) - { - max_bin = i; -#ifdef PRINT_DEBUG - Serial.print("MAX in bin:" + String(max_bin)); - Serial.println(); -#endif - break; - } - } - if (max_bins_array[col] > max_bin) - { - max_bins_array[col] = max_bin; -// Store RSSI value for RSSI Method -#ifdef METHOD_RSSI - max_bins_array_value[col] = result[max_bin]; -#endif - } - // Going to the next OSD step - if (x % osd_steps == 0 && col < 30) - { - // OSD SIDE BAR with frequency log -#ifdef OSD_SIDE_BAR - { - osd.displayString(col, 30 - 7, - String(FREQ_BEGIN + (col * osd_mhz_in_bin)) + ":" + - String(max_bins_array[col])); - } -#endif - // Test with Random Result... - // max_bins_array[s] = rand() % 32; -#ifdef METHOD_RSSI - // With THe RSSI method we can get real RSSI value not just a bin -#endif - // PRINT SIGNAL CHAR ROW, COL, VALUE - osdPrintSignalLevelChart(col, max_bins_array[col]); - -#ifdef PRINT_DEBUG - Serial.println("MAX:" + String(max_bins_array[col])); -#endif - col++; - } -} - -#ifdef OSD_ENABLED -unsigned short selectFreqChar(int bin, int start_level = 0) -{ - if (bin > start_level) - { - // level when we are starting show levels symbols - // you can override with your own character for example 0x100 = " " empty char - return power_level[33]; - } - else if (bin >= 0 && bin < MAX_POWER_LEVELS) - return power_level[bin]; - // when wrong bin number or noc har assigned we are showing "!" char - return 0x121; -} -#endif -#ifdef OSD_ENABLED -void osdPrintSignalLevelChart(int col, int signal_value) -{ - // Third line - if (signal_value <= 9) - { - osd.displayChar(13, col + 2, 0x100); - osd.displayChar(14, col + 2, 0x100); - osd.displayChar(12, col + 2, selectFreqChar(signal_value, drone_detection_level)); - } - // Second line - else if (max_bins_array[col] < 19) - { - osd.displayChar(12, col + 2, 0x100); - osd.displayChar(14, col + 2, 0x100); - osd.displayChar(13, col + 2, selectFreqChar(signal_value, drone_detection_level)); - } - // First line - else - { - // Clean Up symbol - osd.displayChar(12, col + 2, 0x100); - osd.displayChar(13, col + 2, 0x100); - osd.displayChar(14, col + 2, selectFreqChar(signal_value, drone_detection_level)); - } -} -#endif -#endif // END OSD ENABLED diff --git a/src/main.cpp b/src/main.cpp index 94b23f6..2ee1b37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,8 +25,8 @@ #include // This file contains a binary patch for the SX1262 #include "modules/SX126x/patches/SX126x_patch_scan.h" -// #define OSD_ENABLED true -// #define WIFI_SCANNING_ENABLED true +#define OSD_ENABLED true +// #define WIFI_SCANNING_ENABLED true #define BT_SCAN_DELAY 60 * 1 * 1000 #define WF_SCAN_DELAY 60 * 2 * 1000 @@ -44,6 +44,19 @@ uint64_t bt_start = 0; #define MAX_POWER_LEVELS 33 #define OSD_SIDE_BAR true +static const uint16_t levels[10] = { + 0x105, // 0 + 0x10E, // 1 + 0x10D, // 2 + 0x10C, // 3 + 0x10B, // 4 + 0x10A, // 5 + 0x109, // 6 + 0x108, // 7 + 0x107, // 8 + 0x106, // 9 +}; + static const uint16_t power_level[MAX_POWER_LEVELS + 1] = { 0x10E, // 0 0x10E, // 1 @@ -54,7 +67,7 @@ static const uint16_t power_level[MAX_POWER_LEVELS + 1] = { 0x109, // 6 0x108, // 7 0x107, // 8 - 0x107, // 9 not using 106 + 0x106, // 9 not using 106 to accent rise // new line 0x10E, // 10 0x10D, // 11 @@ -64,7 +77,7 @@ static const uint16_t power_level[MAX_POWER_LEVELS + 1] = { 0x109, // 15 0x108, // 16 0x107, // 17 - 0x107, // 18 not using 106 + 0x106, // 18 not using 106 // new line 0x10E, // 19 0x10D, // 20 @@ -75,7 +88,7 @@ static const uint16_t power_level[MAX_POWER_LEVELS + 1] = { 0x108, // 25 0x107, // 26 0x106, // 27 - 0x105, // 28 + 0x105, // 28 --- 0x105, // 29 0x105, // 30 0x105, // 31 @@ -113,8 +126,18 @@ static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00, // project components #if defined(WIFI_SCANNING_ENABLED) && defined(BT_SCANNING_ENABLED) -#include "BT_WIFI_scan.h" + +#include "WiFi.h" +// #define BT_SCANNING_ENABLED true +#ifdef BT_SCANNING_ENABLED +#include +#include +#include +#include #endif + +#endif + #include "global_config.h" #include "ui.h" @@ -151,12 +174,16 @@ int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH; #define DEFAULT_RANGE_PER_PAGE 50 +// Prints debug information and the scan measurement bins from the SX1262 in +// hex Change spectrum plot values at once or by line +bool ANIMATED_RELOAD = false; + // TODO: Ignore power lines #define UP_FILTER 5 #define LOW_FILTER 3 // Remove reading without neighbors #define FILTER_SPECTRUM_RESULTS true -#define DRAW_DETECTION_TICKS true +const bool DRAW_DETECTION_TICKS = true; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez @@ -184,8 +211,9 @@ uint16_t result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; uint16_t result_display_set[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; uint16_t result_detections[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; uint16_t filtered_result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; -uint16_t max_bins_array[OSD_WIDTH]; -int max_bins_array_value[OSD_WIDTH]; +uint16_t max_bins_array[MAX_POWER_LEVELS]; +int max_bins_array_value[MAX_POWER_LEVELS]; +int max_step_range = 32; // Waterfall array bool waterfall[STEPS], detected_y[STEPS]; // 20 - ??? steps of the waterfall @@ -214,7 +242,7 @@ uint64_t scan_start_time = 0; #endif uint64_t x, y, range_item, w, i = 0; -int osd_x = 1, osd_y = 2; +int osd_x = 1, osd_y = 2, col = 0, max_bin = 0; uint64_t ranges_count = 0; float freq = 0; @@ -226,7 +254,213 @@ uint8_t button_pressed_counter = 0; uint64_t loop_cnt = 0; -#include "OSD.h" +#ifdef WIFI_SCANNING_ENABLED +// WiFi Scan +// TODO: Make Async Scan +// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html#async-scan +void scanWiFiWithOSDOut() +{ + osd.clear(); + osd.displayString(14, 2, "Scanning WiFi.."); + int n = WiFi.scanNetworks(); +#ifdef PRINT_DEBUG + Serial.println("scan done"); + if (n == 0) + { + Serial.println("no networks found"); + } +#endif + if (n > 0) + { +#ifdef PRINT_DEBUG + Serial.print(n); + Serial.println(" networks found"); +#endif + for (int i = 0; i < n; ++i) + { +// Print SSID and RSSI for each network found +#ifdef PRINT_DEBUG + Serial.print(i + 1); + Serial.print(": "); + Serial.print(WiFi.SSID(i)); + Serial.print(" ("); + Serial.print(WiFi.RSSI(i)); + Serial.print(")"); + Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*"); +#endif + osd.displayString(i + 1, 1, + "WF:" + String((WiFi.SSID(i) + ":" + WiFi.RSSI(i)))); + } + } + osd.displayChar(14, 1, 0x10f); +} +#endif + +#ifdef BT_SCANNING_ENABLED +//********************** +// BLE devices scan. +//*********************** +// TODO: Make Async Scan +// https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleAsyncScan.cpp +void scanBTWithOSDOut() +{ + osd.clear(); + osd.displayString(14, 2, "Scanning BT..."); + cycleCnt++; + + BLEDevice::init(""); + BLEScan *pBLEScan = BLEDevice::getScan(); + // active scan uses more power, but get results faster + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(0x50); + pBLEScan->setWindow(0x30); + +#ifdef SERIAL_PRINT + Serial.printf("Start BLE scan for %d seconds...\n", BT_SCAN_TIME); +#endif + + BLEScanResults foundDevices = pBLEScan->start(BT_SCAN_TIME); + int count = foundDevices.getCount(); +#ifdef PRINT_DEBUG + Serial.printf("Found devices: %d \n", count); +#endif + present = false; + for (int i = 0; i < count; i++) + { + BLEAdvertisedDevice device = foundDevices.getDevice(i); + String currDevAddr = device.getAddress().toString().c_str(); + String deviceName; + if (device.haveName()) + { + deviceName = device.getName().c_str(); + } + else + { + deviceName = currDevAddr; + } + +#ifdef PRINT_DEBUG + Serial.printf("Found device #%s/%s with RSSI: %d \n", currDevAddr, deviceName, + device.getRSSI()); +#endif + osd.displayString(i + 1, 1, + "BT:" + deviceName + ":" + String(device.getRSSI()) + " \n"); + } +#ifdef PRINT_DEBUG + Serial.println("Scan done!"); + Serial.printf("Cycle counter: %d, Free heap: %d \n", cycleCnt, ESP.getFreeHeap()); +#endif + osd.displayChar(14, 1, 0x10f); + scanFinished = true; +} +#endif + +#ifdef OSD_ENABLED +unsigned short selectFreqChar(int bin, int start_level = 0) +{ + if (bin >= start_level) + { + // level when we are starting show levels symbols + // you can override with your own character for example 0x100 = " " empty char + return power_level[33]; + } + else if (bin >= 0 && bin < MAX_POWER_LEVELS) + return power_level[bin]; + // when wrong bin number or noc har assigned we are showing "!" char + return 0x121; +} + +void osdPrintSignalLevelChart(int col, int signal_value) +{ + // Third line + if (signal_value <= 9) + { + osd.displayChar(13, col + 2, 0x100); + osd.displayChar(14, col + 2, 0x100); + osd.displayChar(12, col + 2, selectFreqChar(signal_value, drone_detection_level)); + } + // Second line + else if (signal_value < 19) + { + osd.displayChar(12, col + 2, 0x100); + osd.displayChar(14, col + 2, 0x100); + osd.displayChar(13, col + 2, selectFreqChar(signal_value, drone_detection_level)); + } + // First line + else + { + // Clean Up symbol + osd.displayChar(12, col + 2, 0x100); + osd.displayChar(13, col + 2, 0x100); + osd.displayChar(14, col + 2, selectFreqChar(signal_value, drone_detection_level)); + } +} + +void osd_spectrum() +{ // OSD enabled + + // memset(max_bins_array, 33, 30); + max_bin = 0; + + osd.displayString(12, 1, String(FREQ_BEGIN)); + osd.displayString(12, 30 - 8, String(FREQ_END)); + // Finding biggest in result + // Skiping 0 to avoid overflow + for (int i = 1; i < 30 - 1; i++) + { + // filter + if (result[i] > 0 && + (result[i + 1] != 0 || (result[i - 1] != 0 && result[i - 2] != 0))) + { + max_bin = i; +#ifdef PRINT_DEBUG + Serial.print("MAX in bin:" + String(max_bin)); + Serial.println(); +#endif + break; + } + } + // max_bin contains fist not 0 index of the bin + if (max_step_range > max_bin) + { + max_step_range = max_bin; +// Store RSSI value for RSSI Method +#ifdef METHOD_RSSI + max_bins_array_value[col] = result[max_bin]; +#endif + } + // Going to the next OSD step + if (x % osd_steps == 0 && col < 30) + { + // some issue when median = 0 + if (max_step_range == 0) + { + max_step_range = 32; + } + // OSD SIDE BAR with frequency log +#ifdef OSD_SIDE_BAR + { + osd.displayString(col, 30 - 7, + String(FREQ_BEGIN + (col * osd_mhz_in_bin)) + "-" + + String(max_step_range) + " "); + } +#endif + // Test with Random Result... + // max_bins_array[s] = rand() % 32; +#ifdef METHOD_RSSI + // With THe RSSI method we can get real RSSI value not just a bin +#endif + // PRINT SIGNAL CHAR ROW, COL, VALUE + osdPrintSignalLevelChart(col, max_step_range); + +#ifdef PRINT_DEBUG + Serial.println("MAX:" + String(max_step_range)); +#endif + max_step_range = 32; + col++; + } +} +#endif void setup(void) { @@ -410,13 +644,11 @@ void loop(void) loop_start = millis(); #endif -#ifdef DISABLED_CODE if (!ANIMATED_RELOAD || !single_page_scan) { // clear the scan plot rectangle UI_clearPlotter(); } -#endif // do the scan range = FREQ_END - FREQ_BEGIN; @@ -492,8 +724,14 @@ void loop(void) drone_detected_frequency_start = 0; display.setTextAlignment(TEXT_ALIGN_RIGHT); + for (int i = 0; i < MAX_POWER_LEVELS; i++) + { + max_bins_array[i] = 32; + max_bins_array_value[i] = 0; + } + // horizontal (x axis) Frequency loop - int osd_x = 1, osd_y = 1, col = 0, max_bin = 0; + osd_x = 1, osd_y = 2, col = 0, max_bin = 0; // x loop for (x = 0; x < STEPS * SCAN_RBW_FACTOR; x++) { @@ -502,10 +740,11 @@ void loop(void) new_pixel = true; else new_pixel = false; -#if ANIMATED_RELOAD - UI_drawCursor(x); -#endif - if (new_pixel) + if (ANIMATED_RELOAD && SCAN_RBW_FACTOR == 1) + { + UI_drawCursor(x); + } + if (new_pixel && ANIMATED_RELOAD && SCAN_RBW_FACTOR > 1) { UI_drawCursor((int)(x / SCAN_RBW_FACTOR)); } @@ -537,7 +776,7 @@ void loop(void) { Serial.print("radio.spectralScanGetStatus ERROR: "); Serial.println(radio.spectralScanGetStatus()); - heltec_delay(ONE_MILLISEC * 50); + heltec_delay(ONE_MILLISEC * 10); } // read the results Array to which the results will be saved radio.spectralScanGetResult(result); @@ -549,7 +788,6 @@ void loop(void) Serial.println("METHOD RSSI"); #endif { - // memset // memset(result, 0, RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE); // Some issues with memset function @@ -588,15 +826,14 @@ void loop(void) // if this code is not executed LORA radio doesn't work // basicaly SX1262 requers delay - // osd.displayString(12, 1, String(FREQ_BEGIN)); + // osd.displayString(12, 1, String(FREQ_BEGIN)); // osd.displayString(12, 30 - 8, String(FREQ_END)); // delay(2); #ifdef OSD_ENABLED - void osd_spectrum() + osd_spectrum(); #endif - - detected = false; + detected = false; detected_y[dispaly_x] = false; for (y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++) @@ -627,9 +864,10 @@ void loop(void) { // do not process 'first' and 'last' row to avoid out of index // access - if ((y != 0) && (y != (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 1))) + if ((y != 0) && (y != (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 2))) { - if ((result[y + 1] != 0) || (result[y - 1] != 0)) + if ((result[y + 1] != 0) || + ((result[y - 1] != 0) && (result[y - 2] != 0))) { filtered_result[y] = 1; } @@ -691,19 +929,20 @@ void loop(void) } } -#if (DRAW_DETECTION_TICKS == true) - // draw vertical line on top of display for "drone detected" - // frequencies - if (!detected_y[dispaly_x]) + if (DRAW_DETECTION_TICKS == true) { - display.drawLine(dispaly_x, 1, dispaly_x, 6); - detected_y[dispaly_x] = true; + // draw vertical line on top of display for "drone detected" + // frequencies + if (!detected_y[dispaly_x]) + { + display.drawLine(dispaly_x, 1, dispaly_x, 6); + detected_y[dispaly_x] = true; + } } -#endif } #if (WATERFALL_ENABLED == true) - if ((filtered_result[y] == 1) && (y < drone_detection_level) && + if ((filtered_result[y] == 1) && (y <= drone_detection_level) && (single_page_scan) && (waterfall[dispaly_x] != true) && new_pixel) { // If drone not found set dark pixel on the waterfall @@ -834,8 +1073,10 @@ void loop(void) { Serial.println("spectralScanGetStatus ERROR(" + String(radio.spectralScanGetStatus()) + - ") hard delay(1) - " + String(delay_cnt)); - heltec_delay(1); + ") hard delay(2) - " + String(delay_cnt)); + // if error than speed is slow animating chart + ANIMATED_RELOAD = true; + heltec_delay(ONE_MILLISEC * 2); } delay_cnt++; } @@ -860,7 +1101,10 @@ void loop(void) // Render display data here display.display(); #ifdef OSD_ENABLED - if (global_counter != 0 && global_counter % 50 == 0) + // Sometimes OSD prints entire screan with the digits. + // We need clean the screan to fix it. + // We can do it every time but to optimise doing every N times + if (global_counter != 0 && global_counter % 10 == 0) { #if !defined(BT_SCANNING_ENABLED) && !defined(WIFI_SCANNING_ENABLED) osd.clear(); @@ -868,6 +1112,7 @@ void loop(void) global_counter = 0; #endif } + ANIMATED_RELOAD = false; global_counter++; #endif } diff --git a/src/ui.cpp b/src/ui.cpp index ada8a0b..2760253 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -143,10 +143,11 @@ void drawTicks(float every, int length) void UI_drawCursor(int16_t possition) { - // Draw animated cursor on reload process + // Draw animated vertical cursor on reload process display_instance->setColor(BLACK); display_instance->drawVerticalLine(possition, 0, HEIGHT); display_instance->drawVerticalLine(possition + 1, 0, HEIGHT); + display_instance->drawVerticalLine(possition + 2, 0, HEIGHT); display_instance->setColor(WHITE); } From 13a82043931e9ec8c233e97a2c181796935b0fe5 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Tue, 20 Aug 2024 03:53:20 -0700 Subject: [PATCH 03/15] Bt some fixes --- src/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2ee1b37..2e42425 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,7 +26,8 @@ // This file contains a binary patch for the SX1262 #include "modules/SX126x/patches/SX126x_patch_scan.h" #define OSD_ENABLED true -// #define WIFI_SCANNING_ENABLED true +// #define WIFI_SCANNING_ENABLED true +// #define BT_SCANNING_ENABLED true #define BT_SCAN_DELAY 60 * 1 * 1000 #define WF_SCAN_DELAY 60 * 2 * 1000 @@ -126,9 +127,7 @@ static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00, // project components #if defined(WIFI_SCANNING_ENABLED) && defined(BT_SCANNING_ENABLED) - #include "WiFi.h" -// #define BT_SCANNING_ENABLED true #ifdef BT_SCANNING_ENABLED #include #include From a6ff82c2fb07078b611d936a9a44c4334ba0d5ca Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Tue, 20 Aug 2024 04:18:18 -0700 Subject: [PATCH 04/15] some fixes --- src/main.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2e42425..eb6c84e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -230,7 +230,7 @@ uint64_t detection_count = 0; bool single_page_scan = false; bool SOUND_ON = false; -// #define PRINT_DEBUG +#define PRINT_DEBUG #define PRINT_PROFILE_TIME #ifdef PRINT_PROFILE_TIME @@ -241,7 +241,7 @@ uint64_t scan_start_time = 0; #endif uint64_t x, y, range_item, w, i = 0; -int osd_x = 1, osd_y = 2, col = 0, max_bin = 0; +int osd_x = 1, osd_y = 2, col = 0, max_bin = 32; uint64_t ranges_count = 0; float freq = 0; @@ -399,17 +399,17 @@ void osd_spectrum() { // OSD enabled // memset(max_bins_array, 33, 30); - max_bin = 0; + max_bin = 32; osd.displayString(12, 1, String(FREQ_BEGIN)); osd.displayString(12, 30 - 8, String(FREQ_END)); // Finding biggest in result // Skiping 0 to avoid overflow - for (int i = 1; i < 30 - 1; i++) + for (int i = 1; i < 30; i++) { // filter if (result[i] > 0 && - (result[i + 1] != 0 || (result[i - 1] != 0 && result[i - 2] != 0))) + ((result[i + 1] != 0 && result[i + 2] != 0) || result[i - 1] != 0)) { max_bin = i; #ifdef PRINT_DEBUG @@ -420,7 +420,7 @@ void osd_spectrum() } } // max_bin contains fist not 0 index of the bin - if (max_step_range > max_bin) + if (max_step_range > max_bin && max_bin != 0) { max_step_range = max_bin; // Store RSSI value for RSSI Method @@ -863,10 +863,10 @@ void loop(void) { // 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 ((y != 0) && (y != (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 3))) { - if ((result[y + 1] != 0) || - ((result[y - 1] != 0) && (result[y - 2] != 0))) + if (((result[y + 1] != 0) && (result[y + 2] != 0)) || + (result[y - 1] != 0)) { filtered_result[y] = 1; } From 94d9b2311f3586089561c283887772d9a82dab16 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Tue, 20 Aug 2024 04:18:51 -0700 Subject: [PATCH 05/15] some fixes --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index eb6c84e..1c6f264 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -230,7 +230,7 @@ uint64_t detection_count = 0; bool single_page_scan = false; bool SOUND_ON = false; -#define PRINT_DEBUG +// #define PRINT_DEBUG #define PRINT_PROFILE_TIME #ifdef PRINT_PROFILE_TIME From f09d904877cce3df18d583135ef7be0002f1c127 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Tue, 20 Aug 2024 19:21:41 -0700 Subject: [PATCH 06/15] add more --- include/OSD.h | 6 ------ include/ui.h | 4 ++-- src/main.cpp | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 include/OSD.h diff --git a/include/OSD.h b/include/OSD.h deleted file mode 100644 index e87600e..0000000 --- a/include/OSD.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _OSD_H_ -#define _OSD_H_ -extern void osd_spectrum(); -extern void osdPrintSignalLevelChart(int col, int signal_value); -extern unsigned short selectFreqChar(int bin, int start_level = 0); -#endif diff --git a/include/ui.h b/include/ui.h index 1cbdba2..0eb1a1c 100644 --- a/include/ui.h +++ b/include/ui.h @@ -13,8 +13,8 @@ #define MINOR_TICKS 5 #define ONE_MILLISEC 1 -#define ONE_SEC 1000 -#define ONE_MINUTE 60 * 1000 +#define ONE_SEC_MIL 1000 +#define ONE_MINUTE_MIL 60 * 1000 #define MAJOR_TICK_LENGTH 2 #define MINOR_TICK_LENGTH 1 diff --git a/src/main.cpp b/src/main.cpp index 1c6f264..bf4d347 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -395,7 +395,7 @@ void osdPrintSignalLevelChart(int col, int signal_value) } } -void osd_spectrum() +void osdProcess() { // OSD enabled // memset(max_bins_array, 33, 30); From 9e4d71bc1cc148c5f7d3297f39bc6299d4bcc720 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Tue, 20 Aug 2024 19:26:45 -0700 Subject: [PATCH 07/15] osdProcess --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index bf4d347..67ac7d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -830,7 +830,7 @@ void loop(void) // delay(2); #ifdef OSD_ENABLED - osd_spectrum(); + osdProcess(); #endif detected = false; detected_y[dispaly_x] = false; From a094a15260df8ba4f35e9aa386ee84096a6f4a2e Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 15:19:32 -0700 Subject: [PATCH 08/15] fixes --- include/BT_WIFI_scan.h | 5 +---- include/ui.h | 5 +---- src/main.cpp | 42 +++++++++++++++++++----------------------- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/include/BT_WIFI_scan.h b/include/BT_WIFI_scan.h index bbafb39..5a4722b 100644 --- a/include/BT_WIFI_scan.h +++ b/include/BT_WIFI_scan.h @@ -1,7 +1,4 @@ -#ifndef _BT_WIFI_SCAN_H_ -#define _BT_WIFI_SCAN_H_ +#pragma once extern void scanWiFiWithOSDOut(); extern void scanBTWithOSDOut(); - -#endif diff --git a/include/ui.h b/include/ui.h index 0eb1a1c..2dcaa96 100644 --- a/include/ui.h +++ b/include/ui.h @@ -1,6 +1,5 @@ -#ifndef __UI_H__ -#define __UI_H__ +#pragma once #include "OLEDDisplayUi.h" #include "SSD1306Wire.h" @@ -35,5 +34,3 @@ extern void UI_displayDecorate(int, int, bool); extern void UI_setLedFlag(bool); extern void UI_clearPlotter(void); extern void UI_drawCursor(int16_t); - -#endif // __UI_H__ diff --git a/src/main.cpp b/src/main.cpp index 67ac7d3..76dee2c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,7 +25,7 @@ #include // This file contains a binary patch for the SX1262 #include "modules/SX126x/patches/SX126x_patch_scan.h" -#define OSD_ENABLED true +// #define OSD_ENABLED true // #define WIFI_SCANNING_ENABLED true // #define BT_SCANNING_ENABLED true @@ -45,7 +45,7 @@ uint64_t bt_start = 0; #define MAX_POWER_LEVELS 33 #define OSD_SIDE_BAR true -static const uint16_t levels[10] = { +static constexpr uint16_t levels[10] = { 0x105, // 0 0x10E, // 1 0x10D, // 2 @@ -58,7 +58,7 @@ static const uint16_t levels[10] = { 0x106, // 9 }; -static const uint16_t power_level[MAX_POWER_LEVELS + 1] = { +static constexpr uint16_t power_level[MAX_POWER_LEVELS + 1] = { 0x10E, // 0 0x10E, // 1 0x10D, // 2 @@ -126,8 +126,9 @@ static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00, 0x49, 0x20, 0x5A, 0xA0, 0x44, 0x60, 0x88, 0x20}; // project components -#if defined(WIFI_SCANNING_ENABLED) && defined(BT_SCANNING_ENABLED) +#ifdef WIFI_SCANNING_ENABLED #include "WiFi.h" +#endif #ifdef BT_SCANNING_ENABLED #include #include @@ -135,8 +136,6 @@ static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00, #include #endif -#endif - #include "global_config.h" #include "ui.h" @@ -165,7 +164,7 @@ 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 -int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH; +constexpr int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH; // To Enable Multi Screen scan // uint64_t RANGE_PER_PAGE = 50; @@ -173,8 +172,7 @@ int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH; #define DEFAULT_RANGE_PER_PAGE 50 -// Prints debug information and the scan measurement bins from the SX1262 in -// hex Change spectrum plot values at once or by line +// Print spectrum values pixels at once or by line bool ANIMATED_RELOAD = false; // TODO: Ignore power lines @@ -182,11 +180,11 @@ bool ANIMATED_RELOAD = false; #define LOW_FILTER 3 // Remove reading without neighbors #define FILTER_SPECTRUM_RESULTS true -const bool DRAW_DETECTION_TICKS = true; +constexpr bool DRAW_DETECTION_TICKS = true; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez -#define SAMPLES 200 //(scan time = 1294) +#define SAMPLES 100 //(scan time = 1294) // number of samples for RSSI method #define SAMPLES_RSSI 20 // 21 // @@ -210,7 +208,7 @@ uint16_t result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; uint16_t result_display_set[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; uint16_t result_detections[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; uint16_t filtered_result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; -uint16_t max_bins_array[MAX_POWER_LEVELS]; + int max_bins_array_value[MAX_POWER_LEVELS]; int max_step_range = 32; @@ -248,9 +246,7 @@ float freq = 0; int rssi = 0; int state = 0; uint8_t result_index = 0; - uint8_t button_pressed_counter = 0; - uint64_t loop_cnt = 0; #ifdef WIFI_SCANNING_ENABLED @@ -311,6 +307,7 @@ void scanBTWithOSDOut() BLEScan *pBLEScan = BLEDevice::getScan(); // active scan uses more power, but get results faster pBLEScan->setActiveScan(true); + // TODO: adjust interval and window pBLEScan->setInterval(0x50); pBLEScan->setWindow(0x30); @@ -398,14 +395,14 @@ void osdPrintSignalLevelChart(int col, int signal_value) void osdProcess() { // OSD enabled - // memset(max_bins_array, 33, 30); + // memset(max_step_range, 33, 30); max_bin = 32; osd.displayString(12, 1, String(FREQ_BEGIN)); - osd.displayString(12, 30 - 8, String(FREQ_END)); + osd.displayString(12, OSD_WIDTH - 8, String(FREQ_END)); // Finding biggest in result - // Skiping 0 to avoid overflow - for (int i = 1; i < 30; i++) + // Skiping 0 and 32 31 to avoid overflow + for (int i = 1; i < MAX_POWER_LEVELS - 3; i++) { // filter if (result[i] > 0 && @@ -429,23 +426,23 @@ void osdProcess() #endif } // Going to the next OSD step - if (x % osd_steps == 0 && col < 30) + if (x % osd_steps == 0 && col < OSD_WIDTH) { // some issue when median = 0 if (max_step_range == 0) { - max_step_range = 32; + max_step_range = OSD_WIDTH - 1; } // OSD SIDE BAR with frequency log #ifdef OSD_SIDE_BAR { - osd.displayString(col, 30 - 7, + osd.displayString(col, OSD_WIDTH - 7, String(FREQ_BEGIN + (col * osd_mhz_in_bin)) + "-" + String(max_step_range) + " "); } #endif // Test with Random Result... - // max_bins_array[s] = rand() % 32; + // max_step_range = rand() % 32; #ifdef METHOD_RSSI // With THe RSSI method we can get real RSSI value not just a bin #endif @@ -725,7 +722,6 @@ void loop(void) for (int i = 0; i < MAX_POWER_LEVELS; i++) { - max_bins_array[i] = 32; max_bins_array_value[i] = 0; } From fee95622f5f277ce105a62af8f1959d35bfcc5d3 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 16:07:05 -0700 Subject: [PATCH 09/15] fixes --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 76dee2c..ce89dbf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,6 +41,7 @@ bool scanFinished = true; uint64_t wf_start = 0; uint64_t bt_start = 0; +#ifndef OSD_ENABLED #include "DFRobot_OSD.h" #define MAX_POWER_LEVELS 33 #define OSD_SIDE_BAR true @@ -102,6 +103,7 @@ static constexpr uint16_t power_level[MAX_POWER_LEVELS + 1] = { #define OSD_MISO 33 #define OSD_MOSI 34 #define OSD_SCK 26 +#endif #define OSD_WIDTH 30 #define OSD_HEIGHT 16 From d956f8778f76fdd618e122ae48fee7c49ae32bff Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 16:08:17 -0700 Subject: [PATCH 10/15] fix --- src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ce89dbf..ff9939d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -255,7 +255,7 @@ uint64_t loop_cnt = 0; // WiFi Scan // TODO: Make Async Scan // https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html#async-scan -void scanWiFiWithOSDOut() +void scanWiFi() { osd.clear(); osd.displayString(14, 2, "Scanning WiFi.."); @@ -299,7 +299,7 @@ void scanWiFiWithOSDOut() //*********************** // TODO: Make Async Scan // https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleAsyncScan.cpp -void scanBTWithOSDOut() +void scanBT() { osd.clear(); osd.displayString(14, 2, "Scanning BT..."); @@ -1128,7 +1128,7 @@ void loop(void) #ifdef WIFI_SCANNING_ENABLED if ((millis() - wf_start) > WF_SCAN_DELAY) { - scanWiFiWithOSDOut(); + scanWiFi(); wf_start = millis(); // prevent BT scanning after scanning WF bt_start = millis(); @@ -1138,7 +1138,7 @@ void loop(void) if ((millis() - bt_start) > BT_SCAN_DELAY) { - scanBTWithOSDOut(); + scanBT(); bt_start = millis(); } #endif From 456778f10249c42e44a6be1b44f44cdb167f22ff Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 18:00:21 -0700 Subject: [PATCH 11/15] if samples = 1 --- src/main.cpp | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ff9939d..e1e76e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -186,7 +186,7 @@ constexpr bool DRAW_DETECTION_TICKS = true; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez -#define SAMPLES 100 //(scan time = 1294) +#define SAMPLES 60 //(scan time = 1294) // number of samples for RSSI method #define SAMPLES_RSSI 20 // 21 // @@ -247,6 +247,14 @@ uint64_t ranges_count = 0; float freq = 0; int rssi = 0; int state = 0; + +#ifdef METHOD_SPECTRAL +constexpr int samples = SAMPLES; +#endif +#ifdef METHOD_RSSI +constexpr int samples = SAMPLES_RSSI; +#endif + uint8_t result_index = 0; uint8_t button_pressed_counter = 0; uint64_t loop_cnt = 0; @@ -406,9 +414,13 @@ void osdProcess() // Skiping 0 and 32 31 to avoid overflow for (int i = 1; i < MAX_POWER_LEVELS - 3; i++) { + // filter - if (result[i] > 0 && - ((result[i + 1] != 0 && result[i + 2] != 0) || result[i - 1] != 0)) + if (result[i] > 0 +#if FILTER_SPECTRUM_RESULTS + && ((result[i + 1] != 0 && result[i + 2] != 0) || result[i - 1] != 0) +#endif + ) { max_bin = i; #ifdef PRINT_DEBUG @@ -841,7 +853,7 @@ void loop(void) Serial.print(String(result[y]) + ","); #endif -#if FILTER_SPECTRUM_RESULTS == false +#if !defined(FILTER_SPECTRUM_RESULTS) || FILTER_SPECTRUM_RESULTS == false if (result[y] && result[y] != 0) { filtered_result[y] = 1; @@ -852,12 +864,13 @@ void loop(void) } #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]) + if (result[y] > 0 && samples > 1) { // do not process 'first' and 'last' row to avoid out of index // access @@ -869,6 +882,10 @@ void loop(void) filtered_result[y] = 1; } } + } // not filtering if samples == 1 + else if (result[y] > 0 && samples == 1) + { + filtered_result[y] = 1; } #endif @@ -1068,13 +1085,15 @@ void loop(void) } else { - Serial.println("spectralScanGetStatus ERROR(" + - String(radio.spectralScanGetStatus()) + - ") hard delay(2) - " + String(delay_cnt)); - // if error than speed is slow animating chart - ANIMATED_RELOAD = true; heltec_delay(ONE_MILLISEC * 2); } + + Serial.println("spectralScanGetStatus ERROR(" + + String(radio.spectralScanGetStatus()) + + ") hard delay(2) - " + String(delay_cnt)); + // if error than speed is slow animating chart + ANIMATED_RELOAD = true; + delay_cnt++; } // TODO: move osd logic here as a dalay ;) From dbcccc4ae826dfbbe7eea0089670008e43dfe729 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 18:03:36 -0700 Subject: [PATCH 12/15] samples 30 --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e1e76e5..d93f038 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -186,7 +186,7 @@ constexpr bool DRAW_DETECTION_TICKS = true; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez -#define SAMPLES 60 //(scan time = 1294) +#define SAMPLES 35 //(scan time = 1294) // number of samples for RSSI method #define SAMPLES_RSSI 20 // 21 // @@ -874,7 +874,7 @@ void loop(void) { // do not process 'first' and 'last' row to avoid out of index // access - if ((y != 0) && (y != (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 3))) + if ((y > 0) && (y != (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 3))) { if (((result[y + 1] != 0) && (result[y + 2] != 0)) || (result[y - 1] != 0)) From 7386dc91f68f8e038db2ab448704de97c03af99a Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 18:05:58 -0700 Subject: [PATCH 13/15] filter noize --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d93f038..a9a73ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -873,7 +873,7 @@ void loop(void) if (result[y] > 0 && samples > 1) { // do not process 'first' and 'last' row to avoid out of index - // access + // access. if ((y > 0) && (y != (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 3))) { if (((result[y + 1] != 0) && (result[y + 2] != 0)) || From 616942ba5328a16caffab30c4d83907538372b6c Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 23:04:07 -0700 Subject: [PATCH 14/15] add Filter debug data --- src/main.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a9a73ef..edbaa0e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -182,11 +182,12 @@ bool ANIMATED_RELOAD = false; #define LOW_FILTER 3 // Remove reading without neighbors #define FILTER_SPECTRUM_RESULTS true +#define FILTER_SAMPLES_MIN constexpr bool DRAW_DETECTION_TICKS = true; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez -#define SAMPLES 35 //(scan time = 1294) +#define SAMPLES 1 //(scan time = 1294) // number of samples for RSSI method #define SAMPLES_RSSI 20 // 21 // @@ -567,7 +568,7 @@ void setup(void) both.println("Multi Screan Res: " + String(resolution) + "Mhz/tick"); both.println( "Resolution: " + String((float)RANGE_PER_PAGE / (STEPS * SCAN_RBW_FACTOR)) + - "Mhz/tick"); + "MHz/tick"); for (int i = 0; i < 500; i++) { button.update(); @@ -792,11 +793,11 @@ void loop(void) } #endif #ifdef METHOD_RSSI -// Spectrum analyzer using getRSSI -#ifdef PRINT_DEBUG - Serial.println("METHOD RSSI"); -#endif + // Spectrum analyzer using getRSSI { +#ifdef PRINT_DEBUG + Serial.println("METHOD RSSI"); +#endif // memset // memset(result, 0, RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE); // Some issues with memset function @@ -866,7 +867,6 @@ void loop(void) // 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 @@ -881,6 +881,12 @@ void loop(void) { filtered_result[y] = 1; } + else + { +#ifdef PRINT_DEBUG + Serial.print("Filtered:" + String(x) + ":" + String(y) + ","); +#endif + } } } // not filtering if samples == 1 else if (result[y] > 0 && samples == 1) @@ -888,7 +894,6 @@ void loop(void) filtered_result[y] = 1; } #endif - // check if we should alarm about a drone presence if ((filtered_result[y] == 1) // we have some data and && (y <= drone_detection_level) && @@ -975,6 +980,10 @@ void loop(void) // next 2 If's ... adds !!!! 10ms of runtime ......tfk ??? if (filtered_result[y] == 1) { +#ifdef PRINT_DEBUG + Serial.print("Pixel:" + String(dispaly_x) + "(" + String(x) + ")" + + ":" + String(y) + ","); +#endif // Set signal level pixel display.setPixel(dispaly_x, y); if (!detected) From c106ff7e3d0488c23586ab8f6e8563506c48355a Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Wed, 21 Aug 2024 23:05:03 -0700 Subject: [PATCH 15/15] #define SAMPLES 35 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index edbaa0e..6d3d619 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -187,7 +187,7 @@ constexpr bool DRAW_DETECTION_TICKS = true; // Number of samples for each frequency scan. Fewer samples = better temporal resolution. // if more than 100 it can freez -#define SAMPLES 1 //(scan time = 1294) +#define SAMPLES 35 //(scan time = 1294) // number of samples for RSSI method #define SAMPLES_RSSI 20 // 21 //