mirror of
https://github.com/Genaker/LoraSA.git
synced 2026-03-28 17:42:59 +01:00
Merge branches 'main' and 'feature/add-sx1280PA' of https://github.com/Genaker/LoraSA into feature/add-sx1280PA
This commit is contained in:
102
README.md
102
README.md
@@ -1,5 +1,15 @@
|
||||
# Lora SA(Spectrum Analyzer)
|
||||
|
||||
# Supportted boards:
|
||||
- Heltec Lora V3 128 x 64 OLED
|
||||
- Heltec Wireless Stick V3 64 x 32 (Not tested)
|
||||
- Heltec Wireless Stick Lite V3 No Display (Not Tested)
|
||||
- Heltec Vision Master E290 - e-Ink 296 x 128 (No OSD)
|
||||
- Heltec Vision MAster T190 - color TFT 320X170 (No OSD)
|
||||
- LilyGo Radio Lora T3S3 V.2 SX1262
|
||||
- LilyGo Radio Lora T3S3 V.2 SX1280
|
||||
- LilyGo Radio Lora T3_V1.6.1 SX1276 (Not Tested)
|
||||
|
||||
## RF Spectrum Analyzer using Lora Radio
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/4caeb467-1964-4184-ab20-ba68b97144aa" alt="LORA hardware" width="200"/>
|
||||
@@ -213,3 +223,95 @@ or buy :
|
||||
|
||||

|
||||
We are using pin 41 as a Buzzer trigger. Connect buzzer + leg with pin 41 and - leg with the ground (GND). You can change the buzzer pin in the code.
|
||||
|
||||
|
||||
## Analog FPV OSD (ON SCREEN DISPLAY)
|
||||
To Enable OSD, Uncomment these lines </br>
|
||||
```
|
||||
// #define OSD_ENABLED true
|
||||
```
|
||||
**OSD sidebar enabled/disable**
|
||||
comment or uncomment this line
|
||||
```
|
||||
#define OSD_SIDE_BAR true
|
||||
```
|
||||
|
||||
Or you can set this and other variables as a build parameter:
|
||||
```
|
||||
build_flags =
|
||||
-DOSD_ENABLED
|
||||
```
|
||||
|
||||
## DFRobot OSD Wiring
|
||||
**Heltec V3 -> DFRobot OSD** <br />
|
||||
GND -> GND <br />
|
||||
3V3 -> 3V3 <br />
|
||||
26 -> SCK <br />
|
||||
34 ->MOSI <br />
|
||||
33 ->MISO <br />
|
||||
47 -> D3 <br />
|
||||
|
||||
More photos you can see there: <br />
|
||||
https://github.com/Genaker/LoraSA/issues/11
|
||||
|
||||

|
||||
|
||||
# Camera to DF robot Wiring
|
||||
**Camera -> DFRobotOSD** <br />
|
||||
Video out -> In <br />
|
||||
GND -> GND <br />
|
||||
3v3 -> 3V3 Heltec or some 3v on FPV <br />
|
||||
|
||||
# DFRobot to Drone or VTX(video transmitter)
|
||||
**DF Robot -> VTX or** <br />
|
||||
Video Out - Video IN <br />
|
||||
|
||||
```
|
||||
// SPI pins
|
||||
#define OSD_CS 47
|
||||
#define OSD_MISO 33
|
||||
#define OSD_MOSI 34
|
||||
#define OSD_SCK 26
|
||||
```
|
||||
|
||||
## Joystick Wiring
|
||||
https://www.aliexpress.us/item/2251832815289133.html
|
||||
https://www.amazon.com/dp/B00P7QBGD2
|
||||
|
||||
**Loystic -> Heltec V3** <br />
|
||||
SW -> 46 <br />
|
||||
VRX -> 19 <br />
|
||||
VRY -> X has not been implemented yet <br />
|
||||
+5v -> 5V <br />
|
||||
GND -> GND <br />
|
||||
|
||||
## Buzzer/Beeper Wiring
|
||||
TMB12A03 - in my case. Low voltage is better. <br />
|
||||
**Buzzer -> Heltec V3** <br />
|
||||
(+) -> 41 <br />
|
||||
GND (another) -> GND <br />
|
||||
|
||||
## Select Board to build
|
||||
Select Visual Code environment:
|
||||

