From db38367705098b63cd907aca255a60f503e82f60 Mon Sep 17 00:00:00 2001 From: KonradIT Date: Mon, 6 Apr 2026 19:05:34 +0200 Subject: [PATCH] mark: wip work to move stuff around --- include/joyStick.h | 63 -- include/radio_init.h | 17 + lib/bt/bt.cpp | 240 ++++++++ lib/bt/bt.h | 28 + .../bt_wifi_scan/bt_wifi_scan.cpp | 42 +- lib/bt_wifi_scan/bt_wifi_scan.h | 16 + lib/charts/StackedChart.cpp | 2 +- lib/comms/radio_comms.cpp | 10 +- lib/config/config.cpp | 6 +- include/File.h => lib/file_io/file_io.cpp | 5 +- lib/file_io/file_io.h | 7 + lib/input/input.cpp | 47 ++ lib/input/input.h | 14 + lib/radio/SX1262.cpp | 11 + lib/radio/radio.h | 2 + .../wifi_server/wifi_server.cpp | 53 +- lib/wifi_server/wifi_server.h | 22 + platformio.ini | 7 +- src/main.cpp | 570 +----------------- src/radio_init.cpp | 245 ++++++++ tft_src/main.cpp | 37 +- 21 files changed, 734 insertions(+), 710 deletions(-) delete mode 100644 include/joyStick.h create mode 100644 include/radio_init.h create mode 100644 lib/bt/bt.cpp create mode 100644 lib/bt/bt.h rename include/BT_WIFI_scan.h => lib/bt_wifi_scan/bt_wifi_scan.cpp (80%) create mode 100644 lib/bt_wifi_scan/bt_wifi_scan.h rename include/File.h => lib/file_io/file_io.cpp (92%) create mode 100644 lib/file_io/file_io.h create mode 100644 lib/input/input.cpp create mode 100644 lib/input/input.h rename include/WIFI_SERVER.h => lib/wifi_server/wifi_server.cpp (74%) create mode 100644 lib/wifi_server/wifi_server.h create mode 100644 src/radio_init.cpp diff --git a/include/joyStick.h b/include/joyStick.h deleted file mode 100644 index ae10fd8..0000000 --- a/include/joyStick.h +++ /dev/null @@ -1,63 +0,0 @@ -// Joystick integration -constexpr int JOY_X_PIN = 19; -int cursor_x_position = 0; -// Not integrated yet constexpr int JOY_Y_PIN = N/A; -constexpr int JOY_BTN_PIN = 46; -bool joy_btn_clicked = false; - -// Joystick integration -bool joy_btn_click() -{ - joy_btn_clicked = true; - // is the output from the pushbutton inside the joystick. It’s normally open. If we - // use a pull-up resistor in this pin, the SW pin will be HIGH - // when it is not pressed, and LOW when Pressed. - return digitalRead(JOY_BTN_PIN) == HIGH ? false : true; -} - -int joyXMid = 0; -int cal_X = 0, cal_Y = 0; - -void calibrate_joy() -{ - for (int i = 0; i < 100; i++) - { - cal_X += analogRead(JOY_X_PIN); - } - // calibrate center - joyXMid = cal_X / 100; -} - -int MID = 100; // 10 mid point delta arduino, use 4 for attiny -int get_joy_x(bool logical = false) -{ - int joyX = analogRead(JOY_X_PIN); - - /* - Serial.print("Calibrated_X_Voltage = "); - Serial.print(joyXMid); - Serial.print("X_Voltage = "); - Serial.print(joyX); - Serial.print("\t"); - */ - - if (logical) - { - // 4095 - if (joyX < joyXMid - MID) - { - return -1; - } - // 0-5 - else if (joyX > joyXMid + MID) - { - return 1; - } - else - { - return 0; - } - } - - return joyX; -} diff --git a/include/radio_init.h b/include/radio_init.h new file mode 100644 index 0000000..3f06d14 --- /dev/null +++ b/include/radio_init.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +extern bool radioIsScan; +extern RadioModule *radio2; + +int16_t initForScan(float freq); +bool setFrequency(float curr_freq); +void init_radio(); +float getRSSI(void *param); +float getCAD(void *param); + +#ifdef USING_LR1121 +void setLRFreq(float freq); +#endif diff --git a/lib/bt/bt.cpp b/lib/bt/bt.cpp new file mode 100644 index 0000000..8adac54 --- /dev/null +++ b/lib/bt/bt.cpp @@ -0,0 +1,240 @@ +#include "bt.h" + +std::atomic bleDeviceConnected{false}; + +#ifdef BT_MOBILE +#define SERVICE_UUID "00001234-0000-1000-8000-00805f9b34fb" +#define CHARACTERISTIC_UUID "00001234-0000-1000-8000-00805f9b34ac" + +#ifndef BT_NM +#include +#include +#include +#include + +BLEServer *pServer = NULL; +BLECharacteristic *pCharacteristic = NULL; +BLEAdvertising *pAdvertising = NULL; + +class MyServerCallbacks : public BLEServerCallbacks +{ + void onConnect(BLEServer *pServer) { bleDeviceConnected = true; }; + + void onDisconnect(BLEServer *pServer) + { + bleDeviceConnected = false; + BLEDevice::startAdvertising(); + } +}; + +#else +#include + +NimBLEServer *pServer = nullptr; +NimBLECharacteristic *pCharacteristic = nullptr; +NimBLEAdvertising *pAdvertising = nullptr; + +class BTServerCallbacks : public NimBLEServerCallbacks +{ + public: + void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override + { + bleDeviceConnected = true; + Serial.printf("Device Connected | Free Heap: %d kByte\n", + ESP.getFreeHeap() / 1000); + Serial.printf("Client address: %s\n", connInfo.getAddress().toString().c_str()); + + pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 180); + } + + void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, + int reason) override + { + bleDeviceConnected = false; + Serial.println("Device Disconnected"); + NimBLEDevice::startAdvertising(); + } + + void onMTUChange(uint16_t MTU, NimBLEConnInfo &connInfo) override + { + Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, + connInfo.getConnHandle()); + } +} BTServerCallbacks; + +class CharacteristicCallbacks : public NimBLECharacteristicCallbacks +{ + void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override + { + Serial.printf("%s : onRead(), value: %s\n", + pCharacteristic->getUUID().toString().c_str(), + pCharacteristic->getValue().c_str()); + } + + void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override + { + Serial.printf("%s : onWrite(), value: %s\n", + pCharacteristic->getUUID().toString().c_str(), + pCharacteristic->getValue().c_str()); + } + + void onStatus(NimBLECharacteristic *pCharacteristic, int code) override + { +#ifdef COMPASS_DEBUG + Serial.printf("Notification/Indication return code: %d, %s\n", code, + NimBLEUtils::returnCodeToString(code)); +#endif + } + + void onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo, + uint16_t subValue) override + { + std::string str = "Client ID: "; + str += connInfo.getConnHandle(); + str += " Address: "; + str += connInfo.getAddress().toString(); + if (subValue == 0) + { + str += " Unsubscribed to "; + } + else if (subValue == 1) + { + str += " Subscribed to notifications for "; + } + else if (subValue == 2) + { + str += " Subscribed to indications for "; + } + else if (subValue == 3) + { + str += " Subscribed to notifications and indications for "; + } + str += std::string(pCharacteristic->getUUID()); + + Serial.printf("%s\n", str.c_str()); + } +} chrCallbacks; + +class DescriptorCallbacks : public NimBLEDescriptorCallbacks +{ + void onWrite(NimBLEDescriptor *pDescriptor, NimBLEConnInfo &connInfo) override + { + std::string dscVal = pDescriptor->getValue(); + Serial.printf("Descriptor written value: %s\n", dscVal.c_str()); + } + + void onRead(NimBLEDescriptor *pDescriptor, NimBLEConnInfo &connInfo) override + { + Serial.printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str()); + } +} dscCallbacks; + +#endif // BT_NM + +void initBT() +{ +#ifdef BT_NM + NimBLEDevice::init("RSSI_Radar"); + + String macAddress = NimBLEDevice::getAddress().toString().c_str(); + Serial.println("Bluetooth MAC Address: " + macAddress); + + pServer = NimBLEDevice::createServer(); + + if (!pServer) + { + Serial.println("Failed to create BLE Server"); + } + + pServer->setCallbacks(&BTServerCallbacks); + + NimBLEService *pService = pServer->createService(SERVICE_UUID); + + pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + pCharacteristic->setCallbacks(&chrCallbacks); + + pService->start(); + + pAdvertising = NimBLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setName("ESP32_RSSI_Radar"); + pAdvertising->enableScanResponse(true); + + pAdvertising->start(); + + Serial.println("BLE server started."); +#else + BLEDevice::init("ESP32_RADAR"); + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + BLEService *pService = pServer->createService(SERVICE_UUID); + + pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE | + BLECharacteristic::PROPERTY_NOTIFY); + + pCharacteristic->setValue("Hello from ESP32"); + pService->start(); + + pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->setMinInterval(300); + pAdvertising->setMaxInterval(350); + BLEDevice::startAdvertising(); + + Serial.println("BLE server is ready!"); +#endif +} + +#endif // BT_MOBILE + +void sendBTData(float heading, float rssi) +{ + String data = + "RSSI_HEADING: '{H:" + String(heading) + ",RSSI:-" + String(rssi) + "}'"; + +#ifdef COMPASS_DEBUG + Serial.println("Sending data: " + data); +#endif +#ifdef BT_MOBILE + pCharacteristic->setValue(data.c_str()); + pCharacteristic->notify(); +#endif +} + +void sendBTData(Message &msg) +{ + if (msg.type != SCAN_HEADING_MAX && msg.type != SCAN_MAX_RESULT && + msg.type != SCAN_RESULT) + { + Serial.println("Unsupported message type: " + String(msg.type)); + return; + } + + String data = "{\"SCAN_RESULT\":{\"Hmin\":" + String(msg.payload.dump.heading_min) + + ",\"Hmax\":" + String(msg.payload.dump.heading_max) + ",\"Spectrum\":["; + + for (int i = 0; i < msg.payload.dump.sz; i++) + { + data += String(i == 0 ? "" : ",") + + "{\"F\":" + String(msg.payload.dump.freqs_khz[i]) + + ",\"R\":" + String(msg.payload.dump.rssis[i]) + + (msg.payload.dump.rssis2 == NULL + ? "" + : ",\"R2\":" + String(msg.payload.dump.rssis2[i])) + + "}"; + } + + data += "]}}"; +#ifdef COMPASS_DEBUG + Serial.println("Sending data: " + data); +#endif +#ifdef BT_MOBILE + pCharacteristic->setValue(data.c_str()); + pCharacteristic->notify(); +#endif +} diff --git a/lib/bt/bt.h b/lib/bt/bt.h new file mode 100644 index 0000000..1a8988d --- /dev/null +++ b/lib/bt/bt.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +extern std::atomic bleDeviceConnected; + +#ifdef BT_MOBILE +void initBT(); + +#ifndef BT_NM +#include +#include +extern BLEServer *pServer; +extern BLECharacteristic *pCharacteristic; +extern BLEAdvertising *pAdvertising; +#else +#include +extern NimBLEServer *pServer; +extern NimBLECharacteristic *pCharacteristic; +extern NimBLEAdvertising *pAdvertising; +#endif + +#endif // BT_MOBILE + +void sendBTData(float heading, float rssi); +void sendBTData(Message &msg); diff --git a/include/BT_WIFI_scan.h b/lib/bt_wifi_scan/bt_wifi_scan.cpp similarity index 80% rename from include/BT_WIFI_scan.h rename to lib/bt_wifi_scan/bt_wifi_scan.cpp index d0b2be5..6035a49 100644 --- a/include/BT_WIFI_scan.h +++ b/lib/bt_wifi_scan/bt_wifi_scan.cpp @@ -1,20 +1,16 @@ -#pragma once +#include "bt_wifi_scan.h" + +#ifdef OSD_ENABLED + +// These globals are defined in main.cpp +extern long cycleCnt; +extern bool present; +extern bool scanFinished; #ifdef WIFI_SCANNING_ENABLED #include "WiFi.h" -#endif -#ifdef BT_SCANNING_ENABLED -#include -#include -#include -#include -#endif -#include "DFRobot_OSD.h" -void setOSD() {} -// TODO: Make Async Scan -// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html#async-scan -void scanWiFi(DFRobot_OSD osd) +void scanWiFi(DFRobot_OSD &osd) { osd.clear(); osd.displayString(14, 2, "Scanning WiFi.."); @@ -34,7 +30,6 @@ void scanWiFi(DFRobot_OSD osd) #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(": "); @@ -50,13 +45,15 @@ void scanWiFi(DFRobot_OSD osd) } osd.displayChar(14, 1, 0x10f); } +#endif // WIFI_SCANNING_ENABLED -//********************** -// BLE devices scan. -//*********************** -// TODO: Make Async Scan -// https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleAsyncScan.cpp -void scanBT(DFRobot_OSD osd) +#ifdef BT_SCANNING_ENABLED +#include +#include +#include +#include + +void scanBT(DFRobot_OSD &osd) { osd.clear(); osd.displayString(14, 2, "Scanning BT..."); @@ -64,9 +61,7 @@ void scanBT(DFRobot_OSD osd) BLEDevice::init(""); 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); @@ -108,3 +103,6 @@ void scanBT(DFRobot_OSD osd) osd.displayChar(14, 1, 0x10f); scanFinished = true; } +#endif // BT_SCANNING_ENABLED + +#endif // OSD_ENABLED diff --git a/lib/bt_wifi_scan/bt_wifi_scan.h b/lib/bt_wifi_scan/bt_wifi_scan.h new file mode 100644 index 0000000..db94aef --- /dev/null +++ b/lib/bt_wifi_scan/bt_wifi_scan.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +#ifdef OSD_ENABLED +#include "DFRobot_OSD.h" + +#ifdef WIFI_SCANNING_ENABLED +void scanWiFi(DFRobot_OSD &osd); +#endif + +#ifdef BT_SCANNING_ENABLED +void scanBT(DFRobot_OSD &osd); +#endif + +#endif // OSD_ENABLED diff --git a/lib/charts/StackedChart.cpp b/lib/charts/StackedChart.cpp index 2c6ca73..f054ab4 100644 --- a/lib/charts/StackedChart.cpp +++ b/lib/charts/StackedChart.cpp @@ -10,7 +10,7 @@ size_t StackedChart::addChart(Chart *c) Chart **cc = new Chart *[charts_sz + 1]; memcpy(cc, charts, charts_sz * sizeof(Chart *)); cc[charts_sz] = c; - free(charts); + delete[] charts; c->reset(pos_x + c->pos_x, pos_y + c->pos_y, trim_w(c->pos_x, c->width, width), c->height); diff --git a/lib/comms/radio_comms.cpp b/lib/comms/radio_comms.cpp index 026588d..e431492 100644 --- a/lib/comms/radio_comms.cpp +++ b/lib/comms/radio_comms.cpp @@ -1,4 +1,5 @@ #include "comms.h" +#include int packetRssi = 0; @@ -414,8 +415,8 @@ Message *_deserialize_config_task(size_t len, size_t &p, uint8_t *packet) return message; } -volatile bool _received = false; -void _rcv() { _received = true; } +static std::atomic _received{false}; +void _rcv() { _received.store(true, std::memory_order_release); } Message *RadioComms::receive(uint16_t timeout_ms) { @@ -426,7 +427,7 @@ Message *RadioComms::receive(uint16_t timeout_ms) #warning Radio Comms not fully supported for LR1121 or SX1276 #else // because of this, receive is single-threaded, single-device - _received = false; + _received.store(false, std::memory_order_relaxed); radio.setDio1Action(_rcv); uint32_t timeout_ticks = (uint32_t)timeout_ms * (1000000 / 15625); @@ -438,8 +439,7 @@ Message *RadioComms::receive(uint16_t timeout_ms) return NULL; } - // wait on a semaphore - while (!_received) + while (!_received.load(std::memory_order_acquire)) { yield(); } diff --git a/lib/config/config.cpp b/lib/config/config.cpp index 3f3d8d9..f3f7e7b 100644 --- a/lib/config/config.cpp +++ b/lib/config/config.cpp @@ -136,7 +136,7 @@ bool Config::updateConfig(String key, String value) if (key.equalsIgnoreCase("listen_on_usb")) { - listen_on_serial0 = value; + listen_on_usb = value; return true; } @@ -828,7 +828,7 @@ BusConfig BusConfig::configure(String cfg) continue; } - if (c.bus_type == SERIAL && k.equals("tx") || + if (c.bus_type == UART && k.equals("tx") || c.bus_type == SPI && k.equals("mosi") || c.bus_type == WIRE && k.equals("sda")) { @@ -836,7 +836,7 @@ BusConfig BusConfig::configure(String cfg) continue; } - if (c.bus_type == SERIAL && k.equals("rx") || + if (c.bus_type == UART && k.equals("rx") || c.bus_type == SPI && k.equals("miso")) { c.rx = param.toInt(); diff --git a/include/File.h b/lib/file_io/file_io.cpp similarity index 92% rename from include/File.h rename to lib/file_io/file_io.cpp index 6f502ec..e7e5c88 100644 --- a/include/File.h +++ b/lib/file_io/file_io.cpp @@ -1,7 +1,6 @@ -#include "FS.h" +#include "file_io.h" #include -// Initialize LittleFS void initLittleFS() { if (!LittleFS.begin(true)) @@ -25,7 +24,7 @@ String readFile(fs::FS &fs, const char *path) Serial.println("- read from file:"); while (file.available()) { - content = file.readStringUntil('\n'); + content += file.readStringUntil('\n') + "\n"; } file.close(); return content; diff --git a/lib/file_io/file_io.h b/lib/file_io/file_io.h new file mode 100644 index 0000000..40105d5 --- /dev/null +++ b/lib/file_io/file_io.h @@ -0,0 +1,7 @@ +#pragma once + +#include "FS.h" + +void initLittleFS(); +String readFile(fs::FS &fs, const char *path); +void writeFile(fs::FS &fs, const char *path, const char *message); diff --git a/lib/input/input.cpp b/lib/input/input.cpp new file mode 100644 index 0000000..5e16d42 --- /dev/null +++ b/lib/input/input.cpp @@ -0,0 +1,47 @@ +#include "input.h" + +int cursor_x_position = 0; +bool joy_btn_clicked = false; + +static int joyXMid = 0; + +bool joy_btn_click() +{ + joy_btn_clicked = true; + return digitalRead(JOY_BTN_PIN) == HIGH ? false : true; +} + +void calibrate_joy() +{ + int cal_X = 0; + for (int i = 0; i < 100; i++) + { + cal_X += analogRead(JOY_X_PIN); + } + joyXMid = cal_X / 100; +} + +static const int MID = 100; + +int get_joy_x(bool logical) +{ + int joyX = analogRead(JOY_X_PIN); + + if (logical) + { + if (joyX < joyXMid - MID) + { + return -1; + } + else if (joyX > joyXMid + MID) + { + return 1; + } + else + { + return 0; + } + } + + return joyX; +} diff --git a/lib/input/input.h b/lib/input/input.h new file mode 100644 index 0000000..9873658 --- /dev/null +++ b/lib/input/input.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +// Joystick pin configuration +constexpr int JOY_X_PIN = 19; +constexpr int JOY_BTN_PIN = 46; + +extern int cursor_x_position; +extern bool joy_btn_clicked; + +bool joy_btn_click(); +void calibrate_joy(); +int get_joy_x(bool logical = false); diff --git a/lib/radio/SX1262.cpp b/lib/radio/SX1262.cpp index 9d21598..087cd4f 100644 --- a/lib/radio/SX1262.cpp +++ b/lib/radio/SX1262.cpp @@ -12,6 +12,17 @@ SX1262Module::SX1262Module(RadioModuleSPIConfig radio2) : RadioModule() Serial.printf("Initialized Radio2: %s\n", radio2.toStr().c_str()); } +SX1262Module::~SX1262Module() +{ + if (_radio != nullptr) + { + Module *mod = _radio->getMod(); + delete _radio; + delete mod; + _radio = nullptr; + } +} + int16_t SX1262Module::beginScan(float init_freq, float bw, uint8_t shaping) { int16_t status = _radio->beginFSK(init_freq); diff --git a/lib/radio/radio.h b/lib/radio/radio.h index 06fc0fc..374c272 100644 --- a/lib/radio/radio.h +++ b/lib/radio/radio.h @@ -6,6 +6,7 @@ struct RadioModule { RadioModule() {}; + virtual ~RadioModule() {}; virtual int16_t beginScan(float init_freq, float bw, uint8_t shaping) = 0; virtual int16_t setFrequency(float freq) = 0; @@ -19,6 +20,7 @@ struct SX1262Module : RadioModule SX1262 *_radio; SX1262Module(RadioModuleSPIConfig cfg); + ~SX1262Module() override; int16_t beginScan(float init_freq, float bw, uint8_t shaping) override; int16_t setFrequency(float freq) override; diff --git a/include/WIFI_SERVER.h b/lib/wifi_server/wifi_server.cpp similarity index 74% rename from include/WIFI_SERVER.h rename to lib/wifi_server/wifi_server.cpp index 8fc24ad..4d9084a 100644 --- a/include/WIFI_SERVER.h +++ b/lib/wifi_server/wifi_server.cpp @@ -1,4 +1,8 @@ -// Search for parameter in HTTP POST request +#include "wifi_server.h" +#include "file_io.h" +#include + +// Parameter name constants const String SSID = "ssid"; const String PASS = "pass"; const String IP = "ip"; @@ -6,32 +10,25 @@ const String GATEWAY = "gateway"; const String FSTART = "fstart"; const String FEND = "fend"; -// File paths to save input values permanently -// const char *ssidPath = "/ssid.txt"; - -// Variables to save values from HTML form +// WiFi config variables String ssid = "LoraSA", pass = "1234567890", ip = "192.168.1.100", gateway = "192.168.1.1", fstart = "", fend = "", smpls = ""; #ifdef WEB_SERVER #include #include -#include #include // Create AsyncWebServer object on port 80 AsyncWebServer server(80); IPAddress localIP; -// Set your Gateway IP address IPAddress localGateway; IPAddress subnet(255, 255, 0, 0); -// Timer variables unsigned long previousMillis = 0; -const long interval = 10000; // interval to wait for Wi-Fi connection (milliseconds) +const long interval = 10000; -// Initialize WiFi bool initWiFi() { Serial.println("SSID:" + ssid); @@ -74,9 +71,8 @@ bool initWiFi() return true; } -void serverServer() +static void serverServer() { - // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(LittleFS, "/index.html", "text/html"); }); @@ -100,16 +96,16 @@ void serverServer() writeParameterToParameterFile(IP, p); } - if (request->hasParam(IP, true)) + if (request->hasParam(SSID, true)) { - p = request->getParam(IP, true)->value(); - writeParameterToParameterFile(IP, p); + p = request->getParam(SSID, true)->value(); + writeParameterToParameterFile(SSID, p); } - if (request->hasParam(IP, true)) + if (request->hasParam(PASS, true)) { - p = request->getParam(IP, true)->value(); - writeParameterToParameterFile(IP, p); + p = request->getParam(PASS, true)->value(); + writeParameterToParameterFile(PASS, p); } if (request->hasParam(GATEWAY, true)) @@ -144,23 +140,6 @@ void serverServer() 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(); } @@ -173,9 +152,7 @@ void serverStart() } else { - // 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); IPAddress IP = WiFi.softAPIP(); @@ -189,14 +166,12 @@ void serverStart() 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()); } diff --git a/lib/wifi_server/wifi_server.h b/lib/wifi_server/wifi_server.h new file mode 100644 index 0000000..d2af613 --- /dev/null +++ b/lib/wifi_server/wifi_server.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +// Parameter name constants +extern const String SSID; +extern const String PASS; +extern const String IP; +extern const String GATEWAY; +extern const String FSTART; +extern const String FEND; + +// WiFi config variables +extern String ssid, pass, ip, gateway, fstart, fend, smpls; + +void writeParameterToFile(String value, String file); +void writeParameterToParameterFile(String param, String value); +String readParameterFromParameterFile(String param); + +#ifdef WEB_SERVER +void serverStart(); +#endif diff --git a/platformio.ini b/platformio.ini index 10b980f..3f16a62 100644 --- a/platformio.ini +++ b/platformio.ini @@ -705,6 +705,7 @@ monitor_filters = esp32_exception_decoder board_upload.use_1200bps_touch = true build_flags = -DHELTEC + -DHELTEC_NO_DISPLAY -DHELTEC_BOARD=38 -DSLOW_CLK_TPYE=1 -DARDUINO_USB_CDC_ON_BOOT=1 @@ -723,7 +724,7 @@ build_flags = -DRADIOLIB_EXCLUDE_SX128X=true -DROTATION=1 # 1 = default; 3 = inverted -lib_deps = +lib_deps = SPI Wire adafruit/Adafruit BusIO @ 1.9.6 @@ -731,6 +732,10 @@ lib_deps = adafruit/Adafruit GFX Library@^1.11.10 ropg/Heltec_ESP32_LoRa_v3@^0.9.1 adafruit/Adafruit ST7735 and ST7789 Library@^1.10.4 +; T190 uses TFT (HT_ST7789 from Heltec ESP32 Dev-Boards), not OLED. +; The SSD1306 lib is a transitive dep of Heltec_ESP32_LoRa_v3 and conflicts +; with Heltec ESP32 Dev-Boards (both define DefaultFontTableLookup). +lib_ignore = ESP8266 and ESP32 OLED driver for SSD1306 displays [env:seek-on-mavic-sx1280] platform = espressif32 diff --git a/src/main.cpp b/src/main.cpp index e407130..525b69a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,28 +25,14 @@ #include "FS.h" #include -#ifdef WEB_SERVER -#include -#include -#endif -#include -#include #include #include #include #include #include -#include "WIFI_SERVER.h" - #define FORMAT_LITTLEFS_IF_FAILED true -// HardwareSerial Serial0(0); - -// #define OSD_ENABLED true -// #define WIFI_SCANNING_ENABLED true -// #define BT_SCANNING_ENABLED true - // Direct access to the low-level SPI communication between RadioLib and the radio module. #define RADIOLIB_LOW_LEVEL (1) // In this mode, all methods and member variables of all RadioLib classes will be made @@ -62,296 +48,36 @@ #include #include -bool bleDeviceConnected = false; +#include "bt.h" +#include "file_io.h" +#include "radio_init.h" +#include "wifi_server.h" -#ifdef BT_MOBILE -#define SERVICE_UUID "00001234-0000-1000-8000-00805f9b34fb" -#define CHARACTERISTIC_UUID "00001234-0000-1000-8000-00805f9b34ac" - -#ifndef BT_NM -#include -#include -#include -#include - -BLEServer *pServer = NULL; -BLECharacteristic *pCharacteristic = NULL; -BLEAdvertising *pAdvertising = NULL; - -class MyServerCallbacks : public BLEServerCallbacks -{ - void onConnect(BLEServer *pServer) { bleDeviceConnected = true; }; - - void onDisconnect(BLEServer *pServer) - { - bleDeviceConnected = false; - BLEDevice::startAdvertising(); // Restart advertising after disconnect - } -}; - -#else -#include - -NimBLEServer *pServer = nullptr; -NimBLECharacteristic *pCharacteristic = nullptr; -NimBLEAdvertising *pAdvertising = nullptr; - -class BTServerCallbacks : public NimBLEServerCallbacks -{ - public: - void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override - { - bleDeviceConnected = true; - Serial.printf("Device Connected | Free Heap: %d kByte\n", - ESP.getFreeHeap() / 1000); - Serial.printf("Client address: %s\n", connInfo.getAddress().toString().c_str()); - - pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 180); - } - - void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, - int reason) override - { - bleDeviceConnected = false; - Serial.println("Device Disconnected"); - NimBLEDevice::startAdvertising(); // Restart advertising - } - - void onMTUChange(uint16_t MTU, NimBLEConnInfo &connInfo) override - { - Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, - connInfo.getConnHandle()); - } -} BTServerCallbacks; - -class CharacteristicCallbacks : public NimBLECharacteristicCallbacks -{ - void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override - { - Serial.printf("%s : onRead(), value: %s\n", - pCharacteristic->getUUID().toString().c_str(), - pCharacteristic->getValue().c_str()); - } - - void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override - { - Serial.printf("%s : onWrite(), value: %s\n", - pCharacteristic->getUUID().toString().c_str(), - pCharacteristic->getValue().c_str()); - } - - void onStatus(NimBLECharacteristic *pCharacteristic, int code) override - { -#ifdef COMPASS_DEBUG - Serial.printf("Notification/Indication return code: %d, %s\n", code, - NimBLEUtils::returnCodeToString(code)); -#endif - } - - void onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo, - uint16_t subValue) override - { - std::string str = "Client ID: "; - str += connInfo.getConnHandle(); - str += " Address: "; - str += connInfo.getAddress().toString(); - if (subValue == 0) - { - str += " Unsubscribed to "; - } - else if (subValue == 1) - { - str += " Subscribed to notifications for "; - } - else if (subValue == 2) - { - str += " Subscribed to indications for "; - } - else if (subValue == 3) - { - str += " Subscribed to notifications and indications for "; - } - str += std::string(pCharacteristic->getUUID()); - - Serial.printf("%s\n", str.c_str()); - } -} chrCallbacks; - -class DescriptorCallbacks : public NimBLEDescriptorCallbacks -{ - void onWrite(NimBLEDescriptor *pDescriptor, NimBLEConnInfo &connInfo) override - { - std::string dscVal = pDescriptor->getValue(); - Serial.printf("Descriptor written value: %s\n", dscVal.c_str()); - } - - void onRead(NimBLEDescriptor *pDescriptor, NimBLEConnInfo &connInfo) override - { - Serial.printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str()); - } -} dscCallbacks; - -#endif - -void initBT() -{ -#ifdef BT_NM - // Initialize BLE device - NimBLEDevice::init("RSSI_Radar"); - - // Get and print the MAC address - String macAddress = NimBLEDevice::getAddress().toString().c_str(); - Serial.println("Bluetooth MAC Address: " + macAddress); - - // Create BLE server - pServer = NimBLEDevice::createServer(); - - if (!pServer) - { - Serial.println("Failed to create BLE Server"); - } - - pServer->setCallbacks(&BTServerCallbacks); - - // Create a BLE service - NimBLEService *pService = pServer->createService(SERVICE_UUID); - - // Create a BLE characteristic - pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); - pCharacteristic->setCallbacks(&chrCallbacks); - - // Start the service - pService->start(); - - // esp_task_wdt_init(20, true); // Increase timeout to 10 seconds - // esp_task_wdt_add(NULL); - - // Start advertising - pAdvertising = NimBLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->setName("ESP32_RSSI_Radar"); // Set the device name - // pAdvertising->setMinInterval(300); - // pAdvertising->setMaxInterval(350); - pAdvertising->enableScanResponse(true); - // pAdvertising->setScanResponse(true); // Allow scan responses - - pAdvertising->start(); - - Serial.println("BLE server started."); -#else - BLEDevice::init("ESP32_RADAR"); - pServer = BLEDevice::createServer(); - pServer->setCallbacks(new MyServerCallbacks()); - - BLEService *pService = pServer->createService(SERVICE_UUID); - - pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_WRITE | - BLECharacteristic::PROPERTY_NOTIFY); - - pCharacteristic->setValue("Hello from ESP32"); - pService->start(); - - pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->setScanResponse(true); - pAdvertising->setMinInterval(300); - pAdvertising->setMaxInterval(350); - BLEDevice::startAdvertising(); - - Serial.println("BLE server is ready!"); -#endif -} - -#endif - -// Function to send RSSI and Heading Data -void sendBTData(float heading, float rssi) -{ - String data = - "RSSI_HEADING: '{H:" + String(heading) + ",RSSI:-" + String(rssi) + "}'"; - -#ifdef COMPASS_DEBUG - Serial.println("Sending data: " + data); -#endif -#ifdef BT_MOBILE - pCharacteristic->setValue(data.c_str()); // Set BLE characteristic value - pCharacteristic->notify(); // Notify connected client -#endif -} - -// Send Scan Result to BLE -void sendBTData(Message &msg) -{ - if (msg.type != SCAN_HEADING_MAX && msg.type != SCAN_MAX_RESULT && - msg.type != SCAN_RESULT) - { - Serial.println("Unsupported message type: " + String(msg.type)); - return; - } - - String data = "{\"SCAN_RESULT\":{\"Hmin\":" + String(msg.payload.dump.heading_min) + - ",\"Hmax\":" + String(msg.payload.dump.heading_max) + ",\"Spectrum\":["; - - for (int i = 0; i < msg.payload.dump.sz; i++) - { - data += String(i == 0 ? "" : ",") + - "{\"F\":" + String(msg.payload.dump.freqs_khz[i]) + - ",\"R\":" + String(msg.payload.dump.rssis[i]) + - (msg.payload.dump.rssis2 == NULL - ? "" - : ",\"R2\":" + String(msg.payload.dump.rssis2[i])) + - "}"; - } - - data += "]}}"; -#ifdef COMPASS_DEBUG - Serial.println("Sending data: " + data); -#endif -#ifdef BT_MOBILE - pCharacteristic->setValue(data.c_str()); // Set BLE characteristic value - pCharacteristic->notify(); // Notify connected client -#endif -} +// BT module is in lib/bt/ #ifndef LILYGO #include -// This file contains a binary patch for the SX1262 -#include "modules/SX126x/patches/SX126x_patch_scan.h" -#endif // end ifndef LILYGO +#endif #if defined(LILYGO) -// LiLyGO device does not support the auto download mode, you need to get into the -// download mode manually. To do so, press and hold the BOOT button and then press the -// RESET button once. After that release the BOOT button. Or OFF->ON together with BOOT - -// Default LilyGO code #include - -// #include "utilities.h" -// Our Code #include -#endif // end LILYGO +#endif #include #include -#include DroneHeading droneHeading; Compass *compass = NULL; HeadingSensor &headingSensor = droneHeading; -RadioModule *radio2; - #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; -bool radioIsScan = false; +// radioIsScan is in lib/radio_init/ // time to scan BT #define BT_SCAN_TIME 10 @@ -587,21 +313,8 @@ uint8_t button_pressed_counter = 0; // #define JOYSTICK_ENABLED #endif -#include "joyStick.h" - -// project components -#if (defined(WIFI_SCANNING_ENABLED) || defined(BT_SCANNING_ENABLED)) && \ - defined(OSD_ENABLED) -#include "BT_WIFI_scan.h" -#endif - -#if defined(WIFI_SCANNING_ENABLED) && defined(OSD_ENABLED) -scanWiFi(osd) -#endif - -#if defined(BT_SCANNING_ENABLED) && defined(OSD_ENABLED) - scanBT(osd) -#endif +#include "input.h" +#include "bt_wifi_scan.h" #ifdef OSD_ENABLED unsigned short selectFreqChar(int bin, int start_level = 0) @@ -869,52 +582,6 @@ void osdProcess() Config config; -#ifdef USING_LR1121 -void setLRFreq(float freq) -{ - // LR1120::setFrequency updates protected freqMHz/highFreq and runs image - // calibration when the hop exceeds RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ. - state = radio.setFrequency(freq); -} -#endif - -float getRSSI(void *param) -{ - Scan *r = (Scan *)param; -#if defined(USING_SX1280PA) - // TODO: TEST new feature - radio.getRSSI(false); -#elif defined(USING_LR1121) - // Try getRssiInst - float rssi; - radio.getRssiInst(&rssi); - // Serial.println("RSSI: " + String(rssi)); - // pass the replies - return rssi; -#else - return radio.getRSSI(false); -#endif -} - -float getCAD(void *param) -{ - Scan *r = (Scan *)param; - - int16_t err = radio.scanChannel(); - if (err != RADIOLIB_ERR_NONE) - { - return -999; - } - -#ifdef USING_LR1121 - // LR1121 doesn't implement getRSSI(bool), getRSSI always - // returns RSSI of the last packet - return radio.getRSSI(); -#else - return radio.getRSSI(true); -#endif -} - Scan r; #define WATERFALL_SENSITIVITY 0.05 @@ -924,201 +591,7 @@ StackedChart stacked(display, 0, 0, 0, 0); UptimeClock *uptime; -int16_t initForScan(float freq) -{ - int16_t state; - -#if defined(USING_SX1280PA) - state = radio.beginGFSK(freq); -#elif defined(USING_LR1121) - state = radio.beginGFSK(freq, 4.8F, 5.0F, 156.2F, 10, 16U, 1.6F); - // RF Switch info Provided by LilyGo support: - // https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/blob/f2d3d995cba03c65a7031c73e212f106b03c95a2/examples/RadioLibExamples/Receive_Interrupt/Receive_Interrupt.ino#L279 - - // LR1121 - // set RF switch configuration for Wio WM1110 - // Wio WM1110 uses DIO5 and DIO6 for RF switching - static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, - RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, - RADIOLIB_NC, RADIOLIB_NC}; - - static const Module::RfSwitchMode_t rfswitch_table[] = { - // mode DIO5 DIO6 - {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, - {LR11x0::MODE_TX, {LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, - {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, - {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, - }; - radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); - - // LR1121 TCXO Voltage 2.85~3.15V - radio.setTCXO(3.0); - heltec_delay(1000); -#else - state = radio.beginFSK(freq); -#endif - - int gotoAcounter = 0; -A: -#ifdef METHOD_RSSI - // TODO: try RADIOLIB_SX126X_RX_TIMEOUT_INF -#ifdef USING_SX1280PA - state = radio.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_NONE); -#elif USING_LR1121 - state = radio.startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_NONE); -#else - state = radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_NONE); -#endif - - if (state != RADIOLIB_ERR_NONE) - { - Serial.print(F("Failed to start receive mode, error code: ")); - display.drawString(0, 64 - 10, "E:startReceive"); - display.display(); - heltec_delay(2000); - Serial.println(state); - gotoAcounter++; - if (gotoAcounter < 5) - { - goto A; - } - } - -#endif - - return state; -} - -bool setFrequency(float curr_freq) -{ - r.current_frequency = curr_freq; - LOG("setFrequency:%f\n", r.current_frequency); - // Serial.println("setFrequency:" + String(curr_freq)); - - int16_t state; -#ifdef USING_SX1280PA - int16_t state1 = - radio.setFrequency(r.current_frequency); // 1280 doesn't have calibration - - state = radio.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF); - if (state != RADIOLIB_ERR_NONE) - { - Serial.println("Error:startReceive:" + String(state)); - } - - state = state1; -#elif USING_SX1276 - state = radio.setFrequency(r.current_frequency); -#elif USING_LR1121 - // state = radio.setRfFrequency((uint32_t)(r.current_frequency * 1000000.0f)); - // TODO: make calibration, DONE!! - // ToDO: check how RF switch works continues scanning when init on low doesn't work - // for high freq - setLRFreq(r.current_frequency); -#else - state = radio.setFrequency(r.current_frequency, - true); // false = calibration is needed here -#endif - if (state != RADIOLIB_ERR_NONE) - { - display.drawString(0, 64 - 10, - "E(" + String(state) + - "):setFrequency:" + String(r.current_frequency)); - Serial.println("E(" + String(state) + - "):setFrequency:" + String(r.current_frequency)); - display.display(); - // delay(2); - return false; - } - - return true; -} - -void init_radio() -{ - // initialize SX1262 FSK modem at the initial frequency - both.println("Init radio"); -#ifndef INIT_FREQ - state = initForScan(CONF_FREQ_BEGIN); -#else - state = initForScan(INIT_FREQ); -#endif - if (state == RADIOLIB_ERR_NONE) - { - radioIsScan = true; - Serial.println(F("success!")); - } - else - { - display.println("Error:" + String(state)); - Serial.print(F("failed, code ")); - Serial.println(state); - while (true) - { - delay(5); - } - } - -#ifdef METHOD_SPECTRAL - // upload a patch to the SX1262 to enable spectral scan - // NOTE: this patch is uploaded into volatile memory, - // and must be re-uploaded on every power up - both.println("Upload SX1262 patch"); - - // Upload binary patch into the SX126x device RAM. Patch is needed to e.g., - // enable spectral scan and must be uploaded again on every power cycle. - RADIOLIB_OR_HALT(radio.uploadPatch(sx126x_patch_scan, sizeof(sx126x_patch_scan))); - // configure scan bandwidth and disable the data shaping -#endif - - both.println("Setting up radio"); -#ifdef USING_SX1280PA - // RADIOLIB_OR_HALT(radio.setBandwidth(RADIOLIB_SX128X_LORA_BW_406_25)); -#elif USING_SX1276 - // Receiver bandwidth in kHz. Allowed values - // are 2.6, 3.1, 3.9, 5.2, 6.3, 7.8, 10.4, 12.5, 15.6, 20.8, 25, 31.3, 41.7, - // 50, 62.5, 83.3, 100, 125, 166.7, 200 and 250 kHz. - RADIOLIB_OR_HALT(radio.setRxBandwidth(250)); -#else - RADIOLIB_OR_HALT(radio.setRxBandwidth(BANDWIDTH)); -#endif - - // and disable the data shaping - state = radio.setDataShaping(RADIOLIB_SHAPING_NONE); - if (state != RADIOLIB_ERR_NONE) - { - Serial.println("Error:setDataShaping:" + String(state)); - } - both.println("Starting scanning..."); - - // calibrate only once ,,, at startup - // TODO: check documentation (9.2.1) if we must calibrate in certain ranges - setFrequency(CONF_FREQ_BEGIN); - - delay(100); - -#ifdef USING_SX1262 - if (config.radio2.enabled && config.radio2.module.equalsIgnoreCase("SX1262")) - { - - radio2 = new SX1262Module(config.radio2); - state = radio2->beginScan(CONF_FREQ_BEGIN, BANDWIDTH, RADIOLIB_SHAPING_NONE); - if (state == RADIOLIB_ERR_NONE) - { - both.println("Initialized additional module OK"); - radio2->setRxBandwidth(BANDWIDTH); - } - else - { - Serial.printf("Error initializing additional module: %d\n", state); - if (state == RADIOLIB_ERR_CHIP_NOT_FOUND) - { - Serial.println("Radio2: CHIP NOT FOUND"); - } - } - } -#endif -} +// Radio init functions are in lib/radio_init/ struct frequency_scan_result { @@ -1131,6 +604,8 @@ struct frequency_scan_result size_t readings_sz; } frequency_scan_result; +static SemaphoreHandle_t scan_result_mutex = xSemaphoreCreateMutex(); + TaskHandle_t logToSerial = NULL; TaskHandle_t dumpToComms = NULL; @@ -1138,6 +613,7 @@ void eventListenerForReport(void *arg, Event &e) { if (e.type == EventType::DETECTED) { + xSemaphoreTake(scan_result_mutex, portMAX_DELAY); if (e.epoch != frequency_scan_result.last_epoch) { frequency_scan_result.dump.sz = 0; @@ -1203,10 +679,11 @@ void eventListenerForReport(void *arg, Event &e) frequency_scan_result.dump.heading_min = min(frequency_scan_result.dump.heading_min, heading); frequency_scan_result.dump.heading_max = - min(frequency_scan_result.dump.heading_max, heading); + max(frequency_scan_result.dump.heading_max, heading); } } + xSemaphoreGive(scan_result_mutex); return; } @@ -1258,7 +735,9 @@ void dumpToCommsTask(void *parameter) Message m; m.type = MessageType::SCAN_RESULT; + xSemaphoreTake(scan_result_mutex, portMAX_DELAY); m.payload.dump = frequency_scan_result.dump; + xSemaphoreGive(scan_result_mutex); if (requested_host) { HostComms->send(m); @@ -3207,7 +2686,7 @@ void doScan() #ifdef WIFI_SCANNING_ENABLED if ((millis() - wf_start) > WF_SCAN_DELAY) { - scanWiFi(); + scanWiFi(osd); wf_start = millis(); // prevent BT scanning after scanning WF bt_start = millis(); @@ -3217,7 +2696,7 @@ void doScan() if ((millis() - bt_start) > BT_SCAN_DELAY) { - scanBT(); + scanBT(osd); bt_start = millis(); } #endif @@ -3248,7 +2727,7 @@ std::unordered_map findMaxRssi(int16_t *rssis, uint32_t *freqs_khz return maxRssiPerMHz; } -bool lock = false; +// dead lock variable removed Result checkRadio(RadioComms &comms) { radioIsScan = false; @@ -3280,13 +2759,6 @@ int16_t sendMessage(RadioComms &comms, Message &msg) return status; } - if (false) - { - lock = true; - - lock = false; - } - status = comms.send(msg); if (status != RADIOLIB_ERR_NONE) diff --git a/src/radio_init.cpp b/src/radio_init.cpp new file mode 100644 index 0000000..18480df --- /dev/null +++ b/src/radio_init.cpp @@ -0,0 +1,245 @@ +#define RADIOLIB_LOW_LEVEL (1) +#define RADIOLIB_GODMODE (1) +#define RADIOLIB_CHECK_PARAMS (0) + +#include "radio_init.h" + +#include +#include + +#if defined(LILYGO) +#include +#include +#else +// For Heltec: we cannot include heltec_unofficial.h again (it defines globals). +// Include the convenience header for RADIOLIB_OR_HALT, and forward-declare the rest. +#include +#include +extern SSD1306Wire display; +// PrintSplitter is defined in heltec_unofficial.h; we only need Print interface +extern Print &both; +extern void heltec_delay(int ms); +#ifdef METHOD_SPECTRAL +#include "modules/SX126x/patches/SX126x_patch_scan.h" +#endif +#endif + +#include "global_config.h" +#include "ui.h" + +#include + +bool radioIsScan = false; +RadioModule *radio2 = NULL; + +extern Scan r; +extern int state; +extern Config config; +extern uint64_t CONF_FREQ_BEGIN, CONF_FREQ_END; + +#ifdef USING_LR1121 +void setLRFreq(float freq) +{ + state = radio.setFrequency(freq); +} + +static int16_t setLRFreqWithStatus(float freq) +{ + return radio.setFrequency(freq); +} +#endif + +float getRSSI(void *param) +{ + Scan *r = (Scan *)param; +#if defined(USING_SX1280PA) + radio.getRSSI(false); +#elif defined(USING_LR1121) + float rssi; + radio.getRssiInst(&rssi); + return rssi; +#else + return radio.getRSSI(false); +#endif +} + +float getCAD(void *param) +{ + Scan *r = (Scan *)param; + + int16_t err = radio.scanChannel(); + if (err != RADIOLIB_ERR_NONE) + { + return -999; + } + +#ifdef USING_LR1121 + return radio.getRSSI(); +#else + return radio.getRSSI(true); +#endif +} + +int16_t initForScan(float freq) +{ + int16_t state; + +#if defined(USING_SX1280PA) + state = radio.beginGFSK(freq); +#elif defined(USING_LR1121) + state = radio.beginGFSK(freq, 4.8F, 5.0F, 156.2F, 10, 16U, 1.6F); + + static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, + RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, + RADIOLIB_NC, RADIOLIB_NC}; + + static const Module::RfSwitchMode_t rfswitch_table[] = { + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, + }; + radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); + + radio.setTCXO(3.0); + heltec_delay(1000); +#else + state = radio.beginFSK(freq); +#endif + + int gotoAcounter = 0; +#ifdef METHOD_RSSI + while (true) + { +#ifdef USING_SX1280PA + state = radio.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_NONE); +#elif USING_LR1121 + state = radio.startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_NONE); +#else + state = radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_NONE); +#endif + + if (state == RADIOLIB_ERR_NONE) + break; + + Serial.print(F("Failed to start receive mode, error code: ")); + display.drawString(0, 64 - 10, "E:startReceive"); + display.display(); + heltec_delay(2000); + Serial.println(state); + gotoAcounter++; + if (gotoAcounter >= 5) + break; + } +#endif + + return state; +} + +bool setFrequency(float curr_freq) +{ + r.current_frequency = curr_freq; + LOG("setFrequency:%f\n", r.current_frequency); + + int16_t state; +#ifdef USING_SX1280PA + int16_t state1 = + radio.setFrequency(r.current_frequency); + + state = radio.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF); + if (state != RADIOLIB_ERR_NONE) + { + Serial.println("Error:startReceive:" + String(state)); + } + + state = state1; +#elif USING_SX1276 + state = radio.setFrequency(r.current_frequency); +#elif USING_LR1121 + state = setLRFreqWithStatus(r.current_frequency); +#else + state = radio.setFrequency(r.current_frequency, true); +#endif + if (state != RADIOLIB_ERR_NONE) + { + display.drawString(0, 64 - 10, + "E(" + String(state) + + "):setFrequency:" + String(r.current_frequency)); + Serial.println("E(" + String(state) + + "):setFrequency:" + String(r.current_frequency)); + display.display(); + return false; + } + + return true; +} + +void init_radio() +{ + both.println("Init radio"); +#ifndef INIT_FREQ + state = initForScan(CONF_FREQ_BEGIN); +#else + state = initForScan(INIT_FREQ); +#endif + if (state == RADIOLIB_ERR_NONE) + { + radioIsScan = true; + Serial.println(F("success!")); + } + else + { + display.println("Error:" + String(state)); + Serial.print(F("failed, code ")); + Serial.println(state); + while (true) + { + delay(5); + } + } + +#ifdef METHOD_SPECTRAL + both.println("Upload SX1262 patch"); + RADIOLIB_OR_HALT(radio.uploadPatch(sx126x_patch_scan, sizeof(sx126x_patch_scan))); +#endif + + both.println("Setting up radio"); +#ifdef USING_SX1280PA +#elif USING_SX1276 + RADIOLIB_OR_HALT(radio.setRxBandwidth(250)); +#else + RADIOLIB_OR_HALT(radio.setRxBandwidth(BANDWIDTH)); +#endif + + state = radio.setDataShaping(RADIOLIB_SHAPING_NONE); + if (state != RADIOLIB_ERR_NONE) + { + Serial.println("Error:setDataShaping:" + String(state)); + } + both.println("Starting scanning..."); + + setFrequency(CONF_FREQ_BEGIN); + + delay(100); + +#ifdef USING_SX1262 + if (config.radio2.enabled && config.radio2.module.equalsIgnoreCase("SX1262")) + { + radio2 = new SX1262Module(config.radio2); + state = radio2->beginScan(CONF_FREQ_BEGIN, BANDWIDTH, RADIOLIB_SHAPING_NONE); + if (state == RADIOLIB_ERR_NONE) + { + both.println("Initialized additional module OK"); + radio2->setRxBandwidth(BANDWIDTH); + } + else + { + Serial.printf("Error initializing additional module: %d\n", state); + if (state == RADIOLIB_ERR_CHIP_NOT_FOUND) + { + Serial.println("Radio2: CHIP NOT FOUND"); + } + } + } +#endif +} diff --git a/tft_src/main.cpp b/tft_src/main.cpp index ad848b7..5b1d55f 100644 --- a/tft_src/main.cpp +++ b/tft_src/main.cpp @@ -62,8 +62,7 @@ static SPIClass *gspi_lcd = NULL; char buffer[256]; -// Disabling default Heltec lib OLED display -#define HELTEC_NO_DISPLAY +// HELTEC_NO_DISPLAY is set in platformio.ini build_flags #define DISPLAY_WIDTH 320 #define DISPLAY_HEIGHT 170 // Without this line Lora Radio doesn't work with heltec lib @@ -131,7 +130,7 @@ uint64_t RANGE_PER_PAGE = FREQ_END - FREQ_BEGIN; // FREQ_BEGIN + DISPLAY_WIDTH; uint64_t iterations = RANGE / RANGE_PER_PAGE; // uint64_t range_frequency = FREQ_END - FREQ_BEGIN; -uint64_t median_frequency = FREQ_BEGIN + FREQ_END - FREQ_BEGIN / 2; +uint64_t median_frequency = FREQ_BEGIN + (FREQ_END - FREQ_BEGIN) / 2; // #define DISABLE_PLOT_CHART false // unused @@ -260,7 +259,7 @@ void setBrightness() { current_brightness = 255; } - ledcWrite(st7789_brightness_channel, current_brightness); + ledcWrite(st7789_LED_K_Pin, current_brightness); } #ifdef SERIAL_OUT @@ -588,22 +587,17 @@ void loop() st7789->drawPixel(x1, rssiToPix(rssi2) - 4, rssiToColor(abs(rssi2))); #ifdef SERIAL_OUT - frequency_scan_result.dump.freqs_khz[frequency_scan_result.dump.sz] = - (int)freq * 1000; - - frequency_scan_result.dump.rssis[frequency_scan_result.dump.sz] = rssi2; - frequency_scan_result.dump.sz++; - if (frequency_scan_result.dump.sz > 10000) + if (frequency_scan_result.dump.sz < 10000) { - Serial.println("frequency_scan_result overflow 10000"); + frequency_scan_result.dump.freqs_khz[frequency_scan_result.dump.sz] = + (int)freq * 1000; + frequency_scan_result.dump.rssis[frequency_scan_result.dump.sz] = rssi2; + frequency_scan_result.dump.sz++; } #endif - if (true /*draw full line*/) - { st7789->drawFastVLine(x1, rssiToPix(rssi2), lower_level - rssiToPix(rssi2), - rssiToColor(abs(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); @@ -881,12 +875,9 @@ void downgradeBandwidth() void setup() { - uint32_t *f = new uint32_t[10000]; - int16_t *r = new int16_t[10000]; - #ifdef SERIAL_OUT - frequency_scan_result.dump.freqs_khz = f; - frequency_scan_result.dump.rssis = r; + frequency_scan_result.dump.freqs_khz = new uint32_t[10000]; + frequency_scan_result.dump.rssis = new int16_t[10000]; #endif for (int i = 0; i < MAX_MHZ_INTERVAL; i++) @@ -916,10 +907,8 @@ void setup() digitalWrite(st7789_LED_K_Pin, HIGH); // set brightness: - ledcSetup(st7789_brightness_channel, st7789_brightness_freq, - st7789_brightness_resolution); - ledcAttachPin(st7789_LED_K_Pin, st7789_brightness_channel); - ledcWrite(st7789_brightness_channel, current_brightness); + ledcAttach(st7789_LED_K_Pin, st7789_brightness_freq, st7789_brightness_resolution); + ledcWrite(st7789_LED_K_Pin, current_brightness); // pinMode(5, OUTPUT); // digitalWrite(5, HIGH);