#include <Adafruit_NeoPixel.h>
#define BUTTON_PIN 2 // Button pin for controlling the timer
#define LED_PIN 5 // Pin connected to the NeoPixels
#define LED_COUNT 16 // Total number of LEDs in the strip
#define BUZZER_PIN 6 // Buzzer pin
#define POTENTIOMETER_PIN 34 // Potentiometer pin (Analog input pin for ESP32)
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
enum State { SHOW_COLOR, RUNNING, PAUSED, FINISHED, PULSING };
State state = SHOW_COLOR; // Initial state to show color
unsigned long previousMillis = 0; // Stores the last time the LEDs were updated
const long interval = 1000; // Interval for updating LEDs (1 second)
int currentPlayer = 0; // Index of the current player
int ledIndex = LED_COUNT; // Start from the last LED for countdown
uint32_t playerColors[] = {strip.Color(255, 0, 255), strip.Color(255, 255, 0), strip.Color(0, 255, 255), strip.Color(255, 255, 255)}; // Player colors
int pulseCount = 0; // Count pulses for the last LED
bool buttonPressed = false;
unsigned long buttonPressStartTime = 0;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
updateNumberOfPlayers(); // Ensure player count is initialized correctly
showCurrentPlayerColor();
}
void loop() {
checkButton();
updateNumberOfPlayers();
if (state == RUNNING && millis() - previousMillis >= interval) {
updateTimer();
}
if (state == PULSING) {
pulseLastLed();
}
}
void checkButton() {
bool currentButtonState = digitalRead(BUTTON_PIN) == LOW;
if (currentButtonState && !buttonPressed) {
buttonPressStartTime = millis();
buttonPressed = true;
} else if (!currentButtonState && buttonPressed) {
long holdTime = millis() - buttonPressStartTime;
buttonPressed = false;
if (holdTime >= 2000) {
nextPlayer();
} else {
if (state == SHOW_COLOR || state == PAUSED || state == FINISHED) {
startTimer();
} else if (state == RUNNING) {
pauseTimer();
}
}
}
}
void showCurrentPlayerColor() {
setAllLedsColor(playerColors[currentPlayer]);
ledIndex = LED_COUNT; // Reset for countdown
state = SHOW_COLOR;
}
void startTimer() {
previousMillis = millis(); // Reset the timer
state = RUNNING;
}
void pauseTimer() {
state = PAUSED;
}
void nextPlayer() {
currentPlayer = (currentPlayer + 1) % (sizeof(playerColors) / sizeof(playerColors[0]));
showCurrentPlayerColor();
}
void setAllLedsColor(uint32_t color) {
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, color);
}
strip.show();
}
void updateTimer() {
if (ledIndex > 0) {
--ledIndex;
float fraction = static_cast<float>(ledIndex) / static_cast<float>(LED_COUNT);
uint32_t color;
if (fraction > 0.66) {
color = strip.Color(0, 255, 0); // Green
} else if (fraction > 0.33) {
color = strip.Color(255, 165, 0); // Orange
} else {
color = strip.Color(255, 0, 0); // Red
}
for (int i = 0; i < ledIndex; i++) {
strip.setPixelColor(i, color);
}
for (int i = ledIndex; i < LED_COUNT; i++) {
strip.setPixelColor(i, 0); // Turn off LEDs ahead of the current index
}
strip.show();
previousMillis = millis();
} else {
state = PULSING;
pulseCount = 0; // Reset pulse count
previousMillis = millis(); // Reset the timer for pulsing
}
}
void pulseLastLed() {
static bool isOn = false;
if (millis() - previousMillis >= 100) {
isOn = !isOn;
strip.setPixelColor(0, isOn ? playerColors[currentPlayer] : 0); // Toggle the first LED
strip.show();
previousMillis = millis();
pulseCount++;
}
if (pulseCount >= 20) {
pulseCount = 0;
state = FINISHED;
}
}
void updateNumberOfPlayers() {
// Read the potentiometer value and map it to the number of players
int potValue = analogRead(POTENTIOMETER_PIN);
int numPlayers;
if (potValue < 1024)
numPlayers = 1;
else if (potValue < 2048)
numPlayers = 2;
else if (potValue < 3072)
numPlayers = 3;
else
numPlayers = 4;
// Adjust the number of players and colors
if (numPlayers != sizeof(playerColors) / sizeof(playerColors[0])) {
currentPlayer = 0; // Reset to the first player
// Update the number of players and show the color for the current player
switch (numPlayers) {
case 1:
playerColors[0] = strip.Color(255, 0, 255);
break;
case 2:
playerColors[0] = strip.Color(255, 0, 255);
playerColors[1] = strip.Color(255, 255, 0);
break;
case 3:
playerColors[0] = strip.Color(255, 0, 255);
playerColors[1] = strip.Color(255, 255, 0);
playerColors[2] = strip.Color(0, 255, 255);
break;
case 4:
playerColors[0] = strip.Color(255, 0, 255);
playerColors[1] = strip.Color(255, 255, 0);
playerColors[2] = strip.Color(0, 255, 255);
playerColors[3] = strip.Color(255, 255, 255);
break;
}
// Show the color for the current player
showCurrentPlayerColor();
}
}