From 783e695771fde102d8c1876256a5c902a9173e82 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 01:14:04 -0700 Subject: [PATCH 01/21] Add HTML server --- data/index.html | 40 ++++++++++++++++ data/style.css | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ data/text.txt | 0 include/File.h | 43 ++++++++++++++++++ platformio.ini | 3 ++ src/main.cpp | 19 ++++++++ 6 files changed, 223 insertions(+) create mode 100644 data/index.html create mode 100644 data/style.css create mode 100644 data/text.txt create mode 100644 include/File.h diff --git a/data/index.html b/data/index.html new file mode 100644 index 0000000..92cddf1 --- /dev/null +++ b/data/index.html @@ -0,0 +1,40 @@ + + + + + ESP Wi-Fi Manager + + + + + + +
+

LORA SA ESP32 CONFIG

+
+
+
+
+
+

+ +
+ +
+ +
+ +
+ +
+ +
+ +

+
+
+
+
+ + + diff --git a/data/style.css b/data/style.css new file mode 100644 index 0000000..491d8c4 --- /dev/null +++ b/data/style.css @@ -0,0 +1,118 @@ +html { + font-family: Arial, Helvetica, sans-serif; + display: inline-block; + text-align: center; +} + +h1 { + font-size: 1.8rem; + color: white; +} + +p { + font-size: 1.4rem; +} + +.topnav { + overflow: hidden; + background-color: #0A1128; +} + +body { + margin: 0; +} + +.content { + padding: 5%; +} + +.card-grid { + max-width: 800px; + margin: 0 auto; + display: grid; + grid-gap: 2rem; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); +} + +.card { + background-color: white; + box-shadow: 2px 2px 12px 1px rgba(140, 140, 140, .5); +} + +.card-title { + font-size: 1.2rem; + font-weight: bold; + color: #034078 +} + +input[type=submit] { + border: none; + color: #FEFCFB; + background-color: #034078; + padding: 15px 15px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + width: 100px; + margin-right: 10px; + border-radius: 4px; + transition-duration: 0.4s; +} + +input[type=submit]:hover { + background-color: #1282A2; +} + +input[type=text], +input[type=number], +select { + width: 50%; + padding: 12px 20px; + margin: 18px; + display: inline-block; + border: 1px solid #ccc; + border-radius: 4px; + box-sizing: border-box; +} + +label { + font-size: 1.2rem; +} + +.value { + font-size: 1.2rem; + color: #1282A2; +} + +.state { + font-size: 1.2rem; + color: #1282A2; +} + +button { + border: none; + color: #FEFCFB; + padding: 15px 32px; + text-align: center; + font-size: 16px; + width: 100px; + border-radius: 4px; + transition-duration: 0.4s; +} + +.button-on { + background-color: #034078; +} + +.button-on:hover { + background-color: #1282A2; +} + +.button-off { + background-color: #858585; +} + +.button-off:hover { + background-color: #252524; +} diff --git a/data/text.txt b/data/text.txt new file mode 100644 index 0000000..e69de29 diff --git a/include/File.h b/include/File.h new file mode 100644 index 0000000..d726c40 --- /dev/null +++ b/include/File.h @@ -0,0 +1,43 @@ +#include "FS.h" +#include + +String readFile(fs::FS &fs, const char *path) +{ + Serial.printf("Reading file: %s\r\n", path); + + File file = fs.open(path); + if (!file || file.isDirectory()) + { + Serial.println("- failed to open file for reading"); + return String(""); + } + String content; + Serial.println("- read from file:"); + while (file.available()) + { + content = file.readStringUntil('\n'); + } + file.close(); + return content; +} + +void writeFile(fs::FS &fs, const char *path, const char *message) +{ + Serial.printf("Writing file: %s\r\n", path); + + File file = fs.open(path, FILE_WRITE); + if (!file) + { + Serial.println("- failed to open file for writing"); + return; + } + if (file.print(message)) + { + Serial.println("- file written"); + } + else + { + Serial.println("- write failed"); + } + file.close(); +} diff --git a/platformio.ini b/platformio.ini index 32ddad0..2868df9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,12 +26,15 @@ framework = arduino upload_speed = 921600 monitor_speed = 115200 board_build.f_cpu = 240000000 +board_build.filesystem = littlefs lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 bblanchon/ArduinoJson@^7.2.0 + ESP Async WebServer build_flags = -DHELTEC_POWER_BUTTON -DHELTEC + [env:heltec_wifi_lora_32_V3_433] platform = espressif32 diff --git a/src/main.cpp b/src/main.cpp index a3d9b44..20fa879 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,9 +27,18 @@ #ifdef HELTEC #include #endif +#include "FS.h" +#include +#include +#include +#include #include #include +#include "WIFI_SERVER.h" + +#define FORMAT_LITTLEFS_IF_FAILED true + // #define OSD_ENABLED true // #define WIFI_SCANNING_ENABLED true // #define BT_SCANNING_ENABLED true @@ -548,6 +557,7 @@ void drone_sound_alarm(void *arg, Event &e); void setup(void) { + #ifdef LILYGO setupBoards(); // true for disable U8g2 display library delay(500); @@ -580,6 +590,7 @@ void setup(void) pinMode(BUZZER_PIN, OUTPUT); pinMode(REB_PIN, OUTPUT); heltec_setup(); + serverStart(); #ifdef JOYSTICK_ENABLED calibrate_joy(); pinMode(JOY_BTN_PIN, INPUT_PULLUP); @@ -600,6 +611,14 @@ void setup(void) } init_radio(); + + if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) + { + Serial.println("LittleFS Mount Failed"); + } + + // writeFile(LittleFS, "/text.txt", "{WIFI:{name:\"sdfsdf\", Password:\"sdfsdf\"}"); + Serial.println(readFile(LittleFS, "/text.txt")); #ifndef LILYGO vbat = heltec_vbat(); both.printf("V battery: %.2fV (%d%%)\n", vbat, heltec_battery_percent(vbat)); From 6ce1058c6658d51f8e4bf5cb70fcb2bd86dd2df6 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 01:14:14 -0700 Subject: [PATCH 02/21] add server --- include/WIFI_SERVER.h | 176 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 include/WIFI_SERVER.h diff --git a/include/WIFI_SERVER.h b/include/WIFI_SERVER.h new file mode 100644 index 0000000..0460306 --- /dev/null +++ b/include/WIFI_SERVER.h @@ -0,0 +1,176 @@ +#include +#include +#include +#include + +// Create AsyncWebServer object on port 80 +AsyncWebServer server(80); + +// Search for parameter in HTTP POST request +const char *PARAM_INPUT_1 = "ssid"; +const char *PARAM_INPUT_2 = "pass"; +const char *PARAM_INPUT_3 = "ip"; +const char *PARAM_INPUT_4 = "gateway"; +const char *PARAM_INPUT_5 = "fstart"; +const char *PARAM_INPUT_6 = "fend"; + +// File paths to save input values permanently +const char *ssidPath = "/ssid.txt"; +const char *passPath = "/pass.txt"; +const char *ipPath = "/ip.txt"; +const char *gatewayPath = "/gateway.txt"; + +// Variables to save values from HTML form +String ssid = "LoraSA", pass = "1234567890", ip, gateway, fstart, fend; + +IPAddress localIP(192, 168, 1, 200); +// Set your Gateway IP address +IPAddress localGateway(192, 168, 1, 1); +IPAddress subnet(255, 255, 0, 0); + +// Timer variables +unsigned long previousMillis = 0; +const long interval = 10000; // interval to wait for Wi-Fi connection (milliseconds) + +// Initialize WiFi +bool initWiFi() +{ + if (ssid == "" || ip == "") + { + Serial.println("Undefined SSID or IP address."); + return false; + } + + WiFi.mode(WIFI_STA); + // localIP.fromString(ip.c_str()); + // localGateway.fromString(gateway.c_str()); + + if (!WiFi.config(localIP, localGateway, subnet)) + { + Serial.println("STA Failed to configure"); + return false; + } + WiFi.begin(ssid.c_str(), pass.c_str()); + Serial.println("Connecting to WiFi..."); + + unsigned long currentMillis = millis(); + previousMillis = currentMillis; + + while (WiFi.status() != WL_CONNECTED) + { + currentMillis = millis(); + if (currentMillis - previousMillis >= interval) + { + Serial.println("Failed to connect."); + return false; + } + } + + Serial.println(WiFi.localIP()); + return true; +} + +void serverStart() +{ + if (initWiFi()) + { + // Route for root / web page + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) + { request->send(LittleFS, "/index.html", "text/html"); }); + server.serveStatic("/", LittleFS, "/"); + + /* // Route to set GPIO state to HIGH + server.on("/on", HTTP_GET, + [](AsyncWebServerRequest *request) + { + digitalWrite(ledPin, HIGH); + request->send(LittleFS, "/index.html", "text/html", false, + processor); + }); + + // Route to set GPIO state to LOW + server.on("/off", HTTP_GET, + [](AsyncWebServerRequest *request) + { + digitalWrite(ledPin, LOW); + request->send(LittleFS, "/index.html", "text/html", false, + processor); + });*/ + server.begin(); + } + else + { + // Connect to Wi-Fi network with SSID and password + Serial.println("Setting AP (Access Point)"); + // NULL sets an open Access Point + WiFi.softAP("LoraSA", NULL); + + IPAddress IP = WiFi.softAPIP(); + Serial.print("AP IP address: "); + Serial.println(IP); + + // Web Server Root URL + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) + { request->send(LittleFS, "/index.html", "text/html"); }); + + server.serveStatic("/", LittleFS, "/"); + + server.on("/", HTTP_POST, + [](AsyncWebServerRequest *request) + { + int params = request->params(); + for (int i = 0; i < params; i++) + { + const AsyncWebParameter *p = request->getParam(i); + if (p->isPost()) + { + // HTTP POST ssid value + if (p->name() == PARAM_INPUT_1) + { + ssid = p->value().c_str(); + Serial.print("SSID set to: "); + Serial.println(ssid); + // Write file to save value + writeFile(LittleFS, ssidPath, ssid.c_str()); + } + // HTTP POST pass value + if (p->name() == PARAM_INPUT_2) + { + pass = p->value().c_str(); + Serial.print("Password set to: "); + Serial.println(pass); + // Write file to save value + writeFile(LittleFS, passPath, pass.c_str()); + } + // HTTP POST ip value + if (p->name() == PARAM_INPUT_3) + { + ip = p->value().c_str(); + Serial.print("IP Address set to: "); + Serial.println(ip); + // Write file to save value + writeFile(LittleFS, ipPath, ip.c_str()); + } + // HTTP POST gateway value + if (p->name() == PARAM_INPUT_4) + { + gateway = p->value().c_str(); + Serial.print("Gateway set to: "); + Serial.println(gateway); + // Write file to save value + writeFile(LittleFS, gatewayPath, gateway.c_str()); + } + // Serial.printf("POST[%s]: %s\n", p->name().c_str(), + // p->value().c_str()); + } + } + request->send(200, "text/plain", + "Done. ESP will restart, connect to your router and " + "go to IP address: " + + ip); + delay(3000); + ESP.restart(); + }); + server.begin(); + } +} From b002afb789cb522430a2fffbd9f05749ba545238 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 18:31:26 -0700 Subject: [PATCH 03/21] Add LR1121 and File config WIFI --- include/File.h | 12 +++ include/LiLyGo.h | 4 + include/WIFI_SERVER.h | 208 +++++++++++++++++++++--------------------- lib/scan/scan.h | 4 +- platformio.ini | 30 ++++++ src/main.cpp | 77 ++++++++++++---- 6 files changed, 213 insertions(+), 122 deletions(-) diff --git a/include/File.h b/include/File.h index d726c40..6f502ec 100644 --- a/include/File.h +++ b/include/File.h @@ -1,6 +1,16 @@ #include "FS.h" #include +// Initialize LittleFS +void initLittleFS() +{ + if (!LittleFS.begin(true)) + { + Serial.println("An error has occurred while mounting LittleFS"); + } + Serial.println("LittleFS mounted successfully"); +} + String readFile(fs::FS &fs, const char *path) { Serial.printf("Reading file: %s\r\n", path); @@ -24,6 +34,7 @@ String readFile(fs::FS &fs, const char *path) void writeFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Writing file: %s\r\n", path); + Serial.printf("Content: %s\r\n", message); File file = fs.open(path, FILE_WRITE); if (!file) @@ -34,6 +45,7 @@ void writeFile(fs::FS &fs, const char *path, const char *message) if (file.print(message)) { Serial.println("- file written"); + delay(500); } else { diff --git a/include/LiLyGo.h b/include/LiLyGo.h index c9c88ee..1d44603 100644 --- a/include/LiLyGo.h +++ b/include/LiLyGo.h @@ -35,6 +35,10 @@ SX1280 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUS // Default SPI on pins from pins_arduino.h SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); #endif // end USING_SX1262 +#ifdef USING_LR1121 +// Default SPI on pins from pins_arduino.h +LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO9_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); +#endif // end USING_LR1121 #ifdef USING_SX1276 // Default SPI on pins from pins_arduino.h SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); diff --git a/include/WIFI_SERVER.h b/include/WIFI_SERVER.h index 0460306..89d95de 100644 --- a/include/WIFI_SERVER.h +++ b/include/WIFI_SERVER.h @@ -7,25 +7,23 @@ AsyncWebServer server(80); // Search for parameter in HTTP POST request -const char *PARAM_INPUT_1 = "ssid"; -const char *PARAM_INPUT_2 = "pass"; -const char *PARAM_INPUT_3 = "ip"; -const char *PARAM_INPUT_4 = "gateway"; -const char *PARAM_INPUT_5 = "fstart"; -const char *PARAM_INPUT_6 = "fend"; +const String SSID = "ssid"; +const String PASS = "pass"; +const String IP = "ip"; +const String GATEWAY = "gateway"; +const String FSTART = "fstart"; +const String FEND = "fend"; // File paths to save input values permanently -const char *ssidPath = "/ssid.txt"; -const char *passPath = "/pass.txt"; -const char *ipPath = "/ip.txt"; -const char *gatewayPath = "/gateway.txt"; +// const char *ssidPath = "/ssid.txt"; // Variables to save values from HTML form -String ssid = "LoraSA", pass = "1234567890", ip, gateway, fstart, fend; +String ssid = "LoraSA", pass = "1234567890", ip = "192.168.1.100", + gateway = "192.168.1.1", fstart = "", fend = ""; -IPAddress localIP(192, 168, 1, 200); +IPAddress localIP; // Set your Gateway IP address -IPAddress localGateway(192, 168, 1, 1); +IPAddress localGateway; IPAddress subnet(255, 255, 0, 0); // Timer variables @@ -35,6 +33,11 @@ const long interval = 10000; // interval to wait for Wi-Fi connection (milliseco // Initialize WiFi bool initWiFi() { + Serial.println("SSID:" + ssid); + Serial.println("PSWD:" + pass); + Serial.println("IP:" + ip); + Serial.println("SUB:" + subnet); + Serial.println("GATAWAY:" + gateway); if (ssid == "" || ip == "") { Serial.println("Undefined SSID or IP address."); @@ -42,8 +45,8 @@ bool initWiFi() } WiFi.mode(WIFI_STA); - // localIP.fromString(ip.c_str()); - // localGateway.fromString(gateway.c_str()); + localIP.fromString(ip.c_str()); + localGateway.fromString(gateway.c_str()); if (!WiFi.config(localIP, localGateway, subnet)) { @@ -70,37 +73,100 @@ bool initWiFi() return true; } +void writeParameterToFile(String value, String file) +{ + // Write file to save value + writeFile(LittleFS, file.c_str(), value.c_str()); +} + +void writeParameterToParameterFile(String param, String value) +{ + String file = String("/" + param + ".txt"); + // Write file to save value + writeParameterToFile(value, file.c_str()); +} + +String readParameterFromParameterFile(String param) +{ + String file = String("/" + param + ".txt"); + return readFile(LittleFS, file.c_str()); +} + +void serverServer() +{ + // Route for root / web page + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) + { request->send(LittleFS, "/index.html", "text/html"); }); + + server.serveStatic("/", LittleFS, "/"); + + server.on("/", HTTP_POST, + [](AsyncWebServerRequest *request) + { + int params = request->params(); + for (int i = 0; i < params; i++) + { + Serial.println("Parameter " + String(i) + ": " + + request->getParam(i)->value()); + } + Serial.println(request->params()); + + String p = request->getParam(SSID, true)->value(); + writeParameterToParameterFile(SSID, p); + + p = request->getParam(PASS, true)->value(); + writeParameterToParameterFile(PASS, p); + + p = request->getParam(IP, true)->value(); + writeParameterToParameterFile(IP, p); + + p = request->getParam(GATEWAY, true)->value(); + writeParameterToParameterFile(GATEWAY, p); + + p = request->getParam(FSTART, true)->value(); + writeParameterToParameterFile(FSTART, p); + + p = request->getParam(FEND, true)->value(); + writeParameterToParameterFile(FEND, p); + + request->send(200, "text/plain", + "Done. ESP will restart, connect to your router and " + "go to IP address: " + + ip); + delay(3000); + ESP.restart(); + }); + + /* // Route to set GPIO state to HIGH + server.on("/on", HTTP_GET, + [](AsyncWebServerRequest *request) + { + digitalWrite(ledPin, HIGH); + request->send(LittleFS, "/index.html", "text/html", false, + processor); + }); + + // Route to set GPIO state to LOW + server.on("/off", HTTP_GET, + [](AsyncWebServerRequest *request) + { + digitalWrite(ledPin, LOW); + request->send(LittleFS, "/index.html", "text/html", false, + processor); + });*/ + server.begin(); +} + void serverStart() { if (initWiFi()) { - // Route for root / web page - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) - { request->send(LittleFS, "/index.html", "text/html"); }); - server.serveStatic("/", LittleFS, "/"); - - /* // Route to set GPIO state to HIGH - server.on("/on", HTTP_GET, - [](AsyncWebServerRequest *request) - { - digitalWrite(ledPin, HIGH); - request->send(LittleFS, "/index.html", "text/html", false, - processor); - }); - - // Route to set GPIO state to LOW - server.on("/off", HTTP_GET, - [](AsyncWebServerRequest *request) - { - digitalWrite(ledPin, LOW); - request->send(LittleFS, "/index.html", "text/html", false, - processor); - });*/ - server.begin(); + Serial.println("Setting Secure WIFI (Access Point)"); + serverServer(); } else { - // Connect to Wi-Fi network with SSID and password + // Connect to Wi-Fi network with default SSID and password Serial.println("Setting AP (Access Point)"); // NULL sets an open Access Point WiFi.softAP("LoraSA", NULL); @@ -109,68 +175,6 @@ void serverStart() Serial.print("AP IP address: "); Serial.println(IP); - // Web Server Root URL - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) - { request->send(LittleFS, "/index.html", "text/html"); }); - - server.serveStatic("/", LittleFS, "/"); - - server.on("/", HTTP_POST, - [](AsyncWebServerRequest *request) - { - int params = request->params(); - for (int i = 0; i < params; i++) - { - const AsyncWebParameter *p = request->getParam(i); - if (p->isPost()) - { - // HTTP POST ssid value - if (p->name() == PARAM_INPUT_1) - { - ssid = p->value().c_str(); - Serial.print("SSID set to: "); - Serial.println(ssid); - // Write file to save value - writeFile(LittleFS, ssidPath, ssid.c_str()); - } - // HTTP POST pass value - if (p->name() == PARAM_INPUT_2) - { - pass = p->value().c_str(); - Serial.print("Password set to: "); - Serial.println(pass); - // Write file to save value - writeFile(LittleFS, passPath, pass.c_str()); - } - // HTTP POST ip value - if (p->name() == PARAM_INPUT_3) - { - ip = p->value().c_str(); - Serial.print("IP Address set to: "); - Serial.println(ip); - // Write file to save value - writeFile(LittleFS, ipPath, ip.c_str()); - } - // HTTP POST gateway value - if (p->name() == PARAM_INPUT_4) - { - gateway = p->value().c_str(); - Serial.print("Gateway set to: "); - Serial.println(gateway); - // Write file to save value - writeFile(LittleFS, gatewayPath, gateway.c_str()); - } - // Serial.printf("POST[%s]: %s\n", p->name().c_str(), - // p->value().c_str()); - } - } - request->send(200, "text/plain", - "Done. ESP will restart, connect to your router and " - "go to IP address: " + - ip); - delay(3000); - ESP.restart(); - }); - server.begin(); + serverServer(); } } diff --git a/lib/scan/scan.h b/lib/scan/scan.h index c6b113c..38b610e 100644 --- a/lib/scan/scan.h +++ b/lib/scan/scan.h @@ -27,7 +27,9 @@ 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 // +#ifndef SAMPLES_RSSI +#define SAMPLES_RSSI 13 // 21 // +#endif #ifdef USING_SX1280PA #define SAMPLES_RSSI 20 #endif diff --git a/platformio.ini b/platformio.ini index 2868df9..a1d92eb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -76,6 +76,36 @@ build_flags = -DARDUINO_LILYGO_T3_S3_V1_X -DARDUINO_USB_MODE=1 +[env:lilygo-T3S3-v1-2-lr1121] +platform = espressif32 +board = t3_s3_v1_x +framework = arduino +upload_speed = 921600 +monitor_speed = 115200 +board_build.f_cpu = 240000000 +board_build.filesystem = littlefs +lib_deps = + ropg/Heltec_ESP32_LoRa_v3@^0.9.1 + RadioLib + U8g2 + XPowersLib + bblanchon/ArduinoJson@^7.2.0 + ESP Async WebServer +build_flags = + -DLILYGO + -DT3_S3_V1_2_LR1121 + -DT3_V1_3_SX1262 + -DARDUINO_LILYGO_T3S3_LR1121 + -DESP32 + -DSAMPLES_RSSI=5 + -DUSING_LR1121 + -DFREQ_BEGIN=2400 + -DFREQ_END=2500 + -DARDUINO_ARCH_ESP32 + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_LILYGO_T3_S3_V1_X + -DARDUINO_USB_MODE=1 + [env:lilygo-T3S3-v1-2-sx1280] platform = espressif32 diff --git a/src/main.cpp b/src/main.cpp index 20fa879..1d60514 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,8 @@ #include #include +#include + #ifndef LILYGO #include // This file contains a binary patch for the SX1262 @@ -143,8 +145,9 @@ int SCAN_RANGES[] = {}; // MHZ per page // to put everything into one page set RANGE_PER_PAGE = FREQ_END - 800 -uint64_t RANGE_PER_PAGE = FREQ_END - FREQ_BEGIN; // FREQ_END - FREQ_BEGIN +uint64_t RANGE_PER_PAGE; // FREQ_END - FREQ_BEGIN +uint64_t CONF_FREQ_END, CONF_FREQ_BEGIN; // To Enable Multi Screen scan // uint64_t RANGE_PER_PAGE = 50; // Default Range on Menu Button Switch @@ -177,16 +180,8 @@ constexpr int WINDOW_SIZE = 15; // if more than 100 it can freeze #define SAMPLES 35 //(scan time = 1294) -#define RANGE (int)(FREQ_END - FREQ_BEGIN) - -#define SINGLE_STEP (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)) - -uint64_t range = (int)(FREQ_END - FREQ_BEGIN); - -uint64_t iterations = RANGE / RANGE_PER_PAGE; - -// uint64_t range_frequency = FREQ_END - FREQ_BEGIN; -uint64_t median_frequency = (FREQ_BEGIN + FREQ_END) / 2; +uint64_t RANGE, range, iterations, median_frequency; +float SINGLE_STEP; // #define DISABLE_PLOT_CHART false // unused @@ -376,13 +371,20 @@ struct RadioScan : Scan float RadioScan::getRSSI() { -#ifdef USING_SX1280PA +#if defined(USING_SX1280PA) // radio.startReceive(); // get instantaneous RSSI value // When PR will be merged we can use radi.getRSSI(false); uint8_t data[3] = {0, 0, 0}; // RssiInst, Status, RFU radio.mod->SPIreadStream(RADIOLIB_SX128X_CMD_GET_RSSI_INST, data, 3); return ((float)data[0] / (-2.0)); + +#elif defined(USING_LR1121) + // Try getRssiInst + float rssi; + radio.getRssiInst(&rssi); + // pass the replies + return rssi; #else return radio.getRSSI(false); #endif @@ -401,7 +403,7 @@ void init_radio() { // initialize SX1262 FSK modem at the initial frequency both.println("Init radio"); -#ifdef USING_SX1280PA +#if defined(USING_SX1280PA) || defined(USING_LR1121) state = radio.beginGFSK(FREQ_BEGIN); #else state = radio.beginFSK(FREQ_BEGIN); @@ -590,7 +592,7 @@ void setup(void) pinMode(BUZZER_PIN, OUTPUT); pinMode(REB_PIN, OUTPUT); heltec_setup(); - serverStart(); + #ifdef JOYSTICK_ENABLED calibrate_joy(); pinMode(JOY_BTN_PIN, INPUT_PULLUP); @@ -612,16 +614,53 @@ void setup(void) init_radio(); - if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) - { - Serial.println("LittleFS Mount Failed"); - } + initLittleFS(); // writeFile(LittleFS, "/text.txt", "{WIFI:{name:\"sdfsdf\", Password:\"sdfsdf\"}"); - Serial.println(readFile(LittleFS, "/text.txt")); + ssid = readParameterFromParameterFile(SSID); + Serial.println("SSID: " + ssid); + + pass = readParameterFromParameterFile(PASS); + Serial.println("PASS: " + pass); + + ip = readParameterFromParameterFile(IP); + Serial.println("PASS: " + ip); + + gateway = readParameterFromParameterFile(GATEWAY); + Serial.println("GATEWAY: " + gateway); + + fstart = readParameterFromParameterFile(FSTART); + Serial.println("FSTART: " + fstart); + + fend = readParameterFromParameterFile(FEND); + Serial.println("FEND: " + fend); + + both.println("Starting WIFI-SERVER"); + serverStart(); + + CONF_FREQ_BEGIN = (fstart == "") ? FREQ_BEGIN : atoi(fstart.c_str()); + CONF_FREQ_END = (fend == "") ? FREQ_END : atoi(fend.c_str()); + + both.println("C FREQ BEGIN:" + String(CONF_FREQ_BEGIN)); + both.println("C FREQ END:" + String(CONF_FREQ_END)); + + RANGE_PER_PAGE = CONF_FREQ_END - CONF_FREQ_BEGIN; // FREQ_END - FREQ_BEGIN + + RANGE = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); + + SINGLE_STEP = (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)); + + range = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); + + iterations = RANGE / RANGE_PER_PAGE; + + // uint64_t range_frequency = FREQ_END - FREQ_BEGIN; + median_frequency = (CONF_FREQ_BEGIN + CONF_FREQ_END) / 2; + #ifndef LILYGO vbat = heltec_vbat(); both.printf("V battery: %.2fV (%d%%)\n", vbat, heltec_battery_percent(vbat)); + delay(1000); #endif // end not LILYGO #ifdef WIFI_SCANNING_ENABLED WiFi.mode(WIFI_STA); From 7c3d48a44dc136d6b4a695af5bea5ad7c2b0241f Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 20:00:42 -0700 Subject: [PATCH 04/21] samples settings --- data/index.html | 6 +++-- include/WIFI_SERVER.h | 51 +++++++++++++++++++++++++++---------- src/main.cpp | 59 ++++++++++++++++++++++++------------------- src/ui.cpp | 11 +++++--- 4 files changed, 82 insertions(+), 45 deletions(-) diff --git a/data/index.html b/data/index.html index 92cddf1..82bfe6a 100644 --- a/data/index.html +++ b/data/index.html @@ -26,9 +26,11 @@
-
+
-
+
+ +

diff --git a/include/WIFI_SERVER.h b/include/WIFI_SERVER.h index 89d95de..93a715d 100644 --- a/include/WIFI_SERVER.h +++ b/include/WIFI_SERVER.h @@ -19,7 +19,7 @@ const String FEND = "fend"; // Variables to save values from HTML form String ssid = "LoraSA", pass = "1234567890", ip = "192.168.1.100", - gateway = "192.168.1.1", fstart = "", fend = ""; + gateway = "192.168.1.1", fstart = "", fend = "", smpls = ""; IPAddress localIP; // Set your Gateway IP address @@ -111,23 +111,48 @@ void serverServer() } Serial.println(request->params()); - String p = request->getParam(SSID, true)->value(); - writeParameterToParameterFile(SSID, p); + String p; + if (request->hasParam(IP, true)) + { + p = request->getParam(IP, true)->value(); + writeParameterToParameterFile(IP, p); + } - p = request->getParam(PASS, true)->value(); - writeParameterToParameterFile(PASS, p); + if (request->hasParam(IP, true)) + { + p = request->getParam(IP, true)->value(); + writeParameterToParameterFile(IP, p); + } - p = request->getParam(IP, true)->value(); - writeParameterToParameterFile(IP, p); + if (request->hasParam(IP, true)) + { + p = request->getParam(IP, true)->value(); + writeParameterToParameterFile(IP, p); + } - p = request->getParam(GATEWAY, true)->value(); - writeParameterToParameterFile(GATEWAY, p); + if (request->hasParam(GATEWAY, true)) + { + p = request->getParam(GATEWAY, true)->value(); + writeParameterToParameterFile(GATEWAY, p); + } - p = request->getParam(FSTART, true)->value(); - writeParameterToParameterFile(FSTART, p); + if (request->hasParam(FSTART, true)) + { + p = request->getParam(FSTART, true)->value(); + writeParameterToParameterFile(FSTART, p); + } - p = request->getParam(FEND, true)->value(); - writeParameterToParameterFile(FEND, p); + if (request->hasParam(FEND, true)) + { + p = request->getParam(FEND, true)->value(); + writeParameterToParameterFile(FEND, p); + } + + if (request->hasParam("samples", true)) + { + p = request->getParam("samples", true)->value(); + writeParameterToParameterFile("samples", p); + } request->send(200, "text/plain", "Done. ESP will restart, connect to your router and " diff --git a/src/main.cpp b/src/main.cpp index 9f3dbec..883889e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -145,10 +145,9 @@ int SCAN_RANGES[] = {}; // MHZ per page // to put everything into one page set RANGE_PER_PAGE = FREQ_END - 800 -uint64_t RANGE_PER_PAGE; // FREQ_END - FREQ_BEGIN +uint64_t RANGE_PER_PAGE; // FREQ_END - CONF_FREQ_BEGIN -uint64_t CONF_FREQ_END, CONF_FREQ_BEGIN; -// To Enable Multi Screen scan +uint64_t CONF_FREQ_END, CONF_FREQ_BEGIN; // To Enable Multi Screen scan // uint64_t RANGE_PER_PAGE = 50; // Default Range on Menu Button Switch @@ -228,11 +227,12 @@ uint64_t ranges_count = 0; int rssi = 0; int state = 0; +int CONF_SAMPLES; #ifdef METHOD_SPECTRAL -constexpr int samples = SAMPLES; +int samples = SAMPLES; #endif #ifdef METHOD_RSSI -constexpr int samples = SAMPLES_RSSI; +int samples = SAMPLES_RSSI; #endif uint8_t result_index = 0; @@ -305,8 +305,8 @@ void osdProcess() // memset(max_step_range, 33, 30); max_bin = 32; - osd.displayString(12, 1, String(FREQ_BEGIN)); - osd.displayString(12, OSD_WIDTH - 8, String(FREQ_END)); + osd.displayString(12, 1, String(CONF_FREQ_BEGIN)); + osd.displayString(12, OSD_WIDTH - 8, String(CONF_FREQ_END)); // Finding biggest in result // Skiping 0 and 32 31 to avoid overflow for (int i = 1; i < MAX_POWER_LEVELS - 3; i++) @@ -343,7 +343,7 @@ void osdProcess() #ifdef OSD_SIDE_BAR { osd.displayString(col, OSD_WIDTH - 7, - String(FREQ_BEGIN + (col * osd_mhz_in_bin)) + "-" + + String(CONF_FREQ_BEGIN + (col * osd_mhz_in_bin)) + "-" + String(max_step_range) + " "); } #endif @@ -404,9 +404,9 @@ void init_radio() // initialize SX1262 FSK modem at the initial frequency both.println("Init radio"); #if defined(USING_SX1280PA) || defined(USING_LR1121) - state = radio.beginGFSK(FREQ_BEGIN); + state = radio.beginGFSK(CONF_FREQ_BEGIN); #else - state = radio.beginFSK(FREQ_BEGIN); + state = radio.beginFSK(CONF_FREQ_BEGIN); #endif if (state == RADIOLIB_ERR_NONE) { @@ -458,7 +458,7 @@ void init_radio() // calibrate only once ,,, at startup // TODO: check documentation (9.2.1) if we must calibrate in certain ranges #ifdef USING_SX1280PA - state = radio.setFrequency(FREQ_BEGIN); + state = radio.setFrequency(CONF_FREQ_BEGIN); if (state != RADIOLIB_ERR_NONE) { Serial.println("Error:setFrequency:" + String(state)); @@ -470,9 +470,9 @@ void init_radio() } #elif USING_SX1276 // Sets carrier frequency. Allowed values range from 137.0 MHz to 1020.0 MHz. - radio.setFrequency(FREQ_BEGIN); + radio.setFrequency(CONF_FREQ_BEGIN); #else - radio.setFrequency(FREQ_BEGIN, true); + radio.setFrequency(CONF_FREQ_BEGIN, true); #endif delay(50); @@ -612,8 +612,6 @@ void setup(void) } } - init_radio(); - initLittleFS(); // writeFile(LittleFS, "/text.txt", "{WIFI:{name:\"sdfsdf\", Password:\"sdfsdf\"}"); @@ -635,16 +633,22 @@ void setup(void) fend = readParameterFromParameterFile(FEND); Serial.println("FEND: " + fend); + smpls = readParameterFromParameterFile("samples"); + Serial.println("SAMPLES: " + smpls); + both.println("Starting WIFI-SERVER"); serverStart(); + CONF_SAMPLES = (smpls == "") ? samples : atoi(smpls.c_str()); + samples = CONF_SAMPLES; CONF_FREQ_BEGIN = (fstart == "") ? FREQ_BEGIN : atoi(fstart.c_str()); CONF_FREQ_END = (fend == "") ? FREQ_END : atoi(fend.c_str()); both.println("C FREQ BEGIN:" + String(CONF_FREQ_BEGIN)); both.println("C FREQ END:" + String(CONF_FREQ_END)); + both.println("C SAMPLES:" + String(CONF_SAMPLES)); - RANGE_PER_PAGE = CONF_FREQ_END - CONF_FREQ_BEGIN; // FREQ_END - FREQ_BEGIN + RANGE_PER_PAGE = CONF_FREQ_END - CONF_FREQ_BEGIN; // FREQ_END - CONF_FREQ_BEGIN RANGE = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); @@ -654,9 +658,11 @@ void setup(void) iterations = RANGE / RANGE_PER_PAGE; - // uint64_t range_frequency = FREQ_END - FREQ_BEGIN; + // uint64_t range_frequency = FREQ_END - CONF_FREQ_BEGIN; median_frequency = (CONF_FREQ_BEGIN + CONF_FREQ_END) / 2; + init_radio(); + #ifndef LILYGO vbat = heltec_vbat(); both.printf("V battery: %.2fV (%d%%)\n", vbat, heltec_battery_percent(vbat)); @@ -763,8 +769,9 @@ void setup(void) r.trigger_level = TRIGGER_LEVEL; stacked.reset(0, 0, display.width(), display.height()); - bar = new DecoratedBarChart(display, 0, 0, display.width(), 0, FREQ_BEGIN, FREQ_END, - LO_RSSI_THRESHOLD, HI_RSSI_THRESHOLD, r.trigger_level); + bar = new DecoratedBarChart(display, 0, 0, display.width(), 0, CONF_FREQ_BEGIN, + CONF_FREQ_END, LO_RSSI_THRESHOLD, HI_RSSI_THRESHOLD, + r.trigger_level); size_t b = stacked.addChart(bar); @@ -778,9 +785,9 @@ void setup(void) delete[] multiples; - waterChart = - new WaterfallChart(display, 0, WATERFALL_START, display.width(), 0, FREQ_BEGIN, - FREQ_END, r.trigger_level, WATERFALL_SENSITIVITY, model); + waterChart = new WaterfallChart(display, 0, WATERFALL_START, display.width(), 0, + CONF_FREQ_BEGIN, CONF_FREQ_END, r.trigger_level, + WATERFALL_SENSITIVITY, model); size_t c = stacked.addChart(waterChart); stacked.setHeight(c, stacked.height - WATERFALL_START - statusBar->height); @@ -1011,13 +1018,13 @@ void loop(void) } // do the scan - range = FREQ_END - FREQ_BEGIN; + range = CONF_FREQ_END - CONF_FREQ_BEGIN; if (RANGE_PER_PAGE > range) { RANGE_PER_PAGE = range; } - r.fr_begin = FREQ_BEGIN; + r.fr_begin = CONF_FREQ_BEGIN; r.fr_end = r.fr_begin; // 50 is a single-screen range @@ -1150,7 +1157,7 @@ void loop(void) // Spectrum analyzer using getRSSI { LOG("METHOD RSSI"); - uint16_t max_rssi = r.rssiMethod(SAMPLES_RSSI, result, + uint16_t max_rssi = r.rssiMethod(CONF_SAMPLES, result, RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE); if (max_x_rssi[display_x] > max_rssi) @@ -1162,7 +1169,7 @@ void loop(void) // if this code is not executed LORA radio doesn't work // basically SX1262 requires delay - // osd.displayString(12, 1, String(FREQ_BEGIN)); + // osd.displayString(12, 1, String(CONF_FREQ_BEGIN)); // osd.displayString(12, 30 - 8, String(FREQ_END)); // delay(2); diff --git a/src/ui.cpp b/src/ui.cpp index e488060..77bdc58 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -16,6 +16,8 @@ // temporary dirty import ... to be solved durring upcoming refactoring extern unsigned int RANGE_PER_PAGE; +extern uint64_t CONF_FREQ_BEGIN; +extern uint64_t CONF_FREQ_END; extern unsigned int median_frequency; extern unsigned int drone_detected_frequency_start; extern unsigned int drone_detected_frequency_end; @@ -95,7 +97,8 @@ void StatusBar::draw() // Frequency start display.setTextAlignment(TEXT_ALIGN_LEFT); display.drawString(pos_x, text_y, - (r.fr_begin == 0) ? String(FREQ_BEGIN) : String(r.fr_begin)); + (r.fr_begin == 0) ? String(CONF_FREQ_BEGIN) + : String(r.fr_begin)); // Frequency detected display.setTextAlignment(TEXT_ALIGN_CENTER); @@ -106,7 +109,7 @@ void StatusBar::draw() // Frequency end display.setTextAlignment(TEXT_ALIGN_RIGHT); display.drawString(pos_x + width, text_y, - (r.fr_end == 0) ? String(FREQ_END) : String(r.fr_end)); + (r.fr_end == 0) ? String(CONF_FREQ_END) : String(r.fr_end)); } // Status text block @@ -170,11 +173,11 @@ void StatusBar::draw() display.drawString(pos_x, text_y, String(loop_time)); #else display.setTextAlignment(TEXT_ALIGN_LEFT); - display.drawString(pos_x, text_y, String(FREQ_BEGIN)); + display.drawString(pos_x, text_y, String(CONF_FREQ_BEGIN)); #endif display.setTextAlignment(TEXT_ALIGN_RIGHT); - display.drawString(pos_x + width, text_y, String(FREQ_END)); + display.drawString(pos_x + width, text_y, String(CONF_FREQ_END)); } else if (ranges_count > 0) { From a62c91d938c75042a0ea35b9166e4cab9cf27eb1 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 21:30:03 -0700 Subject: [PATCH 05/21] WiFi load --- src/main.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 883889e..3815cfc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -49,11 +49,11 @@ // public and so will be exposed to the user. This allows direct manipulation of the // library internals. #define RADIOLIB_GODMODE (1) +#define RADIOLIB_CHECK_PARAMS (0) #include #include #include - #include #ifndef LILYGO @@ -612,6 +612,34 @@ void setup(void) } } + display.clear(); + + both.println("CLICK for WIFI settings."); + + for (int i = 0; i < 200; i++) + { + + both.print("."); + + button.update(); + delay(10); + if (button.pressedNow()) + { + both.println("-----------"); + both.println("Starting WIFI-SERVER..."); + tone(BUZZER_PIN, 205, 100); + delay(50); + tone(BUZZER_PIN, 205, 500); + tone(BUZZER_PIN, 205, 100); + delay(50); + + serverStart(); + break; + } + } + both.print("\n"); + + both.println("Init File System"); initLittleFS(); // writeFile(LittleFS, "/text.txt", "{WIFI:{name:\"sdfsdf\", Password:\"sdfsdf\"}"); @@ -636,9 +664,6 @@ void setup(void) smpls = readParameterFromParameterFile("samples"); Serial.println("SAMPLES: " + smpls); - both.println("Starting WIFI-SERVER"); - serverStart(); - CONF_SAMPLES = (smpls == "") ? samples : atoi(smpls.c_str()); samples = CONF_SAMPLES; CONF_FREQ_BEGIN = (fstart == "") ? FREQ_BEGIN : atoi(fstart.c_str()); From 527ce829394b4ee46d9958d212ed0386ee47d6a9 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 21:53:18 -0700 Subject: [PATCH 06/21] Fix WiFi settings --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 3815cfc..2d0d074 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -618,7 +618,6 @@ void setup(void) for (int i = 0; i < 200; i++) { - both.print("."); button.update(); @@ -627,6 +626,7 @@ void setup(void) { both.println("-----------"); both.println("Starting WIFI-SERVER..."); + // Error here: E (15752) ledc: ledc_get_duty(745): LEDC is not initialized tone(BUZZER_PIN, 205, 100); delay(50); tone(BUZZER_PIN, 205, 500); @@ -634,6 +634,8 @@ void setup(void) delay(50); serverStart(); + both.println("Ready to Connect: 192.168.4.1"); + delay(600); break; } } From 41bd4c3b96850ba05c2fef83f0de2cb1b94e969b Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Oct 2024 22:03:46 -0700 Subject: [PATCH 07/21] move to function readConfigFile --- src/main.cpp | 91 +++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2d0d074..88721c5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -557,6 +557,53 @@ void logToSerialTask(void *parameter) void drone_sound_alarm(void *arg, Event &e); +void readConfigFile() +{ + // writeFile(LittleFS, "/text.txt", "{WIFI:{name:\"sdfsdf\", Password:\"sdfsdf\"}"); + ssid = readParameterFromParameterFile(SSID); + Serial.println("SSID: " + ssid); + + pass = readParameterFromParameterFile(PASS); + Serial.println("PASS: " + pass); + + ip = readParameterFromParameterFile(IP); + Serial.println("PASS: " + ip); + + gateway = readParameterFromParameterFile(GATEWAY); + Serial.println("GATEWAY: " + gateway); + + fstart = readParameterFromParameterFile(FSTART); + Serial.println("FSTART: " + fstart); + + fend = readParameterFromParameterFile(FEND); + Serial.println("FEND: " + fend); + + smpls = readParameterFromParameterFile("samples"); + Serial.println("SAMPLES: " + smpls); + + CONF_SAMPLES = (smpls == "") ? samples : atoi(smpls.c_str()); + samples = CONF_SAMPLES; + CONF_FREQ_BEGIN = (fstart == "") ? FREQ_BEGIN : atoi(fstart.c_str()); + CONF_FREQ_END = (fend == "") ? FREQ_END : atoi(fend.c_str()); + + both.println("C FREQ BEGIN:" + String(CONF_FREQ_BEGIN)); + both.println("C FREQ END:" + String(CONF_FREQ_END)); + both.println("C SAMPLES:" + String(CONF_SAMPLES)); + + RANGE_PER_PAGE = CONF_FREQ_END - CONF_FREQ_BEGIN; // FREQ_END - CONF_FREQ_BEGIN + + RANGE = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); + + SINGLE_STEP = (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)); + + range = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); + + iterations = RANGE / RANGE_PER_PAGE; + + // uint64_t range_frequency = FREQ_END - CONF_FREQ_BEGIN; + median_frequency = (CONF_FREQ_BEGIN + CONF_FREQ_END) / 2; +} + void setup(void) { @@ -644,49 +691,7 @@ void setup(void) both.println("Init File System"); initLittleFS(); - // writeFile(LittleFS, "/text.txt", "{WIFI:{name:\"sdfsdf\", Password:\"sdfsdf\"}"); - ssid = readParameterFromParameterFile(SSID); - Serial.println("SSID: " + ssid); - - pass = readParameterFromParameterFile(PASS); - Serial.println("PASS: " + pass); - - ip = readParameterFromParameterFile(IP); - Serial.println("PASS: " + ip); - - gateway = readParameterFromParameterFile(GATEWAY); - Serial.println("GATEWAY: " + gateway); - - fstart = readParameterFromParameterFile(FSTART); - Serial.println("FSTART: " + fstart); - - fend = readParameterFromParameterFile(FEND); - Serial.println("FEND: " + fend); - - smpls = readParameterFromParameterFile("samples"); - Serial.println("SAMPLES: " + smpls); - - CONF_SAMPLES = (smpls == "") ? samples : atoi(smpls.c_str()); - samples = CONF_SAMPLES; - CONF_FREQ_BEGIN = (fstart == "") ? FREQ_BEGIN : atoi(fstart.c_str()); - CONF_FREQ_END = (fend == "") ? FREQ_END : atoi(fend.c_str()); - - both.println("C FREQ BEGIN:" + String(CONF_FREQ_BEGIN)); - both.println("C FREQ END:" + String(CONF_FREQ_END)); - both.println("C SAMPLES:" + String(CONF_SAMPLES)); - - RANGE_PER_PAGE = CONF_FREQ_END - CONF_FREQ_BEGIN; // FREQ_END - CONF_FREQ_BEGIN - - RANGE = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); - - SINGLE_STEP = (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)); - - range = (int)(CONF_FREQ_END - CONF_FREQ_BEGIN); - - iterations = RANGE / RANGE_PER_PAGE; - - // uint64_t range_frequency = FREQ_END - CONF_FREQ_BEGIN; - median_frequency = (CONF_FREQ_BEGIN + CONF_FREQ_END) / 2; + readConfigFile(); init_radio(); From 1c65cd745a0137dbff7458a78aa0447ce63a787b Mon Sep 17 00:00:00 2001 From: KonradIT Date: Mon, 14 Oct 2024 23:38:43 +0200 Subject: [PATCH 08/21] Modify SpectrumScan.py to use json data in serial (LOG_DATA_JSON must be set to true) --- .gitignore | 2 ++ SpectrumScan.py | 88 +++++++++++++++++++------------------------------ 2 files changed, 35 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 89cc49c..3711360 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch + +out/ diff --git a/SpectrumScan.py b/SpectrumScan.py index acc37a0..ee74707 100644 --- a/SpectrumScan.py +++ b/SpectrumScan.py @@ -11,6 +11,8 @@ import matplotlib.pyplot as plt from datetime import datetime from argparse import RawTextHelpFormatter +import json + # number of samples in each scanline SCAN_WIDTH = 33 @@ -50,17 +52,15 @@ def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, if iteration == total: print() +def parse_line(line): + json_line = json.loads(line) + return json_line def main(): parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description=''' - RadioLib SX126x_Spectrum_Scan plotter script. Displays output from SX126x_Spectrum_Scan example - as grayscale and + Parse serial data from LOG_DATA_JSON functionality. - Depends on pyserial and matplotlib, install by: - 'python3 -m pip install pyserial matplotlib' - - Step-by-step guide on how to use the script: - 1. Upload the SX126x_Spectrum_Scan example to your Arduino board with SX1262 connected. + 1. #define LOG_DATA_JSON true - add this line in main.cpp, upload to device 2. Run the script with appropriate arguments. 3. Once the scan is complete, output files will be saved to out/ ''') @@ -89,88 +89,66 @@ def main(): help=f'Default starting frequency in MHz') args = parser.parse_args() - freq_mode = False - scan_len = args.len - if (args.freq != -1): - freq_mode = True - scan_len = 1000 - - # create the color map and the result array - arr = np.zeros((SCAN_WIDTH, scan_len)) + # create the result array + arr = np.zeros((scan_len, SCAN_WIDTH)) # scanline counter row = 0 - # list of frequencies in frequency mode + # list of frequencies freq_list = [] # open the COM port with serial.Serial(args.port, args.speed, timeout=None) as com: while(True): # update the progress bar - if not freq_mode: - printProgressBar(row, scan_len) + printProgressBar(row, scan_len) # read a single line try: line = com.readline().decode('utf-8') except: continue + print(line) + if "{" in line: + try: + data = parse_line(line) + except: + continue - if SCAN_MARK_FREQ in line: - new_freq = float(line.split(' ')[1]) - if (len(freq_list) > 1) and (new_freq < freq_list[-1]): - break + freq = data["low_range_freq"] + rssi = int(data["value"]) - freq_list.append(new_freq) - print('{:.3f}'.format(new_freq), end = '\r') - continue - - # check the markers - if (SCAN_MARK_START in line) and (SCAN_MARK_END in line): - # get the values - scanline = line[len(SCAN_MARK_START):-len(SCAN_MARK_END)].split(',') - for col in range(SCAN_WIDTH): - arr[col][row] = int(scanline[col]) + if freq not in freq_list: + freq_list.append(freq) + + col = freq_list.index(freq) + arr[row][col] = rssi # increment the row counter row = row + 1 # check if we're done - if (not freq_mode) and (row >= scan_len): + if (row >= scan_len): break - - # scale to the number of scans (sum of any given scanline) - num_samples = arr.sum(axis=0)[0] - arr *= (num_samples/arr.max()) - - if freq_mode: - scan_len = len(freq_list) # create the figure - fig, ax = plt.subplots() + fig, ax = plt.subplots(figsize=(12, 8)) # display the result as heatmap - extent = [0, scan_len, -4*(SCAN_WIDTH + 1), args.offset] - if freq_mode: - extent[0] = freq_list[0] - extent[1] = freq_list[-1] - im = ax.imshow(arr[:,:scan_len], cmap=args.map, extent=extent) - fig.colorbar(im) + extent = [0, scan_len, freq_list[0], freq_list[-1]] + im = ax.imshow(arr.T, cmap=args.map, extent=extent, aspect='auto', origin='lower') + fig.colorbar(im, label='RSSI (dBm)') - # set some properites and show + # set some properties and show timestamp = datetime.now().strftime('%y-%m-%d %H-%M-%S') title = f'RadioLib SX126x Spectral Scan {timestamp}' - if freq_mode: - plt.xlabel("Frequency [Hz]") - else: - plt.xlabel("Time [sample]") - plt.ylabel("RSSI [dBm]") - ax.set_aspect('auto') + plt.xlabel("Time (sample)") + plt.ylabel("Frequency (MHz)") fig.suptitle(title) fig.canvas.manager.set_window_title(title) plt.savefig(f'{OUT_PATH}/{title.replace(" ", "_")}.png', dpi=300) plt.show() if __name__ == "__main__": - main() \ No newline at end of file + main() From e6c92e4eb09936aeec8fcdbdfcecd3fec0c7bd35 Mon Sep 17 00:00:00 2001 From: KonradIT Date: Mon, 14 Oct 2024 23:45:35 +0200 Subject: [PATCH 09/21] Cleaned up, linted, etc... --- SpectrumScan.py | 117 ++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 68 deletions(-) diff --git a/SpectrumScan.py b/SpectrumScan.py index ee74707..ee713a3 100644 --- a/SpectrumScan.py +++ b/SpectrumScan.py @@ -7,32 +7,21 @@ import sys import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt - +import json from datetime import datetime from argparse import RawTextHelpFormatter -import json +# Constants +SCAN_WIDTH = 33 # number of samples in each scanline +OUT_PATH = "out" # output path for saved files -# number of samples in each scanline -SCAN_WIDTH = 33 - -# scanline Serial start/end markers -SCAN_MARK_START = 'SCAN ' -SCAN_MARK_FREQ = 'FREQ ' -SCAN_MARK_END = ' END' - -# output path -OUT_PATH = 'out' - -# default settings +# Default settings DEFAULT_BAUDRATE = 115200 DEFAULT_COLOR_MAP = 'viridis' DEFAULT_SCAN_LEN = 200 DEFAULT_RSSI_OFFSET = -11 -# Print iterations progress -# from https://stackoverflow.com/questions/3173320/text-progress-bar-in-terminal-with-block-characters -def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 50, fill = '█', printEnd = "\r"): +def print_progress_bar(iteration, total, prefix='', suffix='', decimals=1, length=50, fill='█', print_end="\r"): """ Call in a loop to create terminal progress bar @params: @@ -43,80 +32,72 @@ def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, decimals - Optional : positive number of decimals in percent complete (Int) length - Optional : character length of bar (Int) fill - Optional : bar fill character (Str) - printEnd - Optional : end character (e.g. "\r", "\r\n") (Str) + print_end - Optional : end character (e.g. "\r", "\r\n") (Str) """ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) - filledLength = int(length * iteration // total) - bar = fill * filledLength + '-' * (length - filledLength) - print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd) + filled_length = int(length * iteration // total) + bar = fill * filled_length + '-' * (length - filled_length) + print(f'\r{prefix} |{bar}| {percent}% {suffix}', end=print_end) if iteration == total: print() def parse_line(line): - json_line = json.loads(line) - return json_line + """Parse a JSON line from the serial input.""" + return json.loads(line) def main(): - parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description=''' + parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''\ Parse serial data from LOG_DATA_JSON functionality. 1. #define LOG_DATA_JSON true - add this line in main.cpp, upload to device 2. Run the script with appropriate arguments. 3. Once the scan is complete, output files will be saved to out/ ''') - parser.add_argument('port', - type=str, - help='COM port to connect to the device') - parser.add_argument('--speed', - default=DEFAULT_BAUDRATE, - type=int, - help=f'COM port baudrate (defaults to {DEFAULT_BAUDRATE})') - parser.add_argument('--map', - default=DEFAULT_COLOR_MAP, - type=str, - help=f'Matplotlib color map to use for the output (defaults to "{DEFAULT_COLOR_MAP}")') - parser.add_argument('--len', - default=DEFAULT_SCAN_LEN, - type=int, - help=f'Number of scanlines to record (defaults to {DEFAULT_SCAN_LEN})') - parser.add_argument('--offset', - default=DEFAULT_RSSI_OFFSET, - type=int, - help=f'Default RSSI offset in dBm (defaults to {DEFAULT_RSSI_OFFSET})') - parser.add_argument('--freq', - default=-1, - type=float, - help=f'Default starting frequency in MHz') + parser.add_argument('port', type=str, help='COM port to connect to the device') + parser.add_argument('--speed', default=DEFAULT_BAUDRATE, type=int, + help=f'COM port baudrate (defaults to {DEFAULT_BAUDRATE})') + parser.add_argument('--map', default=DEFAULT_COLOR_MAP, type=str, + help=f'Matplotlib color map to use for the output (defaults to "{DEFAULT_COLOR_MAP}")') + parser.add_argument('--len', default=DEFAULT_SCAN_LEN, type=int, + help=f'Number of scanlines to record (defaults to {DEFAULT_SCAN_LEN})') + parser.add_argument('--offset', default=DEFAULT_RSSI_OFFSET, type=int, + help=f'Default RSSI offset in dBm (defaults to {DEFAULT_RSSI_OFFSET})') + parser.add_argument('--freq', default=-1, type=float, + help='Default starting frequency in MHz') args = parser.parse_args() - # create the result array + # Create the result array + scan_len = args.len arr = np.zeros((scan_len, SCAN_WIDTH)) - # scanline counter + # Scanline counter row = 0 - # list of frequencies + # List of frequencies freq_list = [] - # open the COM port + # Open the COM port with serial.Serial(args.port, args.speed, timeout=None) as com: - while(True): - # update the progress bar - printProgressBar(row, scan_len) + while True: + # Update the progress bar + print_progress_bar(row, scan_len) - # read a single line + # Read a single line try: - line = com.readline().decode('utf-8') - except: + line = com.readline().decode('utf-8').strip() + except UnicodeDecodeError: continue - print(line) - if "{" in line: + + if line.startswith("{"): try: data = parse_line(line) - except: + except json.JSONDecodeError: continue + # get the lowest frequency for now, could be averaged too. freq = data["low_range_freq"] + + # value in negative, eg: -70 rssi = int(data["value"]) if freq not in freq_list: @@ -125,24 +106,24 @@ def main(): col = freq_list.index(freq) arr[row][col] = rssi - # increment the row counter - row = row + 1 + # Increment the row counter + row += 1 - # check if we're done - if (row >= scan_len): + # Check if we're done + if row >= scan_len: break - # create the figure + # Create the figure fig, ax = plt.subplots(figsize=(12, 8)) - # display the result as heatmap + # Display the result as heatmap extent = [0, scan_len, freq_list[0], freq_list[-1]] im = ax.imshow(arr.T, cmap=args.map, extent=extent, aspect='auto', origin='lower') fig.colorbar(im, label='RSSI (dBm)') - # set some properties and show + # Set plot properties and show timestamp = datetime.now().strftime('%y-%m-%d %H-%M-%S') - title = f'RadioLib SX126x Spectral Scan {timestamp}' + title = f'LoraSA Spectral Scan {timestamp}' plt.xlabel("Time (sample)") plt.ylabel("Frequency (MHz)") fig.suptitle(title) From 1ace56054d74f125b965dae591b28e357a4fb4d4 Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 18 Oct 2024 01:08:08 -0700 Subject: [PATCH 10/21] add webserver lib --- platformio.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platformio.ini b/platformio.ini index a1d92eb..08f0ebe 100644 --- a/platformio.ini +++ b/platformio.ini @@ -45,6 +45,8 @@ monitor_speed = 115200 board_build.f_cpu = 240000000 lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 + bblanchon/ArduinoJson@^7.2.0 + ESP Async WebServer build_flags = -DHELTEC_POWER_BUTTON -DHELTEC @@ -64,6 +66,7 @@ lib_deps = RadioLib U8g2 XPowersLib + ESP Async WebServer build_flags = -DLILYGO -DT3_S3_V1_2_SX1262 @@ -119,6 +122,7 @@ lib_deps = RadioLib U8g2 XPowersLib + ESP Async WebServer build_flags = -DLILYGO -DT3_S3_V1_2_SX1280_PA @@ -143,6 +147,7 @@ lib_deps = RadioLib U8g2 XPowersLib + ESP Async WebServer build_flags = -DLILYGO -DT3_V1_6_SX1276 From 55d26f0aff66c120a025a1cf9dcd065b344b22e2 Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 18 Oct 2024 01:15:20 -0700 Subject: [PATCH 11/21] forgot to add little file system --- platformio.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platformio.ini b/platformio.ini index 08f0ebe..e85aa6e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -43,6 +43,7 @@ framework = arduino upload_speed = 921600 monitor_speed = 115200 board_build.f_cpu = 240000000 +board_build.filesystem = littlefs lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 bblanchon/ArduinoJson@^7.2.0 @@ -61,6 +62,7 @@ framework = arduino upload_speed = 921600 monitor_speed = 115200 board_build.f_cpu = 240000000 +board_build.filesystem = littlefs lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 RadioLib @@ -117,6 +119,7 @@ framework = arduino upload_speed = 921600 monitor_speed = 115200 board_build.f_cpu = 240000000 +board_build.filesystem = littlefs lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 RadioLib @@ -142,6 +145,7 @@ board = esp32dev framework = arduino upload_speed = 115200 monitor_speed = 115200 +board_build.filesystem = littlefs lib_deps = ropg/Heltec_ESP32_LoRa_v3@^0.9.1 RadioLib From 62ac49e84b91b18383a3dc20d6b2dc266aaf30ba Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 13 Nov 2024 21:34:45 -0800 Subject: [PATCH 12/21] t-190 fix --- tft_src/main.cpp | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index 9eae332..610861e 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -13,9 +13,9 @@ // #define ARDUINO_USB_CDC_ON_BOOT 1 // #define LoRaWAN_DEBUG_LEVEL 0 #include "HT_ST7789spi.h" -#include "global_config.h" +// #include "global_config.h" #include "images.h" -#include "ui.h" +// #include "ui.h" #include #include @@ -71,6 +71,8 @@ constexpr bool DRAW_DETECTION_TICKS = true; #define SAMPLES_RSSI 5 // 21 // #define FREQ_BEGIN 650 +#define FREQ_END 960 +#define BANDWIDTH 467.0 #define DEFAULT_DRONE_DETECTION_LEVEL 90 #define RANGE (int)(FREQ_END - FREQ_BEGIN) @@ -315,6 +317,7 @@ constexpr unsigned int STATUS_BAR_HEIGHT = 5; void loop() { + Serial.println("Loop"); if (screen_update_loop_counter == 0) { fr_x[x1] = 0; @@ -331,7 +334,7 @@ void loop() fr_x[x1] = fr; int u = 0; - int additional_samples = 10; + int additional_samples = 0; // Clear old data with the cursor ... st7789->drawFastVLine(x1, lower_level, -lower_level + 11, ST7789_BLACK); @@ -351,8 +354,15 @@ void loop() additional_samples--; } - radio.setFrequency((float)fr + (float)(rssi_mhz_step * u), - false); // false = no calibration need here + bool calibrate = true; + float freq = (float)fr + (float)(rssi_mhz_step * u); + if ((int)freq % 10 == 0) + { + calibrate = true; + } + radio.setFrequency(freq, + /*false*/ calibrate); // false = no calibration need here + // Serial.println((float)fr + (float)(rssi_mhz_step * u)); u++; if (rssi_mhz_step * u >= mhz_step) { @@ -363,6 +373,7 @@ void loop() rssi_single_start = millis(); } rssi2 = radio.getRSSI(false); + // Serial.print(" RSSI : " + String(rssi2)); scan_iterations++; if (rssi_single_end == 0) { @@ -383,13 +394,17 @@ void loop() #ifdef PRINT_DEBUG Serial.println(String(fr) + ":" + String(rssi2)); #endif + int lineHeight = 0; + st7789->drawPixel(x1, rssiToPix(rssi2), rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 1, rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 2, rssiToColor(abs(rssi2))); + st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - rssiToPix(rssi2), + rssiToColor(abs(rssi2))); // Draw Update Cursor st7789->drawFastVLine(x1 + 1, lower_level, -lower_level + 11, ST7789_BLACK); st7789->drawFastVLine(x1 + 2, lower_level, -lower_level + 11, ST7789_BLACK); - st7789->drawFastVLine(x1 + 3, lower_level, -lower_level + 11, ST7789_BLACK); + // st7789->drawFastVLine(x1 + 3, lower_level, -lower_level + 11, ST7789_BLACK); if (max_scan_rssi[x1] == -999) { @@ -452,7 +467,10 @@ void loop() // Waterfall cursor st7789->drawFastHLine(0, w + 1, DISPLAY_WIDTH, ST7789_BLACK); - st7789->drawFastHLine(0, w + 2, DISPLAY_WIDTH, ST7789_BLACK); + if (w < WATERFALL_END) + { + st7789->drawFastHLine(0, w + 2, DISPLAY_WIDTH, ST7789_ORANGE); + } // drone detection level line if (x1 % 2 == 0) From 2914f249cdbd459c4f79fb20d18381a2a5ec08c9 Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 13 Nov 2024 21:37:02 -0800 Subject: [PATCH 13/21] add comment --- tft_src/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index 610861e..e094d85 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -399,8 +399,12 @@ void loop() st7789->drawPixel(x1, rssiToPix(rssi2), rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 1, rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 2, rssiToColor(abs(rssi2))); - st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - rssiToPix(rssi2), - rssiToColor(abs(rssi2))); + + if (true /*draw full line*/) + { + st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - rssiToPix(rssi2), + rssiToColor(abs(rssi2))); + } // Draw Update Cursor st7789->drawFastVLine(x1 + 1, lower_level, -lower_level + 11, ST7789_BLACK); st7789->drawFastVLine(x1 + 2, lower_level, -lower_level + 11, ST7789_BLACK); From cbd4175e28ca1bb9fb7bc56d4cfbf92faedc5c9c Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 13 Nov 2024 21:44:58 -0800 Subject: [PATCH 14/21] add low level --- tft_src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index e094d85..f3583f2 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -133,6 +133,8 @@ uint64_t scan_time = 0; uint64_t scan_start_time = 0; #endif +// To remove waterfall adjust this and this +#define LOWER_LEVEL 108 #define WATERFALL_START 115 #define WATERFALL_END DISPLAY_HEIGHT - 10 - 2 @@ -249,7 +251,7 @@ void battery() } } -constexpr int lower_level = 108; +constexpr int lower_level = LOWER_LEVEL; constexpr int up_level = 40; int rssiToPix(int rssi) { From 33042ae71e9bd06a40c42db34db485585dd0b4d8 Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 13 Nov 2024 21:54:14 -0800 Subject: [PATCH 15/21] add waterfall disable --- tft_src/main.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index f3583f2..3a92526 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -137,6 +137,7 @@ uint64_t scan_start_time = 0; #define LOWER_LEVEL 108 #define WATERFALL_START 115 #define WATERFALL_END DISPLAY_HEIGHT - 10 - 2 +#define DISABLE_WATERFALL 0 // to disable set to 1 uint64_t x, y, range_item, w = WATERFALL_START, i = 0; int osd_x = 1, osd_y = 2, col = 0, max_bin = 32; @@ -440,8 +441,11 @@ void loop() // Writing pixel only if it is bigger than drone detection level if (abs(max_scan_rssi[x1]) < drone_detection_level) { - // Waterfall Pixel - st7789->drawPixel(x1, w, rssiToColor(abs(max_scan_rssi[x1]), true)); + if (DISABLE_WATERFALL == 0) + { + // Waterfall Pixel + st7789->drawPixel(x1, w, rssiToColor(abs(max_scan_rssi[x1]), true)); + } detailed_scan_candidate[(int)fr] = (int)fr; } @@ -471,11 +475,14 @@ void loop() window_max_rssi = -999; } - // Waterfall cursor - st7789->drawFastHLine(0, w + 1, DISPLAY_WIDTH, ST7789_BLACK); - if (w < WATERFALL_END) + if (DISABLE_WATERFALL == 0) { - st7789->drawFastHLine(0, w + 2, DISPLAY_WIDTH, ST7789_ORANGE); + // Waterfall cursor + st7789->drawFastHLine(0, w + 1, DISPLAY_WIDTH, ST7789_BLACK); + if (w < WATERFALL_END) + { + st7789->drawFastHLine(0, w + 2, DISPLAY_WIDTH, ST7789_ORANGE); + } } // drone detection level line From 5f273c2f73ef6318d8176d2b97c2f9c435560d5a Mon Sep 17 00:00:00 2001 From: Egor Date: Thu, 14 Nov 2024 12:52:14 -0800 Subject: [PATCH 16/21] scaling display --- tft_src/main.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index 3a92526..4010648 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -70,18 +70,19 @@ constexpr bool DRAW_DETECTION_TICKS = true; // number of samples for RSSI method #define SAMPLES_RSSI 5 // 21 // -#define FREQ_BEGIN 650 -#define FREQ_END 960 +#define FREQ_BEGIN 150 +#define FREQ_END 950 #define BANDWIDTH 467.0 +#define MHZ_PX (float)((float)(FREQ_END - FREQ_BEGIN) / DISPLAY_WIDTH) #define DEFAULT_DRONE_DETECTION_LEVEL 90 #define RANGE (int)(FREQ_END - FREQ_BEGIN) -#define SINGLE_STEP (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)) +// #define SINGLE_STEP (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)) uint64_t range = (int)(FREQ_END - FREQ_BEGIN); uint64_t fr_begin = FREQ_BEGIN; -uint64_t fr_end = FREQ_BEGIN; +uint64_t fr_end = FREQ_END; // Feature to scan diapasones. Other frequency settings will be ignored. // int SCAN_RANGES[] = {850890, 920950}; @@ -92,7 +93,7 @@ int SCAN_RANGES[] = {}; // uint64_t RANGE_PER_PAGE = FREQ_END - FREQ_BEGIN; // FREQ_END - FREQ_BEGIN // Override or e-ink -uint64_t RANGE_PER_PAGE = FREQ_BEGIN + DISPLAY_WIDTH; +uint64_t RANGE_PER_PAGE = FREQ_END - FREQ_BEGIN; // FREQ_BEGIN + DISPLAY_WIDTH; uint64_t iterations = RANGE / RANGE_PER_PAGE; @@ -291,7 +292,7 @@ long timeSinceLastModeSwitch = 0; float fr = FREQ_BEGIN, fr_x[STEPS + 5], vbat = 0; // MHz in one screen pix step // END will be Begin + 289 * mhz_step -constexpr int mhz_step = 1; +float mhz_step = MHZ_PX; // TODO: make end_freq // Measure RSS every step constexpr float rssi_mhz_step = 0.33; From 38c0a8540d83d130ff8bb48b32a5bc72c708484a Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 15 Nov 2024 14:05:13 -0800 Subject: [PATCH 17/21] remove waterfall move chart down --- tft_src/main.cpp | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index 4010648..ce0ebdc 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -135,10 +135,11 @@ uint64_t scan_start_time = 0; #endif // To remove waterfall adjust this and this -#define LOWER_LEVEL 108 +#define LOWER_LEVEL DISPLAY_HEIGHT - 22 // 108 +#define SPECTR_CHART_STAR_TOP 40 + 30; #define WATERFALL_START 115 #define WATERFALL_END DISPLAY_HEIGHT - 10 - 2 -#define DISABLE_WATERFALL 0 // to disable set to 1 +#define DISABLE_WATERFALL 1 // to disable set to 1 uint64_t x, y, range_item, w = WATERFALL_START, i = 0; int osd_x = 1, osd_y = 2, col = 0, max_bin = 32; @@ -254,7 +255,7 @@ void battery() } constexpr int lower_level = LOWER_LEVEL; -constexpr int up_level = 40; +constexpr int up_level = SPECTR_CHART_STAR_TOP; int rssiToPix(int rssi) { // Bigger is lower signal @@ -262,11 +263,24 @@ int rssiToPix(int rssi) { return lower_level - 1; } - if (abs(rssi) <= up_level) + if (abs(rssi) <= up_level && lower_level < 130) { return up_level; } - return abs(rssi); + // if chart moved to the bottom + if (lower_level > 130) + { + int returnRssi = rssi - up_level / 3; + if (returnRssi >= lower_level) + { + return lower_level - 1; + } + return abs(returnRssi); + } + else + { + return abs(rssi); + } } // @@ -403,11 +417,22 @@ void loop() st7789->drawPixel(x1, rssiToPix(rssi2), rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 1, rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 2, rssiToColor(abs(rssi2))); + if (LOWER_LEVEL > 140) + { + st7789->drawPixel(x1, rssiToPix(rssi2) - 3, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 5, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 6, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 7, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 8, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 9, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 10, rssiToColor(abs(rssi2))); + } if (true /*draw full line*/) { - st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - rssiToPix(rssi2), - rssiToColor(abs(rssi2))); + // st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - + // rssiToPix(rssi2), + // rssiToColor(abs(rssi2))); } // Draw Update Cursor st7789->drawFastVLine(x1 + 1, lower_level, -lower_level + 11, ST7789_BLACK); From 0d9164db75a15db1461bd1942ef385fa84af04a2 Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 15 Nov 2024 14:09:27 -0800 Subject: [PATCH 18/21] add line --- tft_src/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index ce0ebdc..62251a5 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -430,9 +430,8 @@ void loop() if (true /*draw full line*/) { - // st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - - // rssiToPix(rssi2), - // rssiToColor(abs(rssi2))); + st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - rssiToPix(rssi2), + rssiToColor(abs(rssi2))); } // Draw Update Cursor st7789->drawFastVLine(x1 + 1, lower_level, -lower_level + 11, ST7789_BLACK); From 85349f2a8c8e417069cebd64a0105a4444f5bb21 Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 15 Nov 2024 16:38:21 -0800 Subject: [PATCH 19/21] some fixes --- tft_src/main.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tft_src/main.cpp b/tft_src/main.cpp index 62251a5..4d48dbb 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -136,7 +136,7 @@ uint64_t scan_start_time = 0; // To remove waterfall adjust this and this #define LOWER_LEVEL DISPLAY_HEIGHT - 22 // 108 -#define SPECTR_CHART_STAR_TOP 40 + 30; +#define SPECTR_CHART_STAR_TOP 40 + 50; #define WATERFALL_START 115 #define WATERFALL_END DISPLAY_HEIGHT - 10 - 2 #define DISABLE_WATERFALL 1 // to disable set to 1 @@ -270,8 +270,9 @@ int rssiToPix(int rssi) // if chart moved to the bottom if (lower_level > 130) { - int returnRssi = rssi - up_level / 3; - if (returnRssi >= lower_level) + int returnRssi = lower_level + abs(rssi) - up_level - 21; + Serial.println("RSSI: " + String(rssi)); + if (returnRssi >= lower_level - 2) { return lower_level - 1; } @@ -417,16 +418,8 @@ void loop() st7789->drawPixel(x1, rssiToPix(rssi2), rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 1, rssiToColor(abs(rssi2))); st7789->drawPixel(x1, rssiToPix(rssi2) - 2, rssiToColor(abs(rssi2))); - if (LOWER_LEVEL > 140) - { - st7789->drawPixel(x1, rssiToPix(rssi2) - 3, rssiToColor(abs(rssi2))); - st7789->drawPixel(x1, rssiToPix(rssi2) - 5, rssiToColor(abs(rssi2))); - st7789->drawPixel(x1, rssiToPix(rssi2) - 6, rssiToColor(abs(rssi2))); - st7789->drawPixel(x1, rssiToPix(rssi2) - 7, rssiToColor(abs(rssi2))); - st7789->drawPixel(x1, rssiToPix(rssi2) - 8, rssiToColor(abs(rssi2))); - st7789->drawPixel(x1, rssiToPix(rssi2) - 9, rssiToColor(abs(rssi2))); - st7789->drawPixel(x1, rssiToPix(rssi2) - 10, rssiToColor(abs(rssi2))); - } + st7789->drawPixel(x1, rssiToPix(rssi2) - 3, rssiToColor(abs(rssi2))); + st7789->drawPixel(x1, rssiToPix(rssi2) - 4, rssiToColor(abs(rssi2))); if (true /*draw full line*/) { From 6028e13ef6a6bd2a9114d0189adf400223cc1477 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 24 Nov 2024 13:28:34 -0800 Subject: [PATCH 20/21] Ad legend and fix screen scaling --- eink_src/main.cpp | 2 +- tft_src/main.cpp | 114 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 97 insertions(+), 19 deletions(-) diff --git a/eink_src/main.cpp b/eink_src/main.cpp index 71a35a0..ee82ccb 100644 --- a/eink_src/main.cpp +++ b/eink_src/main.cpp @@ -364,7 +364,7 @@ void loop() for (int i = 0; i < SAMPLES_RSSI; i++) { state = radio.setFrequency((float)fr + (float)(rssi_mhz_step * u), - false); // false = no calibration need here + true); // false = no calibration need here int radio_error_count = 0; if (state != RADIOLIB_ERR_NONE) { diff --git a/tft_src/main.cpp b/tft_src/main.cpp index 4d48dbb..ac220ef 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -18,6 +18,23 @@ // #include "ui.h" #include #include +#include + +struct Entry +{ + String drone; // Drone name + int fstart; // Fr Start + int fend; // Fr End + int y; // y(vertical) position + uint16_t color; // color +}; + +// Define and initialize the vector +std::vector fpvArray = {{"FPV-ELRS", 160, 350, 100, ST7789_BLUE}, + {"915-ELRS", 700, 1000, 100, ST7789_ORANGE}, + {"FPV433-ELRS", 350, 530, 100, ST7789_YELLOW}, + {"Orlan", 820, 940, 98, ST7789_GREEN}, + {"Zala", 830, 950, 80, ST7789_MAGENTA}}; #define st7789_CS_Pin 39 #define st7789_REST_Pin 40 @@ -74,7 +91,8 @@ constexpr bool DRAW_DETECTION_TICKS = true; #define FREQ_END 950 #define BANDWIDTH 467.0 #define MHZ_PX (float)((float)(FREQ_END - FREQ_BEGIN) / DISPLAY_WIDTH) -#define DEFAULT_DRONE_DETECTION_LEVEL 90 +#define DEFAULT_DRONE_DETECTION_LEVEL -90 +#define DRONE_LEGEND 1; #define RANGE (int)(FREQ_END - FREQ_BEGIN) @@ -117,7 +135,7 @@ bool waterfall[STEPS], detected_y[STEPS]; // 20 - ??? steps of the waterfall bool first_run, new_pixel, detected_x = false; // drone detection flag bool detected = false; -uint64_t drone_detection_level = DEFAULT_DRONE_DETECTION_LEVEL; +int64_t drone_detection_level = DEFAULT_DRONE_DETECTION_LEVEL; uint64_t drone_detected_frequency_start = 0; uint64_t drone_detected_frequency_end = 0; uint64_t detection_count = 0; @@ -135,11 +153,22 @@ uint64_t scan_start_time = 0; #endif // To remove waterfall adjust this and this -#define LOWER_LEVEL DISPLAY_HEIGHT - 22 // 108 -#define SPECTR_CHART_STAR_TOP 40 + 50; -#define WATERFALL_START 115 +#define ZERO_LEVEL 110 // Equal to minimal RSSI +#define ZERO_SHIFT 42 +#define LOWER_LEVEL ZERO_LEVEL + ZERO_SHIFT // 108(zero) - (40 moving down) +#define SPECTR_CHART_STAR_TOP 42; +#define WATERFALL_START 119 #define WATERFALL_END DISPLAY_HEIGHT - 10 - 2 + +#ifndef DISABLE_WATERFALL #define DISABLE_WATERFALL 1 // to disable set to 1 +#endif + +#if DISABLE_WATERFALL == 0 +#define ZERO_LEVEL 110 +#define ZERO_SHIFT 0 +#define LOWER_LEVEL ZERO_LEVEL +#endif uint64_t x, y, range_item, w = WATERFALL_START, i = 0; int osd_x = 1, osd_y = 2, col = 0, max_bin = 32; @@ -254,6 +283,25 @@ void battery() } } +void drawDroneLegend() +{ + // Draw FPV array Names + for (const auto &entry : fpvArray) + { + int pixelStart = (entry.fstart - FREQ_BEGIN) / MHZ_PX; + int pixelEnd = (entry.fend - FREQ_BEGIN) / MHZ_PX; + int length = (pixelEnd - pixelStart); + // Serial.println("Pixel Start: " + String(pixelStart)); + // Serial.println("MHinPIX: " + String(MHZ_PX)); + int median = length / 2; + if (entry.fstart < FREQ_END) + { + st7789->drawFastHLine(pixelStart, entry.y, length, entry.color); + drawText(pixelStart, entry.y - 10, entry.drone, entry.color); + } + } +} + constexpr int lower_level = LOWER_LEVEL; constexpr int up_level = SPECTR_CHART_STAR_TOP; int rssiToPix(int rssi) @@ -270,13 +318,13 @@ int rssiToPix(int rssi) // if chart moved to the bottom if (lower_level > 130) { - int returnRssi = lower_level + abs(rssi) - up_level - 21; - Serial.println("RSSI: " + String(rssi)); - if (returnRssi >= lower_level - 2) + int returnRssi = abs(rssi - ZERO_SHIFT); + // Serial.println("RSSI: " + String(rssi)); + if (returnRssi >= lower_level) { return lower_level - 1; } - return abs(returnRssi); + return returnRssi; } else { @@ -322,6 +370,7 @@ int window_max_rssi = -999; int window_max_fr = -999; int max_scan_rssi[STEPS + 2]; int max_history_rssi[STEPS + 2]; +int historical_loops = 50, h = 0; long display_scan_start = 0; long display_scan_end = 0; long display_scan_i_end = 0; @@ -336,7 +385,7 @@ constexpr unsigned int STATUS_BAR_HEIGHT = 5; void loop() { - Serial.println("Loop"); + // Serial.println("Loop"); if (screen_update_loop_counter == 0) { fr_x[x1] = 0; @@ -357,7 +406,16 @@ void loop() // Clear old data with the cursor ... st7789->drawFastVLine(x1, lower_level, -lower_level + 11, ST7789_BLACK); + // Draw max history line + if (h == historical_loops) + { + st7789->drawLine(x1, rssiToPix(max_history_rssi[x1]), x1, lower_level, + ST7789_BLACK /*gray*/); + // clear history + max_history_rssi[x1] = -999; + } + st7789->drawLine(x1, rssiToPix(max_history_rssi[x1]), x1, lower_level, 12710 /*gray*/); // Fetch samples @@ -429,7 +487,8 @@ void loop() // Draw Update Cursor st7789->drawFastVLine(x1 + 1, lower_level, -lower_level + 11, ST7789_BLACK); st7789->drawFastVLine(x1 + 2, lower_level, -lower_level + 11, ST7789_BLACK); - // st7789->drawFastVLine(x1 + 3, lower_level, -lower_level + 11, ST7789_BLACK); + // st7789->drawFastVLine(x1 + 3, lower_level, -lower_level + 11, + // ST7789_BLACK); if (max_scan_rssi[x1] == -999) { @@ -457,7 +516,7 @@ void loop() } } // Writing pixel only if it is bigger than drone detection level - if (abs(max_scan_rssi[x1]) < drone_detection_level) + if (abs(max_scan_rssi[x1]) < abs(drone_detection_level)) { if (DISABLE_WATERFALL == 0) { @@ -474,7 +533,7 @@ void loop() // Draw legend for windows if (x1 % rssi_window_size == 0 || x1 == DISPLAY_WIDTH) { - if (abs(window_max_rssi) < drone_detection_level && window_max_rssi != 0 && + if (abs(window_max_rssi) < abs(drone_detection_level) && window_max_rssi != 0 && window_max_rssi != -999) { y2 = 15; @@ -519,9 +578,9 @@ void loop() button_pressed_counter = 0; if (button.pressed()) { - drone_detection_level++; - if (drone_detection_level > 107) - drone_detection_level = DEFAULT_DRONE_DETECTION_LEVEL - 20; + drone_detection_level--; + if (drone_detection_level < -107) + drone_detection_level = DEFAULT_DRONE_DETECTION_LEVEL + 20; while (button.pressedNow()) { delay(100); @@ -540,6 +599,14 @@ void loop() heltec_deep_sleep(); } + // Drone legend every 1/4 of the screen + if (x1 % (STEPS / 4) == 0) + { +#ifdef DRONE_LEGEND + drawDroneLegend(); +#endif + } + // Main N x-axis full loop end logic if (x1 >= STEPS) { @@ -551,17 +618,28 @@ void loop() #ifdef PRINT_DEBUG Serial.println("Screen End for Output: " + String(screen_update_loop_counter)); #endif + // Doing output only after full scan if (screen_update_loop_counter + 1 == SCANS_PER_DISPLAY) { +#ifdef DRONE_LEGEND + drawDroneLegend(); +#endif + + h++; + if (h == historical_loops - 1) + { + h = 0; + } + // Scan results to max Mhz and dB in window display_scan_end = millis(); st7789->fillRect(0, 0, DISPLAY_WIDTH, 11, ST7789_BLACK); drawText(0, 0, "T:" + String(display_scan_end - display_scan_start) + "/" + - String(rssi_single_end - rssi_single_start) + " L:-" + - String(drone_detection_level) + "dB", + String(rssi_single_end - rssi_single_start) + + " L:" + String(drone_detection_level) + "dB", ST7789_BLUE); /// battery(); From f9f423446f44ebc71011ffff85d02f6a4b98f9d3 Mon Sep 17 00:00:00 2001 From: KonradIT Date: Mon, 25 Nov 2024 22:31:52 +0100 Subject: [PATCH 21/21] Fix for lilygo T3S3 LR1121 TCXO voltage + calibration skip --- src/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 88721c5..76803a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -403,8 +403,10 @@ void init_radio() { // initialize SX1262 FSK modem at the initial frequency both.println("Init radio"); -#if defined(USING_SX1280PA) || defined(USING_LR1121) +#if defined(USING_SX1280PA) state = radio.beginGFSK(CONF_FREQ_BEGIN); +#elif defined(USING_LR1121) + state = radio.beginGFSK(CONF_FREQ_BEGIN, 4.8F, 5.0F, 156.2F, 10, 16U, 1.7F); #else state = radio.beginFSK(CONF_FREQ_BEGIN); #endif @@ -1140,7 +1142,7 @@ void loop(void) state = radio.setFrequency(freq); #else state = radio.setFrequency(r.current_frequency, - false); // false = no calibration need here + true); // true = no calibration need here #endif int radio_error_count = 0; if (state != RADIOLIB_ERR_NONE)