mirror of
https://github.com/Genaker/LoraSA.git
synced 2026-07-05 09:22:05 +02:00
add waterfall
This commit is contained in:
+413
-166
@@ -22,8 +22,31 @@
|
||||
*/
|
||||
|
||||
// frequency range in MHz to scan
|
||||
#define FREQ_BEGIN 820
|
||||
#define FREQ_END 900
|
||||
#define FREQ_BEGIN 860
|
||||
// TODO: if % RANGE_PER_PAGE 1= 0
|
||||
#define FREQ_END 960
|
||||
|
||||
#define UP_FILTER = 5;
|
||||
#define LOW_FILTER = 3;
|
||||
|
||||
// numbers of the spectrum screen lines = width of screen
|
||||
#define STEPS 128
|
||||
// Number of samples for each frequency scan. Fewer samples = better temporal resolution.
|
||||
#define SAMPLES 60 //(scan time = 1294)
|
||||
|
||||
#define RANGE (int)(FREQ_END - FREQ_BEGIN)
|
||||
// MHZ per page
|
||||
// to put everething into one page set RANGE_PER_PAGE = FREQ_END - 800
|
||||
unsigned int RANGE_PER_PAGE = 100;
|
||||
#define SINGLE_STEP (float)(RANGE / STEPS)
|
||||
|
||||
unsigned int single_step = SINGLE_STEP;
|
||||
|
||||
unsigned int range = (int)(FREQ_END - FREQ_BEGIN);
|
||||
unsigned int fr_begin = FREQ_BEGIN;
|
||||
unsigned int fr_end = FREQ_BEGIN;
|
||||
|
||||
unsigned int iterations = RANGE / RANGE_PER_PAGE;
|
||||
|
||||
unsigned int range_freqancy = FREQ_END - FREQ_BEGIN;
|
||||
unsigned int median_freqancy = FREQ_BEGIN + range_freqancy / 2;
|
||||
@@ -35,7 +58,7 @@ unsigned int median_freqancy = FREQ_BEGIN + range_freqancy / 2;
|
||||
|
||||
// (optional) major and minor tickmarks at x MHz
|
||||
#define MAJOR_TICKS 10
|
||||
// #define MINOR_TICKS 4
|
||||
#define MINOR_TICKS 5
|
||||
|
||||
// Turns the 'PRG' button into the power button, long press is off
|
||||
#define HELTEC_POWER_BUTTON // must be before "#include <heltec_unofficial.h>"
|
||||
@@ -52,28 +75,31 @@ unsigned int median_freqancy = FREQ_BEGIN + range_freqancy / 2;
|
||||
// Change spectrum plot values at once or by line
|
||||
#define ANIMATED_RELOAD true
|
||||
|
||||
// numbers of the spectrum screan lines = width of screan
|
||||
#define STEPS 128
|
||||
// Number of samples for each freqancy scan. Fewer samples = better temporal resolution.
|
||||
#define SAMPLES 190 //(scan time = 1294)
|
||||
#define MAJOR_TICK_LENGTH 3
|
||||
#define MINOR_TICK_LENGTH 1
|
||||
#define X_AXIS_WEIGHT 2
|
||||
#define HEIGHT RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE
|
||||
//
|
||||
#define SCALE_TEXT_TOP (HEIGHT + X_AXIS_WEIGHT + MAJOR_TICK_LENGTH)
|
||||
#define STATUS_TEXT_TOP (64 - 14)
|
||||
#define RANGE (float)(FREQ_END - FREQ_BEGIN)
|
||||
#define SINGLE_STEP (float)(RANGE / STEPS)
|
||||
#define STATUS_TEXT_TOP (64 - 10)
|
||||
|
||||
// Detection level from the 33 levels. Higher number is more sensative
|
||||
#define DEFAULT_DRONE_DETECTION_LEVEL 21
|
||||
|
||||
#define BUZZZER_PIN 41
|
||||
// REB trigger PIN
|
||||
#define REB_PIN 42
|
||||
|
||||
#define WATERFALL_START 39
|
||||
|
||||
#define DISABLE_PLOT_CHART false
|
||||
|
||||
// Array to store the scan results
|
||||
uint16_t result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
|
||||
uint16_t filtered_result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
|
||||
|
||||
// Waterfall array
|
||||
bool waterfall[10][STEPS][10];
|
||||
// global variable
|
||||
unsigned short int scan_var = 0;
|
||||
// initialized flag
|
||||
@@ -86,6 +112,8 @@ bool drone_detected = false;
|
||||
unsigned int drone_detection_level = DEFAULT_DRONE_DETECTION_LEVEL;
|
||||
unsigned int drone_detected_freqancy_start = 0;
|
||||
unsigned int drone_detected_freqancy_end = 0;
|
||||
unsigned int detection_count = 0;
|
||||
bool single_page_scan = false;
|
||||
|
||||
unsigned int start_scan_text = (128 / 2) - 3;
|
||||
|
||||
@@ -94,10 +122,26 @@ unsigned int scan_start_time = 0;
|
||||
|
||||
uint64_t start = 0;
|
||||
|
||||
unsigned int x, y = 0;
|
||||
unsigned int x, y, i, w = 0;
|
||||
|
||||
float freq = 0;
|
||||
|
||||
void clearStatus()
|
||||
{
|
||||
// clear status line
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(0, STATUS_TEXT_TOP + 2, 128, 13);
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
|
||||
void clearPloter()
|
||||
{
|
||||
// clear the scan plot rectangle
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(0, 0, STEPS, HEIGHT);
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draws ticks on the display at regular whole intervals.
|
||||
*
|
||||
@@ -106,92 +150,149 @@ float freq = 0;
|
||||
*/
|
||||
void drawTicks(float every, int length)
|
||||
{
|
||||
float first_tick = FREQ_BEGIN + (every - (FREQ_BEGIN - (int)(FREQ_BEGIN / every) * every));
|
||||
if (first_tick < FREQ_BEGIN)
|
||||
int first_tick = 0;
|
||||
//+ (every - (fr_begin - (int)(fr_begin / every) * every));
|
||||
/*if (first_tick < fr_begin)
|
||||
{
|
||||
first_tick += every;
|
||||
}
|
||||
for (float tick_freq = first_tick; tick_freq <= FREQ_END; tick_freq += every)
|
||||
}*/
|
||||
bool correction = false;
|
||||
int pixels_per_step = STEPS / (RANGE_PER_PAGE / every);
|
||||
if (STEPS / RANGE_PER_PAGE != 0)
|
||||
{
|
||||
int tick = round((tick_freq - FREQ_BEGIN) / SINGLE_STEP);
|
||||
display.drawLine(tick, HEIGHT + X_AXIS_WEIGHT, tick, HEIGHT + X_AXIS_WEIGHT + length);
|
||||
correction = true;
|
||||
}
|
||||
int correction_number = STEPS - (int)(pixels_per_step * (RANGE_PER_PAGE / every));
|
||||
int tick = 0;
|
||||
int tick_minor = 0;
|
||||
int median = (RANGE_PER_PAGE / every) / 2;
|
||||
for (int t = 0; t <= (RANGE_PER_PAGE / every) + 1; t++)
|
||||
{
|
||||
// fix if pixels per step is not int and we have shift
|
||||
if (correction && t % 2 != 0 && correction_number > 1)
|
||||
{
|
||||
// pixels_per_step++;
|
||||
correction_number--;
|
||||
}
|
||||
|
||||
tick += pixels_per_step;
|
||||
Serial.print("tick:");
|
||||
Serial.print(tick);
|
||||
Serial.print("\n");
|
||||
|
||||
tick_minor = tick - pixels_per_step / 2;
|
||||
Serial.print("tick_minor:");
|
||||
Serial.print(tick_minor);
|
||||
Serial.print("\n");
|
||||
|
||||
// Fix double tick at the end ...
|
||||
if (tick < 128 - 3)
|
||||
display.drawLine(tick, HEIGHT + X_AXIS_WEIGHT, tick, HEIGHT + X_AXIS_WEIGHT + length);
|
||||
|
||||
#ifdef MINOR_TICKS
|
||||
// Fix two ticks togather
|
||||
// if(tick_minor + 1 != tick && tick_minor - 1 != tick && tick_minor + 2 != tick && tick_minor - 2 != tick) {
|
||||
display.drawLine(tick_minor, HEIGHT + X_AXIS_WEIGHT, tick_minor, HEIGHT + X_AXIS_WEIGHT + 2);
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw Central Tick
|
||||
// display.drawLine(128/2, HEIGHT + X_AXIS_WEIGHT, 128/2, HEIGHT + X_AXIS_WEIGHT + 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decorates the display: everything but the plot itself.
|
||||
*/
|
||||
void displayDecorate()
|
||||
void displayDecorate(int begin = 0, int end = 0, bool redraw = false)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
// begining and end ticks
|
||||
display.fillRect(0, HEIGHT + X_AXIS_WEIGHT, 2, MAJOR_TICK_LENGTH);
|
||||
display.fillRect(126, HEIGHT + X_AXIS_WEIGHT, 2, MAJOR_TICK_LENGTH);
|
||||
// frequencies
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawString(0, SCALE_TEXT_TOP, String(FREQ_BEGIN));
|
||||
|
||||
// drone detection level
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display.drawString(128, 0, String(drone_detection_level));
|
||||
}
|
||||
|
||||
if (!initialized || redraw)
|
||||
{
|
||||
// Clear something
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(0, SCALE_TEXT_TOP + 1, 128, 12);
|
||||
display.setColor(WHITE);
|
||||
|
||||
// drone detection level
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display.drawString(128, 0, String(drone_detection_level));
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.drawString(128 / 2, SCALE_TEXT_TOP, String(median_freqancy));
|
||||
// Draw Central line
|
||||
display.drawLine(128 / 2, HEIGHT + X_AXIS_WEIGHT, 128 / 2, HEIGHT + X_AXIS_WEIGHT + 4);
|
||||
// frequency start
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawString(0, SCALE_TEXT_TOP, (begin == 0) ? String(FREQ_BEGIN) : String(begin));
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.drawString(128 / 2, SCALE_TEXT_TOP, (begin == 0) ? String(median_freqancy) : String(begin + ((end - begin) / 2)));
|
||||
|
||||
// frequency end
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display.drawString(128, SCALE_TEXT_TOP, String(FREQ_END));
|
||||
display.drawString(128, SCALE_TEXT_TOP, (end == 0) ? String(FREQ_END) : String(end));
|
||||
}
|
||||
|
||||
if (led_flag == true)
|
||||
{
|
||||
digitalWrite(LED, HIGH);
|
||||
tone(BUZZZER_PIN, 104, 250);
|
||||
digitalWrite(REB_PIN, HIGH);
|
||||
led_flag = false;
|
||||
}
|
||||
else
|
||||
|
||||
else if (!redraw)
|
||||
{
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
// Status text block
|
||||
if (drone_detected == 0)
|
||||
if (!drone_detected)
|
||||
{
|
||||
// "Scanning"
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
// clear status line
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(0, STATUS_TEXT_TOP, 128, 16);
|
||||
display.setColor(WHITE);
|
||||
clearStatus();
|
||||
if (scan_var == 0)
|
||||
{
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, "Scanning. ");
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, "Scan. ");
|
||||
}
|
||||
else if (scan_var == 1)
|
||||
{
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, "Scanning.. ");
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, "Scan.. ");
|
||||
}
|
||||
else if (scan_var == 2)
|
||||
{
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, "Scanning...");
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, "Scan...");
|
||||
}
|
||||
scan_var++;
|
||||
if (scan_var == 3)
|
||||
{
|
||||
scan_var = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (drone_detected)
|
||||
{
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
// clear status line
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(0, STATUS_TEXT_TOP, 128, 16);
|
||||
display.setColor(WHITE);
|
||||
clearStatus();
|
||||
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, String(drone_detected_freqancy_start) + ">!UAV!<" + String(drone_detected_freqancy_end));
|
||||
drone_detected_freqancy_start = 0;
|
||||
drone_detected = 0;
|
||||
display.drawString(start_scan_text, STATUS_TEXT_TOP, String(drone_detected_freqancy_start) + ">RF<" + String(drone_detected_freqancy_end));
|
||||
}
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawString(0, STATUS_TEXT_TOP, String(FREQ_BEGIN));
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display.drawString(128, STATUS_TEXT_TOP, String(FREQ_END));
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
// X-axis
|
||||
@@ -199,9 +300,6 @@ void displayDecorate()
|
||||
// ticks
|
||||
#ifdef MAJOR_TICKS
|
||||
drawTicks(MAJOR_TICKS, MAJOR_TICK_LENGTH);
|
||||
#endif
|
||||
#ifdef MINOR_TICKS
|
||||
drawTicks(MINOR_TICKS, MINOR_TICK_LENGTH);
|
||||
#endif
|
||||
}
|
||||
initialized = true;
|
||||
@@ -211,18 +309,21 @@ void setup()
|
||||
{
|
||||
pinMode(LED, OUTPUT);
|
||||
pinMode(BUZZZER_PIN, OUTPUT);
|
||||
pinMode(REB_PIN, OUTPUT);
|
||||
heltec_setup();
|
||||
display.clear();
|
||||
// draw the logo
|
||||
// draw the UCOG welcome logo
|
||||
display.drawXbm(0, 2, 128, 64, epd_bitmap_ucog);
|
||||
display.display();
|
||||
delay(4000);
|
||||
|
||||
delay(2000);
|
||||
|
||||
// initialize SX1262 FSK modem at the initial frequency
|
||||
both.println("Init radio");
|
||||
RADIOLIB_OR_HALT(radio.beginFSK(FREQ_BEGIN));
|
||||
// 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
|
||||
// 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)));
|
||||
@@ -237,145 +338,291 @@ void setup()
|
||||
delay(300);
|
||||
|
||||
display.clear();
|
||||
displayDecorate();
|
||||
// waterfall start line y-asix
|
||||
w = WATERFALL_START;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
float resolution = RANGE / STEPS;
|
||||
if (RANGE_PER_PAGE == range)
|
||||
{
|
||||
single_page_scan = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
single_page_scan = false;
|
||||
}
|
||||
|
||||
if (single_page_scan)
|
||||
{
|
||||
both.println("Single Page Screan MODE");
|
||||
both.println("To Enable single screan View Press P - button");
|
||||
both.println("Single Screan Resolution: " + String(resolution) + "Mhz/tick");
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
delay(10);
|
||||
both.print(".");
|
||||
if (button.pressed())
|
||||
{
|
||||
RANGE_PER_PAGE = 50;
|
||||
single_page_scan = false;
|
||||
tone(BUZZZER_PIN, 205, 100);
|
||||
delay(50);
|
||||
tone(BUZZZER_PIN, 205, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
both.println("Multi Page Screan MODE");
|
||||
both.println("To Enable single screan View Press P - button");
|
||||
both.println("Single screan Resolution: " + String(resolution) + "Mhz/tick");
|
||||
both.println("Curent Resolution: " + String((float)RANGE_PER_PAGE / STEPS) + "Mhz/tick");
|
||||
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
delay(10);
|
||||
both.print(".");
|
||||
if (button.pressed())
|
||||
{
|
||||
RANGE_PER_PAGE = range;
|
||||
single_page_scan = true;
|
||||
tone(BUZZZER_PIN, 205, 100);
|
||||
delay(50);
|
||||
tone(BUZZZER_PIN, 205, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
display.clear();
|
||||
}
|
||||
displayDecorate();
|
||||
drone_detected = false;
|
||||
drone_detected_freqancy_start = 0;
|
||||
#ifdef PRINT_PROFILE_TIME
|
||||
start = millis();
|
||||
#endif
|
||||
|
||||
if (!ANIMATED_RELOAD)
|
||||
if (!ANIMATED_RELOAD || !single_page_scan)
|
||||
{
|
||||
// clear the scan plot rectangle
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(0, 0, STEPS, HEIGHT);
|
||||
display.setColor(WHITE);
|
||||
clearPloter();
|
||||
}
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
// drone detection level
|
||||
display.drawString(128, 0, String(drone_detection_level));
|
||||
|
||||
// do the scan
|
||||
for (x = 0; x < STEPS; x++)
|
||||
range = FREQ_END - FREQ_BEGIN;
|
||||
|
||||
if (RANGE_PER_PAGE > range)
|
||||
{
|
||||
if (ANIMATED_RELOAD)
|
||||
{
|
||||
display.setColor(BLACK);
|
||||
display.drawVerticalLine(x, 0, HEIGHT);
|
||||
display.drawVerticalLine(x + 1, 0, HEIGHT);
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
freq = FREQ_BEGIN + (RANGE * ((float)x / STEPS));
|
||||
radio.setFrequency(freq);
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.println();
|
||||
Serial.print("step-");
|
||||
Serial.print(x);
|
||||
Serial.print(" Frequancy:");
|
||||
Serial.print(freq);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
scan_start_time = millis();
|
||||
// start spectral scan
|
||||
radio.spectralScanStart(SAMPLES, 1);
|
||||
// wait for spectral scan to finish
|
||||
while (radio.spectralScanGetStatus() != RADIOLIB_ERR_NONE)
|
||||
{
|
||||
heltec_delay(1);
|
||||
}
|
||||
// read the results Array to which the results will be saved
|
||||
radio.spectralScanGetResult(result);
|
||||
// Filter Elements without neabors
|
||||
for (y = 1; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
{
|
||||
if (result[y] && (result[y + 1] > 0 || result[y - 1] > 0))
|
||||
{
|
||||
filtered_result[y] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered_result[y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
{
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.printf("%04X,", result[y]);
|
||||
#endif
|
||||
if (result[y] || y == drone_detection_level)
|
||||
{
|
||||
// check if we shuld alarm the dron
|
||||
if (filtered_result[y] == 1 && y <= drone_detection_level)
|
||||
{
|
||||
drone_detected = true;
|
||||
if (drone_detected_freqancy_start == 0)
|
||||
{
|
||||
drone_detected_freqancy_start = freq;
|
||||
}
|
||||
drone_detected_freqancy_end = freq;
|
||||
led_flag = true;
|
||||
//if level to sensetive doing beep every 10th freaqancy and shorter
|
||||
//TODO: make every 10th detection...
|
||||
if (drone_detection_level < 25){
|
||||
tone(BUZZZER_PIN, 205, 10);
|
||||
} else {
|
||||
if (x % 10 == 0)
|
||||
tone(BUZZZER_PIN, 205, 5);
|
||||
}
|
||||
display.setPixel(x, 1);
|
||||
display.setPixel(x, 2);
|
||||
display.setPixel(x, 3);
|
||||
display.setPixel(x, 4);
|
||||
}
|
||||
if (filtered_result[y] == 1)
|
||||
{
|
||||
display.setPixel(x, y);
|
||||
}
|
||||
|
||||
// Detection Level line
|
||||
if (y == drone_detection_level && x % 2 == 0)
|
||||
{
|
||||
display.setPixel(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.println();
|
||||
#endif
|
||||
if (first_run || ANIMATED_RELOAD)
|
||||
{
|
||||
display.display();
|
||||
}
|
||||
|
||||
// Detection level button short press
|
||||
if (button.pressedFor(100)) {
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
// erase old value
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(128-13, 0, 13, 13);
|
||||
display.setColor(WHITE);
|
||||
drone_detection_level++;
|
||||
// print new value
|
||||
display.drawString(128, 0, String(drone_detection_level));
|
||||
if (drone_detection_level > 30) {
|
||||
drone_detection_level = 1;
|
||||
}
|
||||
RANGE_PER_PAGE = range;
|
||||
}
|
||||
// wait a little bit before the next scan, otherwise the SX1262 hangs
|
||||
heltec_delay(1);
|
||||
|
||||
fr_begin = FREQ_BEGIN;
|
||||
fr_end = fr_begin;
|
||||
// 50 is a single screan range
|
||||
// TODO:Make 50 as a variable with the option show full range
|
||||
iterations = range / RANGE_PER_PAGE;
|
||||
|
||||
single_step = RANGE_PER_PAGE / 128;
|
||||
if (range % RANGE_PER_PAGE != 0)
|
||||
{
|
||||
// add more scan
|
||||
//++;
|
||||
}
|
||||
|
||||
if (RANGE_PER_PAGE == range)
|
||||
{
|
||||
single_page_scan = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
single_page_scan = false;
|
||||
}
|
||||
|
||||
// Iterateing by small ranges by 50 Mhz each pixel is 0.4 Mhz
|
||||
for (i = 0; i < iterations; i++)
|
||||
{
|
||||
range = RANGE_PER_PAGE;
|
||||
drone_detected_freqancy_start == 0;
|
||||
|
||||
fr_begin = (i == 0) ? fr_begin : fr_begin += range;
|
||||
fr_end = fr_begin + RANGE_PER_PAGE;
|
||||
|
||||
if (!ANIMATED_RELOAD || !single_page_scan)
|
||||
{
|
||||
// clear the scan plot rectangle
|
||||
clearPloter();
|
||||
}
|
||||
|
||||
if (single_page_scan == false)
|
||||
{
|
||||
displayDecorate(fr_begin, fr_end, true);
|
||||
}
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
// horizontal x assix loop
|
||||
for (x = 0; x < STEPS; x++)
|
||||
{
|
||||
if (ANIMATED_RELOAD)
|
||||
{
|
||||
// Draw animated cursor on reload process
|
||||
display.setColor(BLACK);
|
||||
display.drawVerticalLine(x, 0, HEIGHT);
|
||||
display.drawVerticalLine(x + 1, 0, HEIGHT);
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
waterfall[i][x][w] = false;
|
||||
freq = fr_begin + (range * ((float)x / STEPS));
|
||||
radio.setFrequency(freq);
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.println();
|
||||
Serial.print("step-");
|
||||
Serial.print(x);
|
||||
Serial.print(" Frequancy:");
|
||||
Serial.print(freq);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
scan_start_time = millis();
|
||||
// start spectral scan
|
||||
radio.spectralScanStart(SAMPLES, 1);
|
||||
// wait for spectral scan to finish
|
||||
while (radio.spectralScanGetStatus() != RADIOLIB_ERR_NONE)
|
||||
{
|
||||
heltec_delay(1);
|
||||
}
|
||||
// read the results Array to which the results will be saved
|
||||
radio.spectralScanGetResult(result);
|
||||
// Filter Elements without neabors
|
||||
bool detected = false;
|
||||
for (y = 1; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
{
|
||||
if (result[y] && (result[y + 1] > 0 || result[y - 1] > 0))
|
||||
{
|
||||
filtered_result[y] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered_result[y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++)
|
||||
{
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.printf("%04X,", result[y]);
|
||||
#endif
|
||||
if (result[y] || y == drone_detection_level)
|
||||
{
|
||||
// check if we shuld alarm the dron
|
||||
if (filtered_result[y] == 1 && y <= drone_detection_level)
|
||||
{
|
||||
drone_detected = true;
|
||||
if (single_page_scan)
|
||||
{
|
||||
// Drone detection true for waterfall
|
||||
waterfall[i][x][w] = true;
|
||||
display.setColor(WHITE);
|
||||
display.setPixel(x, w);
|
||||
}
|
||||
|
||||
if (drone_detected_freqancy_start == 0)
|
||||
{
|
||||
drone_detected_freqancy_start = freq;
|
||||
}
|
||||
drone_detected_freqancy_end = freq;
|
||||
led_flag = true;
|
||||
// if level to sensetive doing beep every 10th freaqancy and shorter
|
||||
if (drone_detection_level < 25)
|
||||
{
|
||||
if (detection_count % 3 == 0)
|
||||
tone(BUZZZER_PIN, 205, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (detection_count % 10 == 0)
|
||||
tone(BUZZZER_PIN, 205, 5);
|
||||
}
|
||||
|
||||
// TODO: make detection waterfall
|
||||
display.setPixel(x, 1);
|
||||
display.setPixel(x, 2);
|
||||
display.setPixel(x, 3);
|
||||
display.setPixel(x, 4);
|
||||
}
|
||||
else if (filtered_result[y] == 1 && y > drone_detection_level && single_page_scan && waterfall[i][x][w] != true)
|
||||
{
|
||||
// if drone not found dark pixel on waterfall
|
||||
waterfall[i][x][w] = false;
|
||||
display.setColor(BLACK);
|
||||
display.setPixel(x, w);
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
|
||||
if (filtered_result[y] == 1)
|
||||
{
|
||||
// Set signal level pixel
|
||||
display.setPixel(x, y);
|
||||
detected = true;
|
||||
}
|
||||
|
||||
// Draw detection Level line
|
||||
if (y == drone_detection_level && x % 2 == 0)
|
||||
{
|
||||
display.setPixel(x, y);
|
||||
}
|
||||
}
|
||||
if (detected)
|
||||
{
|
||||
detection_count++;
|
||||
detected = false;
|
||||
}
|
||||
}
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.println();
|
||||
#endif
|
||||
if (first_run || ANIMATED_RELOAD)
|
||||
{
|
||||
display.display();
|
||||
}
|
||||
|
||||
// Detection level button short press
|
||||
if (button.pressedFor(100))
|
||||
{
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
// erase old value
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(128 - 13, 0, 13, 13);
|
||||
display.setColor(WHITE);
|
||||
drone_detection_level++;
|
||||
// print new value
|
||||
display.drawString(128, 0, String(drone_detection_level));
|
||||
tone(BUZZZER_PIN, 104, 150);
|
||||
if (drone_detection_level > 30)
|
||||
{
|
||||
drone_detection_level = 1;
|
||||
}
|
||||
}
|
||||
// wait a little bit before the next scan, otherwise the SX1262 hangs
|
||||
heltec_delay(1);
|
||||
|
||||
#ifdef PRINT_PROFILE_TIME
|
||||
scan_time = millis() - scan_start_time;
|
||||
Serial.printf("Single Scan took %lld ms\n", scan_time);
|
||||
scan_time = millis() - scan_start_time;
|
||||
Serial.printf("Single Scan took %lld ms\n", scan_time);
|
||||
#endif
|
||||
|
||||
}
|
||||
w++;
|
||||
if (w > STATUS_TEXT_TOP + 1)
|
||||
{
|
||||
w = WATERFALL_START;
|
||||
}
|
||||
display.display();
|
||||
}
|
||||
|
||||
#ifdef PRINT_SCAN_VALUES
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user