|
||||
|
||||
Edit **paltformio.io** uncommenting/selecting your sources
|
||||
```
|
||||
[platformio]
|
||||
; for env:vision-master-e190
|
||||
; src_dir = tft_src
|
||||
; for env:vision-master-e290
|
||||
; src_dir = eink_src
|
||||
; for env:heltec_wifi_lora_32_V3
|
||||
; src_dir = src ;;Default
|
||||
```
|
||||
for LilyGo use env:heltec_wifi_lora_32_V3
|
||||
|
||||
# WiFi and Bluetooth BT Scanning
|
||||
Works only with OSD enabled <br/>
|
||||
Uncomment this lines
|
||||
```
|
||||
// #define OSD_ENABLED true
|
||||
// #define WIFI_SCANNING_ENABLED true
|
||||
// #define BT_SCANNING_ENABLED true
|
||||
```
|
||||
|
||||
@@ -13,8 +13,67 @@
|
||||
#ifndef _DFRobot_OSD_H_
|
||||
#define _DFRobot_OSD_H_
|
||||
|
||||
#define MAX_POWER_LEVELS 33
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/*Define Custom characters Example*/
|
||||
static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00,
|
||||
0x42, 0x00, 0x7A, 0x40, 0x4A, 0x40, 0x4A, 0x80,
|
||||
0x49, 0x20, 0x5A, 0xA0, 0x44, 0x60, 0x88, 0x20};
|
||||
|
||||
static constexpr uint16_t levels[10] = {
|
||||
0x105, // 0
|
||||
0x10E, // 1
|
||||
0x10D, // 2
|
||||
0x10C, // 3
|
||||
0x10B, // 4
|
||||
0x10A, // 5
|
||||
0x109, // 6
|
||||
0x108, // 7
|
||||
0x107, // 8
|
||||
0x106, // 9
|
||||
};
|
||||
|
||||
static constexpr uint16_t power_level[MAX_POWER_LEVELS + 1] = {
|
||||
0x10E, // 0
|
||||
0x10E, // 1
|
||||
0x10D, // 2
|
||||
0x10C, // 3
|
||||
0x10B, // 4
|
||||
0x10A, // 5
|
||||
0x109, // 6
|
||||
0x108, // 7
|
||||
0x107, // 8
|
||||
0x106, // 9 not using 106 to accent rise
|
||||
// new line
|
||||
0x10E, // 10
|
||||
0x10D, // 11
|
||||
0x10C, // 12
|
||||
0x10B, // 13
|
||||
0x10A, // 14
|
||||
0x109, // 15
|
||||
0x108, // 16
|
||||
0x107, // 17
|
||||
0x106, // 18 not using 106
|
||||
// new line
|
||||
0x10E, // 19
|
||||
0x10D, // 20
|
||||
0x10C, // 21
|
||||
0x10B, // 22
|
||||
0x10A, // 23
|
||||
0x109, // 24
|
||||
0x108, // 25
|
||||
0x107, // 26
|
||||
0x106, // 27
|
||||
0x105, // 28 ---
|
||||
0x105, // 29
|
||||
0x105, // 30
|
||||
0x105, // 31
|
||||
0x105, // 32
|
||||
0x105 // 33
|
||||
};
|
||||
|
||||
// #define ENABLE_DBG //!< Open this macro and you can see the details of the program
|
||||
#ifdef ENABLE_DBG
|
||||
#define DBG(...) \
|
||||
|
||||
69
lib/scan/scan.cpp
Normal file
69
lib/scan/scan.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef LORASA_CORE_CPP
|
||||
#define LORASA_CORE_CPP
|
||||
|
||||
#include "scan.h"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
float Scan::getRSSI() { return 0.1; }
|
||||
|
||||
uint16_t Scan::rssiMethod(uint16_t *result)
|
||||
{
|
||||
memset(result, 0, res_size * sizeof(uint16_t));
|
||||
int result_index = 0;
|
||||
|
||||
//
|
||||
uint16_t max_signal = 65535;
|
||||
// N of samples
|
||||
for (int r = 0; r < SAMPLES_RSSI; r++)
|
||||
{
|
||||
float rssi = getRSSI();
|
||||
if (rssi < -65535)
|
||||
rssi = -65535;
|
||||
|
||||
uint16_t abs_rssi = abs(rssi);
|
||||
if (abs_rssi < max_signal)
|
||||
{
|
||||
max_signal = abs_rssi;
|
||||
}
|
||||
// ToDO: check if 4 is correct value for 33 power bins
|
||||
// Now we have more space because we are ignoring low dB values
|
||||
// we can / 3 default 4
|
||||
if (RSSI_OUTPUT_FORMULA == 1)
|
||||
{
|
||||
result_index =
|
||||
/// still not clear formula but it works
|
||||
uint8_t(abs(rssi) / 4);
|
||||
}
|
||||
else if (RSSI_OUTPUT_FORMULA == 2)
|
||||
{
|
||||
if (rssi > HI_RSSI_THRESHOLD)
|
||||
{
|
||||
rssi = HI_RSSI_THRESHOLD;
|
||||
}
|
||||
else if (rssi < LO_RSSI_THRESHOLD)
|
||||
{
|
||||
rssi = LO_RSSI_THRESHOLD;
|
||||
}
|
||||
|
||||
result_index = uint8_t((HI_RSSI_THRESHOLD - rssi) * scale);
|
||||
}
|
||||
|
||||
if (result_index >= res_size)
|
||||
{
|
||||
// Maximum index possible
|
||||
result_index = res_size - 1;
|
||||
}
|
||||
|
||||
LOG("RSSI: %f IDX: %d\n", rssi, result_index);
|
||||
if (result[result_index] == 0 || result[result_index] > abs_rssi)
|
||||
{
|
||||
result[result_index] = abs_rssi;
|
||||
}
|
||||
}
|
||||
|
||||
return max_signal;
|
||||
}
|
||||
|
||||
#endif
|
||||
46
lib/scan/scan.h
Normal file
46
lib/scan/scan.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <cstdint>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef LORASA_CORE_H
|
||||
|
||||
#define LORASA_CORE_H
|
||||
|
||||
#ifdef PRINT_DEBUG
|
||||
#define LOG(args...) Serial.printf(args...)
|
||||
#define LOG_IF(cond, args...) \
|
||||
if (cond) \
|
||||
LOG(args...)
|
||||
#elif !defined(LOG)
|
||||
#define LOG(args...)
|
||||
#define LOG_IF(cond, args...)
|
||||
#endif
|
||||
|
||||
// Output Pixel Formula
|
||||
// 1 = rssi / 4, 2 = (rssi / 2) - 22 or 20
|
||||
constexpr int RSSI_OUTPUT_FORMULA = 2;
|
||||
|
||||
// based on the formula for RSSI_OUTPUT_FORMULA == 2
|
||||
// -2 * (22 + RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE) < rssi =< -44
|
||||
// practice may require a better pair of thresholds
|
||||
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 //
|
||||
|
||||
struct Scan
|
||||
{
|
||||
Scan(int sz)
|
||||
: res_size(sz), scale((float)sz / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1))
|
||||
{
|
||||
}
|
||||
|
||||
virtual float getRSSI();
|
||||
|
||||
uint16_t rssiMethod(uint16_t *result);
|
||||
|
||||
int res_size;
|
||||
float scale;
|
||||
};
|
||||
|
||||
#endif
|
||||
4
ml_research/Diagram_ML.svg
Normal file
4
ml_research/Diagram_ML.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
13
ml_research/datasets.md
Normal file
13
ml_research/datasets.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## Overview of ML Dataets
|
||||
|
||||
| dataset name | data content | data format | frequencies / Sampling rate | other infos | source paper/website | source data | open questions |
|
||||
|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
|
||||
| Noisy Drone RF Signal Classification (Glüge et al.) | Drones: DJI, FutabaT14, FutabaT7, Graupner, Taranis, Turnigy | I/Q Data as well as generated Spectrograms available | The device can scan a range of 6Ghz. But the newest plot is very weird. +/- 7 Mhz, can this really be? "non-overlapping signal vectors of length of 1048576 samples, which corresponds to approx. 74.9ms at 14MHz" | mixed with either Labnoise (50%) or Gaussian noise (50%). The noise class was created by mixing Labnoise and Gaussian noise in all possible combinations. Several levels of SNR were used over the entire dataset. | https://www.scitepress.org/Link.aspx?doi=10.5220/0012176800003595 https://github.com/sgluege/Noisy-Drone-RF-Signal-Classification https://github.com/sgluege/Noisy-Drone-RF-Signal-Classification-v2/tree/main | https://www.kaggle.com/datasets/sgluege/noisy-drone-rf-signal-classification-v2/data https://www.kaggle.com/datasets/sgluege/noisy-drone-rf-signal-classification | Not sure about the frequencies. |
|
||||
| DroneDataset (Swinney and Woods) | Drones: new DJI Mavic 2 Air S, DJI Mavic Pro, DJI Mavic Pro 2, DJI Inspire 2, DJI Mavic Mini, DJI Phantom 4 and the Parrot Disco. | Raw I/Q Data | TODO; Recordings were collected using a Nuand BladeRF SDR and using open source software GNURadio | There are 4 subsets of data included in this dataset, the UAS signals in the presence of Bluetooth interference, in the presence of Wi-Fi signals, in the presence of both and with no interference. 3 flight modes are captured - switched on, hovering and flying. | No paper seen | https://ieee-dataport.org/open-access/dronedetect-dataset-radio-frequency-dataset-unmanned-aerial-system-uas-signals-machine | Sampling rate? |
|
||||
| DroneRF (Allahham et al.) | Drones: Bepop; AR; Phantom | "the dataset contains only time series data, and not the complex IQ signals" (From Glüge and not from the authors) - but what does this exactly mean? | capture the whole 2.4GHz bandwidth, we have used 2 RF receivers. Each RF receiver has a maximum instantaneous bandwidth of 40 MHz, so both receivers must be operating simultaneously to at least capture a technology spectrum such as WiFi (i.e. 80 MHz). Recorded using universal soft- ware radio peripheral (USRP) software-defined radio (SDR) transceivers. Signals that could be considered noise in the 2.4 GHz band (Bluetooth, Wi-Fi) were not recorded. | modes, including off, on and connected, hovering, flying, and video recording. | https://www.sciencedirect.com/science/article/pii/S2352340919306675?ref=pdf_download&fr=RR-2&rr=8bf5de727fa35d7f | https://data.mendeley.com/datasets/f4c2b4n755/1 | Apparently time versus db? Not very clear what is in the data |
|
||||
| Radio-Frequency Control and Video Signal Recordings of Drones (Vuorenmaa et al.) | Drones: DJI Inspire 2 (2.44 and 5.8 GHz), DJI Matrice 100 (2.44 GHz), DJI Matrice 210 (2.44 and 5.8 GHz), DJI Mavic Mini (2.44 GHz), DJI Mavic Pro (2.44 GHz), DJI Phantom 4 (2.44 GHz), DJI Phantom 4 Pro Plus (2.44 and 5.8 GHz), Parrot Disco (2.44 GHz), Parrot Mambo (2.44 GHz), Yuneec Typhoon H (2.44 and 5.7 GHz) | I/Q Data (And Video data) | TODO: not clear yet | | https://zenodo.org/records/4264467 | | |
|
||||
| Spectrogram Dataset (Wicht et al.) | Wi-Fi and Bluetooth signals (NOT DRONES) | Sepctrograms | | | https://www.mdpi.com/2306-5729/7/12/168 | | |
|
||||
|
||||
|
||||
## Current Proposal for ML
|
||||

