Public Access
Debug Builds: `lora noise test` changes one thing at a time, Sweeps the band, and reports the floor under each condition; it runs on the device by itself, since one condition pauses Wi-Fi (not saved, so a restart brings it back). Result, at 125 kHz: -117 dBm with the antenna switched off, -106 with the GNSS receiver in standby, -98 with it running. The receiver's serial line isn't it (one sentence a second changes nothing), and neither are the main loop, the CPU frequency, Wi-Fi, the screen or the radio's own regulator, all within 1 dB. Settings > "Pause GNSS for LoRa", off by default: the receiver waits in standby while the radio listens or sweeps, except during a Track, and has a Fix again about 7 s after. The GNSS App says it's paused. 11 dB remain between the antenna with GNSS quiet and the chip alone, untouched by anything that can be switched from the firmware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
60 lines
1.8 KiB
C++
60 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#ifdef RORO_DEBUG
|
|
|
|
#include <Print.h>
|
|
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "services/radio_service.h"
|
|
|
|
namespace roro {
|
|
|
|
// `lora noise test` (Debug Builds, issue #20): which part of the Cardputer raises the radio's
|
|
// noise floor? Applies one condition at a time, Sweeps the band a few passes, records the floor
|
|
// and the steady peaks, and puts things back. It runs from the main loop on its own, because one
|
|
// condition switches Wi-Fi off, and prints its report once the console can be reached again.
|
|
class NoiseTest {
|
|
public:
|
|
struct Condition {
|
|
std::string name;
|
|
std::function<void()> apply, restore; // either may be empty
|
|
uint32_t settleMs = 1500;
|
|
};
|
|
|
|
explicit NoiseTest(RadioService& radio) : radio_(radio) {}
|
|
void start(std::vector<Condition> conditions, int passes = 8);
|
|
void step(uint32_t nowMs); // from the main loop
|
|
bool running() const { return phase_ != Phase::Idle; }
|
|
void printReport(Print& out) const;
|
|
|
|
private:
|
|
enum class Phase { Idle, Settle, Sweep };
|
|
struct Result {
|
|
std::string name;
|
|
int floor = 0, top = 0;
|
|
std::string peaks; // steady ones: the lowest reading at each step over the passes
|
|
};
|
|
void begin(uint32_t nowMs);
|
|
void finish();
|
|
|
|
RadioService& radio_;
|
|
std::vector<Condition> conditions_;
|
|
std::vector<Result> results_;
|
|
size_t index_ = 0;
|
|
int passes_ = 8, seen_ = 0;
|
|
Phase phase_ = Phase::Idle;
|
|
uint32_t phaseMs_ = 0, lastSeq_ = 0;
|
|
int8_t lowest_[SweepFrame::kMaxSteps];
|
|
uint16_t counts_[128]; // how often each level (in -dBm) was read: for the median
|
|
uint32_t fromHz_ = 0, stepHz_ = 0;
|
|
uint16_t steps_ = 0;
|
|
std::vector<std::string> report_;
|
|
};
|
|
|
|
} // namespace roro
|
|
|
|
#endif // RORO_DEBUG
|