// ------------- A very simplified button class -----------
class Button {
public:
Button(uint8_t pin)
: pin(pin) {}
void begin() {
pinMode(pin, INPUT_PULLUP);
}
operator bool() {
bool current = digitalRead(pin) == LOW;
if (current != prevState && (millis() - prevMillis >= 20)) {
prevState = current;
prevMillis = millis();
return current;
}
return false;
}
private:
uint8_t pin;
bool prevState = true;
uint32_t prevMillis = 0;
};
// --------------------------------------------------
const byte buttonPin = 9;
const byte ledPins[] = { 2, 3, 4, 5 };
const byte ledCnt = sizeof ledPins / sizeof * ledPins;
const byte pot1Pin = A0;
const byte pot2Pin = A1;
Button button(buttonPin);
// ---- State machine ----------------------------------
enum Mode : uint8_t { BLINK, CHASE};
enum Phase : uint8_t { LED_ON, LED_OFF};
Mode mode = BLINK;
Phase phase = LED_ON;
uint32_t stateStart = 0; // when the current phase began
byte chaseIdx = 0; // which LED is lit in CHASE mode
void allLeds(bool isLedON) {
for (byte pin : ledPins) digitalWrite(pin, isLedON ? HIGH : LOW);
}
void setup() {
for (byte pin : ledPins) pinMode(pin, OUTPUT);
button.begin();
stateStart = millis();
allLeds(true);
}
void loop() {
// --- Handle button press (toggle mode, reset state machine)
if (button) {
mode = (mode == BLINK) ? CHASE : BLINK;
phase = LED_ON;
chaseIdx = 0;
stateStart = millis();
allLeds(false);
if (mode == BLINK) {
allLeds(true);
} else {
allLeds(false);
digitalWrite(ledPins[chaseIdx], HIGH);
}
}
// --- Read pots every loop (non-blocking)
uint32_t onTime = analogRead(pot1Pin);
uint32_t offTime = analogRead(pot2Pin);
uint32_t now = millis();
uint32_t elapsed = now - stateStart;
if (mode == BLINK) {
// Two-phase: ON → OFF → ON → …
if (phase == LED_ON && elapsed >= onTime) {
allLeds(false);
phase = LED_OFF;
stateStart = now;
} else if (phase == LED_OFF && elapsed >= offTime) {
allLeds(true);
phase = LED_ON;
stateStart = now;
}
} else {
// CHASE: one LED on for (pot1+pot2) ms, then advance
uint32_t stepTime = onTime + offTime;
if (elapsed >= stepTime) {
digitalWrite(ledPins[chaseIdx], LOW);
chaseIdx = (chaseIdx + 1) % ledCnt;
digitalWrite(ledPins[chaseIdx], HIGH);
stateStart = now;
}
}
}