#include <Adafruit_NeoPixel.h>
#define NEOPIXEL_PIN 13 // Pin connected to the NeoPixel strip
#define NUM_LEDS 16 // Number of LEDs in the strip
#define BUTTON_PIN 2 // Push button connected to pin 2
#define BUZZER_PIN 12 // Buzzer connected to pin 12
Adafruit_NeoPixel strip(NUM_LEDS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
enum TimerState {STOPPED, RUNNING, PAUSED};
TimerState timerState = STOPPED;
unsigned long lastButtonPressTime = 0;
unsigned long lastUpdateTime = 0; // Track last update time for non-blocking delay
const long debounceTime = 50; // Debounce time for button presses
const int updateInterval = 1000; // Time between updates in milliseconds
int ledIndex = -1; // Initialize outside valid range to indicate not started
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
strip.begin();
strip.show(); // Turn off all pixels initially
fillStripWithColor(strip.Color(255, 0, 255)); // Start with all LEDs as magenta
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
// Button press detection with debounce
if (buttonState == LOW && millis() - lastButtonPressTime > debounceTime) {
lastButtonPressTime = millis();
if (timerState == STOPPED || timerState == PAUSED) {
timerState = RUNNING; // Start or resume the timer
if (ledIndex == -1) {
ledIndex = 0; // Start from the first LED if we were stopped
}
} else if (timerState == RUNNING) {
timerState = PAUSED; // Pause the timer
}
}
// Non-blocking LED update logic
if (timerState == RUNNING && millis() - lastUpdateTime > updateInterval) {
lastUpdateTime = millis();
if (ledIndex < NUM_LEDS) {
updateLEDs();
ledIndex++;
} else {
pulseLastLED(); // When all LEDs have been updated, pulse the last LED
timerState = STOPPED; // Stop the timer cycle after completion
ledIndex = -1; // Reset to indicate we've completed the cycle
}
}
}
void updateLEDs() {
// Calculate which third of the cycle we're in
int third = NUM_LEDS / 3;
if (ledIndex < third) {
fillStripWithColor(strip.Color(0, 255, 0)); // Green
} else if (ledIndex < 2 * third) {
fillStripWithColor(strip.Color(255, 165, 0)); // Orange
} else {
fillStripWithColor(strip.Color(255, 0, 0)); // Red
}
}
void fillStripWithColor(uint32_t color) {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, color);
}
strip.show();
}
void pulseLastLED() {
for (int i = 0; i < 10; i++) {
strip.setPixelColor(NUM_LEDS - 1, strip.Color(255, 0, 0)); // Red
strip.show();
delay(100);
strip.setPixelColor(NUM_LEDS - 1, 0); // Turn off the LED
strip.show();
delay(100);
}
// Activate buzzer
digitalWrite(BUZZER_PIN, HIGH);
delay(500);
digitalWrite(BUZZER_PIN, LOW);
}