#pragma once #include "Buttons.h" #include "Display.h" #include "Measurement.h" #include "Pwm.h" #include "Radio.h" #include "SettingsStore.h" enum class AppState : uint8_t { IDLE, MENU, SOLO_MEASURE, MASTER_DISCOVER, MASTER_WAIT_READY, MASTER_WAIT_RESULT, MASTER_FINALIZE, SLAVE_READY, SLAVE_WAIT_START, SLAVE_MEASURE, SLAVE_WAIT_ACK, FINISHED }; class App { public: App(); void begin(); void update(); private: void showIdle(); void finishInitialization(bool factoryReset); void showMenu(); void changeMenu(int direction); void sanitizeRange(); void startTest(); bool armSlave(bool preserveDisplay = false); bool prepareStage(bool showProgress = true); bool startLocalMeasurement(float hz, float duty); void startMasterDiscovery(); void handleRadio(); void updateMaster(); void updateSlave(); void stagePassed(); void finish(bool pass, FailReason reason, bool preserveDisplay = false); void abortTest(); void sendAbort(FailReason reason = FailReason::ABORTED); void printConfiguration(); void printStageStats(const StageStats &s, uint32_t hz); void showStageResult(const StageStats &s); void showRemoteResult(const ProtocolPacket &packet); void fillMeasuredResult(ProtocolPacket &packet, const StageStats &stats) const; void showStageProgress(); uint64_t actualNominalTotalUs(); ProtocolPacket makePacket(MessageType type) const; bool sendLinked(ProtocolPacket packet); void sendCurrent(MessageType type); void updateHeartbeat(); bool packetForCurrent(const ProtocolPacket &p) const; void serviceIdlePowerSave(); void serviceRxPinStateLog(); void leaveIdlePowerSave(bool wakeDisplay = true); bool idlePowerSaveAllowed() const; void setStandbyOpticalOutput(); void setActivePerformance(bool active); Button startButton_, modeButton_; Display display_; SettingsStore store_; Settings settings_ = {}; TestParams params_ = {}; PwmGenerator pwm_; PulseReceiver receiver_; Measurement measurement_; Radio radio_; AppState state_ = AppState::IDLE; uint8_t menuItem_ = 0; uint32_t stageIndex_ = 0, stageCount_ = 0; uint32_t requestedHz_ = 0, requestedPulseNs_ = 0; ActualPwm actual_ = {}; FailReason pendingReason_ = FailReason::NONE; uint32_t session_ = 0; uint16_t sequence_ = 0; uint8_t peer_[6] = {}; bool havePeer_ = false; uint32_t deadlineMs_ = 0, lastSendMs_ = 0; uint32_t localMeasurementDeadlineMs_ = 0; uint32_t lastHeartbeatMs_ = 0, lastPeerSeenMs_ = 0; uint8_t retries_ = 0; ProtocolPacket pendingPacket_ = {}; bool initialized_ = false, bootResetCandidate_ = false; uint32_t bootCheckStartedMs_ = 0; uint32_t slaveRearmAtMs_ = 0; bool stageStartConfirmed_ = false; uint32_t lastUserActivityMs_ = 0; bool idlePowerSave_ = false; bool idleSleepRadioStopped_ = false; uint32_t lastOpticalWakeToggleMs_ = 0; bool opticalWakeActive_ = false; bool rxPinStateKnown_ = false, rxPinState_ = false; };