constexpr unsigned long overallBlinkTime = 10000;
constexpr unsigned long blinkDelay = 500;
constexpr unsigned long lightDelay = 500;
constexpr byte buttonPin = 5;
constexpr int noOfLeds = 3;
byte ledPin[noOfLeds] = {2, 3, 4};
int currentLed = 1;
int lastLed = 0;
unsigned long nextStateTime;
byte button;
enum States {CHOOSELED, ON500, BLINK};
States state = CHOOSELED;
void setup() {
Serial.begin(115200);
Serial.println("Start");
for (int i = 0; i < noOfLeds; i++) {
pinMode(ledPin[i], OUTPUT);
}
pinMode(buttonPin, INPUT_PULLUP);
randomSeed(analogRead(0));
}
void loop() {
button = buttonState();
stateMachine();
}
void stateMachine() {
switch (state) {
case CHOOSELED:
chooseLed();
break;
case ON500:
on500();
break;
case BLINK:
blink();
break;
}
}
void blink() {
static unsigned long lastBlinkTime = 0;
if (millis() - lastBlinkTime >= blinkDelay) {
lastBlinkTime = millis();
byte actState = digitalRead(ledPin[currentLed]);
digitalWrite(ledPin[currentLed], !actState);
}
if (millis() - nextStateTime >= overallBlinkTime) {
digitalWrite(ledPin[currentLed], LOW);
changeStateTo(CHOOSELED);
Serial.println("BLINK -> CHOOSELED " + String(currentLed));
}
}
void on500() {
if (millis() - nextStateTime >= lightDelay) {
if (button == LOW) {
changeStateTo(BLINK);
Serial.println("ON500 -> BLINK " + String(currentLed));
} else {
digitalWrite(ledPin[currentLed], LOW);
changeStateTo(CHOOSELED);
Serial.println("ON500 -> CHOOSELED " + String(currentLed));
}
}
}
void chooseLed() {
if (button == LOW) {
for (int i = 0; i < noOfLeds; i++) {
digitalWrite(ledPin[i], LOW);
}
while (currentLed == lastLed) {
currentLed = random(0, noOfLeds);
}
lastLed = currentLed;
digitalWrite(ledPin[currentLed], HIGH);
changeStateTo(ON500);
Serial.println("ON500 " + String(currentLed));
}
}
void changeStateTo(States newState) {
state = newState;
nextStateTime = millis();
}
byte buttonState() {
static unsigned long lastChangeTime = 0;
static byte lastState = HIGH;
static byte state = HIGH;
byte actState = digitalRead(buttonPin);
if (actState != lastState) {
lastState = actState;
lastChangeTime = millis();
}
if (state != lastState && millis() - lastChangeTime > 30) {
state = lastState;
}
return state;
}