From 655e8caf42b6959062de178a8d6fdba1593e79d9 Mon Sep 17 00:00:00 2001 From: Egor Shitikov Date: Sun, 22 Sep 2024 13:59:13 -0700 Subject: [PATCH] merge SX1280 with new ScanRSSI method logic --- include/LiLyGo.h | 38 ------------- platformio.ini | 3 ++ src/main.cpp | 103 ++++++++++++------------------------ src/radioScan/radioScan.cpp | 69 ++++++++++++++++++++++++ src/radioScan/radioScan.h | 40 ++++++++++++++ test/test_rssi.cpp | 57 ++++++++++++++++++++ 6 files changed, 204 insertions(+), 106 deletions(-) create mode 100644 src/radioScan/radioScan.cpp create mode 100644 src/radioScan/radioScan.h create mode 100644 test/test_rssi.cpp diff --git a/include/LiLyGo.h b/include/LiLyGo.h index 37e02f0..3c0c262 100644 --- a/include/LiLyGo.h +++ b/include/LiLyGo.h @@ -1,42 +1,4 @@ -#define UNUSED_PIN (0) -// LilyGo defined - -// Check this LiLyGo file LoraSA2\include\utilities.h - -#define I2C_SDA 18 -#define I2C_SCL 17 -#define OLED_RST UNUSED_PIN - -#define RADIO_SCLK_PIN 5 -#define RADIO_MISO_PIN 3 -#define RADIO_MOSI_PIN 6 -#define RADIO_CS_PIN 7 - -#define SDCARD_MOSI 11 -#define SDCARD_MISO 2 -#define SDCARD_SCLK 14 -#define SDCARD_CS 13 - -#define BOARD_LED 37 -#define LED_ON HIGH - -#define BUTTON_PIN 0 -#define ADC_PIN 1 - -#define RADIO_RST_PIN 8 - -#define RADIO_DIO1_PIN 33 -#define RADIO_BUSY_PIN 34 - -#ifdef USING_SX1280PA -#define RADIO_DIO1_PIN 9 // SX1280 DIO1 = IO9 -#define RADIO_BUSY_PIN 36 // SX1280 BUSY = IO36 -#define RADIO_RX_PIN 21 -#define RADIO_TX_PIN 10 -#define BUTTON_PIN 0 -#endif - // Define for our code #define RST_OLED UNUSED_PIN #define LED BOARD_LED diff --git a/platformio.ini b/platformio.ini index e2a476a..4e79c64 100644 --- a/platformio.ini +++ b/platformio.ini @@ -151,3 +151,6 @@ 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 + +[env:native] +platform = native diff --git a/src/main.cpp b/src/main.cpp index 1881d14..f83e37b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,9 @@ // 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 // This file contains a binary patch for the SX1262 @@ -162,13 +165,15 @@ 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; +// constexpr int RSSI_OUTPUT_FORMULA = 2; // Feature to scan diapasones. Other frequency settings will be ignored. // int SCAN_RANGES[] = {850890, 920950}; @@ -226,7 +231,7 @@ uint64_t median_frequency = FREQ_BEGIN + FREQ_END - FREQ_BEGIN / 2; // #define DISABLE_PLOT_CHART false // unused // Array to store the scan results -int16_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]; @@ -410,7 +415,7 @@ void init_radio() // initialize SX1262 FSK modem at the initial frequency both.println("Init radio"); #ifdef USING_SX1280PA - radio.begin(); + // radio.begin(); state = radio.beginGFSK(FREQ_BEGIN); #else state = radio.beginFSK(FREQ_BEGIN); @@ -801,9 +806,31 @@ void check_ranges() single_page_scan = false; } } + +struct RadioScan : Scan +{ + float getRSSI() override; +}; + +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; +RadioScan r; + void loop(void) { UI_displayDecorate(0, 0, false); // some default values @@ -972,72 +999,12 @@ void loop(void) #ifdef METHOD_RSSI // Spectrum analyzer using getRSSI { -#ifdef PRINT_DEBUG - Serial.println("METHOD RSSI"); -#endif - // memset - // memset(result, 0, RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE); - // Some issues with memset function - for (i = 0; i < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; i++) + LOG("METHOD RSSI"); + uint16_t max_rssi = r.rssiMethod(SAMPLES_RSSI, result, + RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE); + if (max_x_rssi[display_x] > max_rssi) { - result[i] = 0; - } - result_index = 0; - // N of samples - for (int r = 0; r < SAMPLES_RSSI; r++) - { -#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); - rssi = ((float)data[0] / (-2.0)); -#else - rssi = radio.getRSSI(false); -#endif - int abs_rssi = 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) - { - // I like this formula better - result_index = uint8_t(abs_rssi / 2) - 22; - } - if (result_index >= RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE) - { - // Maximum index possible - result_index = RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE - 1; - } - -#ifdef PRINT_DEBUG - Serial.printf("RSSI: %d IDX: %d\n", rssi, result_index); -#endif - // avoid buffer overflow - if (result_index < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE) - { - // Saving max ABS value of RSSI. dB is negative, so smaller - // absolute value represents stronger signal. - if (result[result_index] == 0 || result[result_index] > abs_rssi) - { - result[result_index] = abs_rssi; - } - if (max_x_rssi[display_x] > abs_rssi) - { - max_x_rssi[display_x] = abs_rssi; - } - } - else - { - Serial.print("Out-of-Range: result_index %d\n"); - } + max_x_rssi[display_x] = max_rssi; } } #endif // SCAN_METHOD == METHOD_RSSI diff --git a/src/radioScan/radioScan.cpp b/src/radioScan/radioScan.cpp new file mode 100644 index 0000000..73150fc --- /dev/null +++ b/src/radioScan/radioScan.cpp @@ -0,0 +1,69 @@ +#ifndef LORASA_CORE_CPP +#define LORASA_CORE_CPP + +#include "radioScan.h" +#include +#include +#include + +uint16_t Scan::rssiMethod(size_t samples, uint16_t *result, size_t res_size) +{ + float scale((float)res_size / (HI_RSSI_THRESHOLD - LO_RSSI_THRESHOLD + 0.1)); + + 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; 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 diff --git a/src/radioScan/radioScan.h b/src/radioScan/radioScan.h new file mode 100644 index 0000000..1c8ca8e --- /dev/null +++ b/src/radioScan/radioScan.h @@ -0,0 +1,40 @@ +#include +#include + +#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 +{ + virtual float getRSSI() = 0; + + // rssiMethod gets the data similar to the scan method, + // but uses getRSSI directly. + uint16_t rssiMethod(size_t samples, uint16_t *result, size_t res_size); +}; + +#endif diff --git a/test/test_rssi.cpp b/test/test_rssi.cpp new file mode 100644 index 0000000..0215179 --- /dev/null +++ b/test/test_rssi.cpp @@ -0,0 +1,57 @@ +#include +#define LOG(args...) printf(args) +#include "../src/radioScan/radioScan.cpp" +#include + +void setUp(void) {} + +void tearDown(void) {} + +struct TestScan : Scan +{ + TestScan(float *ctx, int sz) : ctx(ctx), sz(sz), idx(0) {} + + float getRSSI() override; + + float *ctx; + int sz; + int idx; +}; + +float TestScan::getRSSI() +{ + if (idx >= sz) + { + return -1000000; + } + + return ctx[idx++]; +} + +constexpr int test_sz = 13; +constexpr int inputs_sz = 13; + +void test_rssi(void) +{ + uint16_t samples[test_sz]; + float inputs[inputs_sz] = {-40.0, -100.0, -200.0, -50.0, -400.0, -60.0, -20, + -75.5, -70, -80, -90, -55.9, -110}; + + TestScan t = TestScan(inputs, inputs_sz); + + uint16_t r = t.rssiMethod(inputs_sz, samples, test_sz); + + uint16_t expect[test_sz] = {20, 50, 55, 60, 0, 70, 75, 80, 0, 90, 0, 100, 110}; + + TEST_ASSERT_EQUAL_INT16(20, r); + TEST_ASSERT_EQUAL_INT16_ARRAY(expect, samples, test_sz); +} + +int main(int argc, char **argv) +{ + UNITY_BEGIN(); + + RUN_TEST(test_rssi); + + UNITY_END(); +}