#pragma once #ifdef RORO_DEBUG #include #include #include #include #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 apply, restore; // either may be empty uint32_t settleMs = 1500; }; explicit NoiseTest(RadioService& radio) : radio_(radio) {} void start(std::vector 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 conditions_; std::vector 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 report_; }; } // namespace roro #endif // RORO_DEBUG