Files
roro9stack/src/services/noise_test.h
T
twislaandClaude Opus 5.5 70fb37ebb5 The radio's noise: the GNSS receiver costs 8 dB; a setting pauses it (#20)
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
2026-10-06 03:41:15 +02:00

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