#ifndef BLINK_APP_H #define BLINK_APP_H #include /* * BlinkApp -- Testable blink logic, decoupled from hardware. * * Blinks an LED and reads a button. When the button is pressed, * the blink rate doubles (toggles between normal and fast mode). * * All hardware access goes through the injected Hal pointer. This * class has no dependency on Arduino.h and compiles on any host. */ class BlinkApp { public: static constexpr uint8_t DEFAULT_LED_PIN = LED_BUILTIN; // pin 13 static constexpr uint8_t DEFAULT_BUTTON_PIN = 2; static constexpr unsigned long SLOW_INTERVAL_MS = 500; static constexpr unsigned long FAST_INTERVAL_MS = 125; BlinkApp(Hal* hal, uint8_t led_pin = DEFAULT_LED_PIN, uint8_t button_pin = DEFAULT_BUTTON_PIN) : hal_(hal) , led_pin_(led_pin) , button_pin_(button_pin) , led_state_(LOW) , fast_mode_(false) , last_toggle_ms_(0) , last_button_state_(HIGH) // pulled up, so HIGH = not pressed {} // Call once from setup() void begin() { hal_->pinMode(led_pin_, OUTPUT); hal_->pinMode(button_pin_, INPUT_PULLUP); hal_->serialBegin(115200); hal_->serialPrintln("BlinkApp started"); last_toggle_ms_ = hal_->millis(); } // Call repeatedly from loop() void update() { handleButton(); handleBlink(); } // -- Accessors for testing ---------------------------------------------- bool ledState() const { return led_state_ == HIGH; } bool fastMode() const { return fast_mode_; } unsigned long interval() const { return fast_mode_ ? FAST_INTERVAL_MS : SLOW_INTERVAL_MS; } private: void handleButton() { uint8_t reading = hal_->digitalRead(button_pin_); // Detect falling edge (HIGH -> LOW = button press with INPUT_PULLUP) if (last_button_state_ == HIGH && reading == LOW) { fast_mode_ = !fast_mode_; hal_->serialPrintln(fast_mode_ ? "FAST" : "SLOW"); } last_button_state_ = reading; } void handleBlink() { unsigned long now = hal_->millis(); unsigned long target = fast_mode_ ? FAST_INTERVAL_MS : SLOW_INTERVAL_MS; if (now - last_toggle_ms_ >= target) { led_state_ = (led_state_ == HIGH) ? LOW : HIGH; hal_->digitalWrite(led_pin_, led_state_); last_toggle_ms_ = now; } } Hal* hal_; uint8_t led_pin_; uint8_t button_pin_; uint8_t led_state_; bool fast_mode_; unsigned long last_toggle_ms_; uint8_t last_button_state_; }; #endif // BLINK_APP_H