mirror of
https://github.com/Genaker/LoraSA.git
synced 2026-08-07 09:22:46 +02:00
Merge branch 'main' into testable
This commit is contained in:
+128
-111
@@ -29,14 +29,21 @@
|
||||
// #define WIFI_SCANNING_ENABLED true
|
||||
// #define BT_SCANNING_ENABLED true
|
||||
|
||||
// RSSI Scan Logic
|
||||
#include <scan.h>
|
||||
// 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
|
||||
// public and so will be exposed to the user. This allows direct manipulation of the
|
||||
// library internals.
|
||||
#define RADIOLIB_GODMODE (1)
|
||||
|
||||
#include "radioScan/radioScan.h"
|
||||
|
||||
#ifndef LILYGO
|
||||
#include <heltec_unofficial.h>
|
||||
// This file contains a binary patch for the SX1262
|
||||
#include "modules/SX126x/patches/SX126x_patch_scan.h"
|
||||
#elif defined(LILYGO)
|
||||
#endif // end LILYGO
|
||||
#if defined(LILYGO)
|
||||
// LiLyGO device does not support the auto download mode, you need to get into the
|
||||
// download mode manually. To do so, press and hold the BOOT button and then press the
|
||||
// RESET button once. After that release the BOOT button. Or OFF->ON together with BOOT
|
||||
@@ -45,7 +52,6 @@
|
||||
#include "utilities.h"
|
||||
// Our Code
|
||||
#include "LiLyGo.h"
|
||||
|
||||
#endif // end LILYGO
|
||||
|
||||
#define BT_SCAN_DELAY 60 * 1 * 1000
|
||||
@@ -102,10 +108,16 @@ typedef enum
|
||||
METHOD_SPECTRAL
|
||||
} TSCAN_METOD_ENUM;
|
||||
|
||||
// #define SCAN_METHOD METHOD_SPECTRAL
|
||||
|
||||
#define SCAN_METHOD
|
||||
// #define METHOD_SPECTRAL // Spectral scan method
|
||||
#define METHOD_RSSI // Uncomment this and comment METHOD_SPECTRAL fot RSSI
|
||||
|
||||
// Output Pixel Formula
|
||||
// 1 = rssi / 4, 2 = (rssi / 2) - 22 or 20
|
||||
// constexpr int RSSI_OUTPUT_FORMULA = 2;
|
||||
|
||||
// Feature to scan diapasones. Other frequency settings will be ignored.
|
||||
// int SCAN_RANGES[] = {850890, 920950};
|
||||
int SCAN_RANGES[] = {};
|
||||
@@ -114,15 +126,15 @@ int SCAN_RANGES[] = {};
|
||||
// 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
|
||||
|
||||
// To Enable Multi Screen scan
|
||||
// uint64_t RANGE_PER_PAGE = 50;
|
||||
// Default Range on Menu Button Switch
|
||||
|
||||
// multiplies STEPS * N to increase scan resolution.
|
||||
#define SCAN_RBW_FACTOR 2
|
||||
|
||||
constexpr int OSD_PIXELS_PER_CHAR = (STEPS * SCAN_RBW_FACTOR) / OSD_CHART_WIDTH;
|
||||
|
||||
// To Enable Multi Screen scan
|
||||
// uint64_t RANGE_PER_PAGE = 50;
|
||||
// Default Range on Menu Button Switch
|
||||
|
||||
#define DEFAULT_RANGE_PER_PAGE 50
|
||||
|
||||
// Print spectrum values pixels at once or by line
|
||||
@@ -132,8 +144,6 @@ bool ANIMATED_RELOAD = false;
|
||||
#define UP_FILTER 5
|
||||
// Trim low signals - nose level
|
||||
#define START_LOW 6
|
||||
// Remove reading without neighbors
|
||||
#define FILTER_SPECTRUM_RESULTS true
|
||||
#define FILTER_SAMPLES_MIN
|
||||
constexpr bool DRAW_DETECTION_TICKS = true;
|
||||
int16_t max_x_rssi[STEPS] = {999};
|
||||
@@ -343,14 +353,19 @@ void init_radio()
|
||||
{
|
||||
// initialize SX1262 FSK modem at the initial frequency
|
||||
both.println("Init radio");
|
||||
state == radio.beginFSK(FREQ_BEGIN);
|
||||
|
||||
#ifdef USING_SX1280PA
|
||||
// radio.begin();
|
||||
state = radio.beginGFSK(FREQ_BEGIN);
|
||||
#else
|
||||
state = radio.beginFSK(FREQ_BEGIN);
|
||||
#endif
|
||||
if (state == RADIOLIB_ERR_NONE)
|
||||
{
|
||||
Serial.println(F("success!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
display.println("Error:" + String(state));
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true)
|
||||
@@ -372,15 +387,37 @@ void init_radio()
|
||||
#endif
|
||||
|
||||
both.println("Setting up radio");
|
||||
#ifdef USING_SX1280PA
|
||||
// RADIOLIB_OR_HALT(radio.setBandwidth(RADIOLIB_SX128X_LORA_BW_406_25));
|
||||
#else
|
||||
RADIOLIB_OR_HALT(radio.setRxBandwidth(BANDWIDTH));
|
||||
#endif
|
||||
|
||||
// and disable the data shaping
|
||||
RADIOLIB_OR_HALT(radio.setDataShaping(RADIOLIB_SHAPING_NONE));
|
||||
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
|
||||
// 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);
|
||||
if (state != RADIOLIB_ERR_NONE)
|
||||
{
|
||||
Serial.println("Error:setFrequency:" + String(state));
|
||||
}
|
||||
state = radio.startReceive();
|
||||
if (state != RADIOLIB_ERR_NONE)
|
||||
{
|
||||
Serial.println("Error:startReceive:" + String(state));
|
||||
}
|
||||
#else
|
||||
radio.setFrequency(FREQ_BEGIN, true);
|
||||
#endif
|
||||
|
||||
delay(50);
|
||||
}
|
||||
|
||||
@@ -447,7 +484,7 @@ void setup(void)
|
||||
delay(400);
|
||||
display.clear();
|
||||
|
||||
resolution = RANGE / (STEPS * SCAN_RBW_FACTOR);
|
||||
resolution = (float)RANGE / (STEPS * SCAN_RBW_FACTOR);
|
||||
|
||||
single_page_scan = (RANGE_PER_PAGE == range);
|
||||
|
||||
@@ -510,7 +547,12 @@ void setup(void)
|
||||
|
||||
#ifdef METHOD_RSSI
|
||||
// TODO: try RADIOLIB_SX126X_RX_TIMEOUT_INF
|
||||
#ifdef USING_SX1280PA
|
||||
state = radio.startReceive(RADIOLIB_SX128X_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: "));
|
||||
@@ -709,7 +751,19 @@ struct RadioScan : Scan
|
||||
float getRSSI() override;
|
||||
};
|
||||
|
||||
float RadioScan::getRSSI() { return radio.getRSSI(false); }
|
||||
float RadioScan::getRSSI()
|
||||
{
|
||||
#ifdef 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));
|
||||
#else
|
||||
return radio.getRSSI(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
// MAX Frequency RSSI BIN value of the samples
|
||||
int max_rssi_x = 999;
|
||||
@@ -828,11 +882,14 @@ void loop(void)
|
||||
float step = (range * ((float)x / (STEPS * SCAN_RBW_FACTOR)));
|
||||
|
||||
freq = fr_begin + step;
|
||||
#ifdef PRINT_DEBUG
|
||||
Serial.println("setFrequency:" + String(freq));
|
||||
#endif
|
||||
LOG("setFrequency:%f\n", freq);
|
||||
|
||||
#ifdef USING_SX1280PA
|
||||
state = radio.setFrequency(freq); // 1280 doesn't have calibration
|
||||
radio.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF);
|
||||
#else
|
||||
state = radio.setFrequency(freq, false); // false = no calibration need here
|
||||
#endif
|
||||
int radio_error_count = 0;
|
||||
if (state != RADIOLIB_ERR_NONE)
|
||||
{
|
||||
@@ -846,9 +903,7 @@ void loop(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef PRINT_DEBUG
|
||||
Serial.printf("Step:%d Freq: %f\n", x, freq);
|
||||
#endif
|
||||
LOG("Step:%d Freq: %f\n", x, freq);
|
||||
// SpectralScan Method
|
||||
#ifdef METHOD_SPECTRAL
|
||||
{
|
||||
@@ -906,59 +961,21 @@ void loop(void)
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
#endif
|
||||
detected = false;
|
||||
detected_y[display_x] = false;
|
||||
max_rssi_x = 999;
|
||||
size_t detected_at = r.detect(
|
||||
result, filtered_result, RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE, samples);
|
||||
|
||||
for (y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
if (max_rssi_x > detected_at)
|
||||
{
|
||||
// MAx bin Value not RSSI
|
||||
max_rssi_x = detected_at;
|
||||
}
|
||||
|
||||
#ifdef PRINT_DEBUG
|
||||
Serial.print(String(y) + ":");
|
||||
Serial.print(String(result[y]) + ",");
|
||||
#endif
|
||||
#if !defined(FILTER_SPECTRUM_RESULTS) || FILTER_SPECTRUM_RESULTS == false
|
||||
if (result[y] && result[y] != 0)
|
||||
{
|
||||
filtered_result[y] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered_result[y] = 0;
|
||||
}
|
||||
#endif
|
||||
detected = detected_at < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE;
|
||||
detected_y[display_x] = false;
|
||||
|
||||
// if samples low ~1 filter removes all values
|
||||
#if FILTER_SPECTRUM_RESULTS
|
||||
|
||||
filtered_result[y] = 0;
|
||||
// Filter Elements without neighbors
|
||||
// if RSSI method actual value is -xxx dB
|
||||
if (result[y] > 0 && samples > 1)
|
||||
{
|
||||
// do not process 'first' and 'last' row to avoid out of index
|
||||
// access.
|
||||
if ((y > 0) && (y < (RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 2)))
|
||||
{
|
||||
if (((result[y + 1] != 0) && (result[y + 2] != 0)) ||
|
||||
(result[y - 1] != 0))
|
||||
{
|
||||
filtered_result[y] = 1;
|
||||
// Fill empty pixel
|
||||
result[y + 1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PRINT_DEBUG
|
||||
Serial.print("Filtered:" + String(x) + ":" + String(y) + ",");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // not filtering if samples == 1 because it will be filtered
|
||||
else if (result[y] > 0 && samples == 1)
|
||||
{
|
||||
filtered_result[y] = 1;
|
||||
}
|
||||
for (int y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
{
|
||||
// calculating max window x RSSI after filters
|
||||
x_window = (int)(display_x / WINDOW_SIZE);
|
||||
int abs_result = abs(result[y]);
|
||||
@@ -966,16 +983,15 @@ void loop(void)
|
||||
max_x_window[x_window] > abs_result)
|
||||
{
|
||||
max_x_window[x_window] = abs_result;
|
||||
#ifdef PRINT_DEBUG
|
||||
Serial.println("MAX x window: " + String(x_window) + " " +
|
||||
String(abs_result));
|
||||
#endif
|
||||
LOG("MAX x window: %i %i\n", x_window, abs_result);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (detected_at <= drone_detection_level)
|
||||
{
|
||||
// check if we should alarm about a drone presence
|
||||
if ((filtered_result[y] == 1) // we have some data and
|
||||
&& (y <= drone_detection_level) &&
|
||||
detected_y[display_x] == false) // detection threshold match
|
||||
if (detected_y[display_x] == false) // detection threshold match
|
||||
{
|
||||
// Set LED to ON (filtered in UI component)
|
||||
UI_setLedFlag(true);
|
||||
@@ -1019,8 +1035,7 @@ void loop(void)
|
||||
}
|
||||
}
|
||||
#if (WATERFALL_ENABLED == true)
|
||||
if ((filtered_result[y] == 1) && (y <= drone_detection_level) &&
|
||||
(single_page_scan) && (waterfall[display_x] != true) && new_pixel)
|
||||
if ((single_page_scan) && (waterfall[display_x] != true) && new_pixel)
|
||||
{
|
||||
// If drone not found set dark pixel on the waterfall
|
||||
// TODO: make something like scrolling up if possible
|
||||
@@ -1030,44 +1045,46 @@ void loop(void)
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
#endif
|
||||
// next 2 If's ... adds !!!! 10ms of runtime ......tfk ???
|
||||
}
|
||||
|
||||
#ifdef PRINT_DEBUG
|
||||
for (int y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
{
|
||||
if (filtered_result[y] == 1)
|
||||
{
|
||||
#ifdef PRINT_DEBUG
|
||||
Serial.print("Pixel:" + String(display_x) + "(" + String(x) + ")" +
|
||||
":" + String(y) + ",");
|
||||
#endif
|
||||
if (max_rssi_x > y)
|
||||
{
|
||||
// MAx bin Value not RSSI
|
||||
max_rssi_x = y;
|
||||
}
|
||||
// Set MAIN signal level pixel
|
||||
if (y < MAX_POWER_LEVELS - START_LOW)
|
||||
{
|
||||
display.setPixel(display_x, y + START_LOW);
|
||||
}
|
||||
if (!detected)
|
||||
{
|
||||
detected = true;
|
||||
}
|
||||
LOG("Pixel:%i(%i):%i,", display_x, x, y);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Draw "Detection Level line" every 2 pixel
|
||||
// -------------------------------------------------------------
|
||||
if ((y == drone_detection_level) && (display_x % 2 == 0))
|
||||
for (int y = 0; y < min(RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE,
|
||||
MAX_POWER_LEVELS - START_LOW);
|
||||
y++)
|
||||
{
|
||||
if (filtered_result[y] == 1)
|
||||
{
|
||||
// Set MAIN signal level pixel
|
||||
display.setPixelColor(display_x, y + START_LOW, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Draw "Detection Level line" every 2 pixel
|
||||
// -------------------------------------------------------------
|
||||
if (display_x % 2 == 0)
|
||||
{
|
||||
if (filtered_result[drone_detection_level] == 1)
|
||||
{
|
||||
display.setColor(INVERSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.setColor(WHITE);
|
||||
if (filtered_result[y] == 1)
|
||||
{
|
||||
display.setColor(INVERSE);
|
||||
}
|
||||
display.setPixel(display_x, y + START_LOW);
|
||||
// display.setPixel(display_x, y + START_LOW - 1); // 2 px wide
|
||||
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
display.setPixel(display_x, drone_detection_level + START_LOW);
|
||||
// display.setPixel(display_x, y + START_LOW - 1); // 2 px wide
|
||||
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
|
||||
#ifdef JOYSTICK_ENABLED
|
||||
|
||||
Reference in New Issue
Block a user