|
||||
@@ -9,6 +9,7 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
default_envs = heltec_wifi_lora_32_V3
|
||||
; for env:vision-master-e190
|
||||
; src_dir = tft_src
|
||||
; for env:vision-master-e290
|
||||
|
||||
65
src/main.cpp
65
src/main.cpp
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// #define OSD_ENABLED true
|
||||
#define OSD_ENABLED true
|
||||
// #define WIFI_SCANNING_ENABLED true
|
||||
// #define BT_SCANNING_ENABLED true
|
||||
|
||||
@@ -71,58 +71,6 @@ uint64_t bt_start = 0;
|
||||
#include "DFRobot_OSD.h"
|
||||
#define OSD_SIDE_BAR true
|
||||
|
||||
static constexpr uint16_t levels[10] = {
|
||||
0x105, // 0
|
||||
0x10E, // 1
|
||||
0x10D, // 2
|
||||
0x10C, // 3
|
||||
0x10B, // 4
|
||||
0x10A, // 5
|
||||
0x109, // 6
|
||||
0x108, // 7
|
||||
0x107, // 8
|
||||
0x106, // 9
|
||||
};
|
||||
|
||||
static constexpr uint16_t power_level[MAX_POWER_LEVELS + 1] = {
|
||||
0x10E, // 0
|
||||
0x10E, // 1
|
||||
0x10D, // 2
|
||||
0x10C, // 3
|
||||
0x10B, // 4
|
||||
0x10A, // 5
|
||||
0x109, // 6
|
||||
0x108, // 7
|
||||
0x107, // 8
|
||||
0x106, // 9 not using 106 to accent rise
|
||||
// new line
|
||||
0x10E, // 10
|
||||
0x10D, // 11
|
||||
0x10C, // 12
|
||||
0x10B, // 13
|
||||
0x10A, // 14
|
||||
0x109, // 15
|
||||
0x108, // 16
|
||||
0x107, // 17
|
||||
0x106, // 18 not using 106
|
||||
// new line
|
||||
0x10E, // 19
|
||||
0x10D, // 20
|
||||
0x10C, // 21
|
||||
0x10B, // 22
|
||||
0x10A, // 23
|
||||
0x109, // 24
|
||||
0x108, // 25
|
||||
0x107, // 26
|
||||
0x106, // 27
|
||||
0x105, // 28 ---
|
||||
0x105, // 29
|
||||
0x105, // 30
|
||||
0x105, // 31
|
||||
0x105, // 32
|
||||
0x105 // 33
|
||||
};
|
||||
|
||||
// SPI pins
|
||||
#define OSD_CS 47
|
||||
#define OSD_MISO 33
|
||||
@@ -147,11 +95,6 @@ int global_counter = 0;
|
||||
DFRobot_OSD osd(OSD_CS);
|
||||
#endif
|
||||
|
||||
/*Define Custom characters Example*/
|
||||
static const int buf0[36] = {0x02, 0x80, 0x02, 0x40, 0x7F, 0xE0, 0x42, 0x00,
|
||||
0x42, 0x00, 0x7A, 0x40, 0x4A, 0x40, 0x4A, 0x80,
|
||||
0x49, 0x20, 0x5A, 0xA0, 0x44, 0x60, 0x88, 0x20};
|
||||
|
||||
#include "global_config.h"
|
||||
#include "ui.h"
|
||||
|
||||
@@ -212,8 +155,6 @@ constexpr int WINDOW_SIZE = 15;
|
||||
// Number of samples for each frequency scan. Fewer samples = better temporal resolution.
|
||||
// if more than 100 it can freeze
|
||||
#define SAMPLES 35 //(scan time = 1294)
|
||||
// number of samples for RSSI method
|
||||
#define SAMPLES_RSSI 12 // 21 //
|
||||
|
||||
#define RANGE (int)(FREQ_END - FREQ_BEGIN)
|
||||
|
||||
@@ -232,6 +173,7 @@ uint64_t median_frequency = FREQ_BEGIN + FREQ_END - FREQ_BEGIN / 2;
|
||||
|
||||
// Array to store the scan results
|
||||
uint16_t result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
|
||||
uint16_t result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
|
||||
|
||||
bool filtered_result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
|
||||
|
||||
@@ -831,6 +773,8 @@ int max_rssi_x = 999;
|
||||
|
||||
RadioScan r;
|
||||
|
||||
RadioScan r;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
UI_displayDecorate(0, 0, false); // some default values
|
||||
@@ -919,6 +863,7 @@ void loop(void)
|
||||
|
||||
// horizontal (x axis) Frequency loop
|
||||
osd_x = 1, osd_y = 2, col = 0, max_bin = 0;
|
||||
int radio_error_count = 0;
|
||||
// x loop
|
||||
for (x = 0; x < STEPS * SCAN_RBW_FACTOR; x++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user