Testable RSSI method

This commit is contained in:
Sassa NF
2024-09-19 19:51:43 +01:00
parent 9ea009ff47
commit 7b1e8599b9
5 changed files with 181 additions and 68 deletions
+3
View File
@@ -127,3 +127,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
+57
View File
@@ -0,0 +1,57 @@
#ifndef LORASA_CORE_CPP
#define LORASA_CORE_CPP
#include "core.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();
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)
{
// I like this formula better
result_index = uint8_t(abs(rssi) / 2) - 22;
}
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
+45
View File
@@ -0,0 +1,45 @@
#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)
{
}
virtual float getRSSI();
uint16_t rssiMethod(uint16_t *result);
int res_size;
};
#endif
+20 -68
View File
@@ -29,6 +29,8 @@
// #define WIFI_SCANNING_ENABLED true
// #define BT_SCANNING_ENABLED true
#include "core.h"
#ifndef LILYGO
#include <heltec_unofficial.h>
// This file contains a binary patch for the SX1262
@@ -160,10 +162,6 @@ typedef enum
// #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[] = {};
@@ -201,8 +199,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)
@@ -220,7 +216,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];
@@ -763,9 +759,21 @@ void check_ranges()
single_page_scan = false;
}
}
struct RadioScan : Scan
{
RadioScan() : Scan(RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE) {}
float getRSSI() override;
};
float RadioScan::getRSSI() { return radio.getRSSI(false); }
// 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
@@ -854,6 +862,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++)
{
@@ -882,12 +891,7 @@ void loop(void)
Serial.println("setFrequency:" + String(freq));
#endif
#ifdef LILYGO
state = radio.setFrequency(freq, false); // false = no calibration need here
#else
state = radio.setFrequency(freq, false); // false = no calibration need here
#endif
int radio_error_count = 0;
if (state != RADIOLIB_ERR_NONE)
{
display.drawString(0, 64 - 10, "E:setFrequency:" + String(freq));
@@ -933,63 +937,11 @@ 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(result);
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++)
{
rssi = radio.getRSSI(false);
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
+56
View File
@@ -0,0 +1,56 @@
#include <stdio.h>
#define LOG(args...) printf(args)
#include "../src/core.cpp"
#include <unity.h>
void setUp(void) {}
void tearDown(void) {}
struct TestScan : Scan
{
TestScan(float *ctx, int sz) : Scan(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;
void test_rssi(void)
{
uint16_t samples[test_sz];
float inputs[] = {-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, test_sz);
uint16_t r = t.rssiMethod(samples);
uint16_t expect[test_sz] = {20, 50, 55, 60, 0, 70, 75, 80, 0, 90, 0, 100, 200};
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();
}