// FSM approach to airplane-like LED flashing
const int ontime = 250;
const int offtime = 150;
const int pausetime = 1000;
const int strobes = 2;
// button characteristics
const int buttonPin = 3;
const unsigned long buttonDebounceTime = 50;
#define BUTTON_DOWN LOW
// two FSM's are defined. "system" and "LED".
// LED fsm ative only when system is in flashing state
enum systemStates {NOT_FLASHING, FLASHING} systemState;
enum LEDstates {LED_ON, LED_OFF, LED_PAUSE} LEDstate;
// LED control
const int LEDpin = 8;
unsigned long lastTimeLED;
int strobeCounter;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(LEDpin, OUTPUT);
setSystemState(NOT_FLASHING);
}
void loop() {
// system fsm
switch (systemState) {
case NOT_FLASHING:
if (buttonWasPressed()) {
setSystemState(FLASHING);
}
break;
case FLASHING:
if (buttonWasPressed()) {
setSystemState(NOT_FLASHING);
}
break;
}
if (systemState == FLASHING) {
// LED fsm is active
switch (LEDstate) {
case LED_ON:
if (millis() - lastTimeLED >= ontime) { // see if LED has been ON long enough
strobeCounter++;
if (strobeCounter == strobes) {
setLEDstate(LED_PAUSE);
strobeCounter = 0; // reset strobe counter
} else {
setLEDstate(LED_OFF);
}
}
break;
case LED_OFF:
if (millis() - lastTimeLED >= offtime) {
setLEDstate(LED_ON);
}
break;
case LED_PAUSE:
if (millis() - lastTimeLED >= pausetime) {
setLEDstate(LED_ON);
}
break;
}
}
}
// transition LED fsm to a new state
void setLEDstate(LEDstates newState) {
LEDstate = newState;
// action to be taken upon entering new state
switch (LEDstate) {
case LED_ON:
digitalWrite(LEDpin, HIGH);
break;
case LED_OFF:
digitalWrite(LEDpin, LOW);
break;
case LED_PAUSE:
digitalWrite(LEDpin, LOW);
break;
}
lastTimeLED = millis(); // record event time
}
// transition system fsm to a new state
void setSystemState(systemStates newState) {
systemState = newState;
// action to be taken upon entering new state
switch (systemState) {
case FLASHING:
// wake up: start with LED on
setLEDstate(LED_ON);
strobeCounter = 0;
break;
case NOT_FLASHING:
// turn lights off before going to bed
setLEDstate(LED_OFF);
break;
}
}
// check button
boolean buttonWasPressed() {
static unsigned long lastButtonCheckTime=0;
int currentButtonState;
static int previousButtonState;
boolean wasPressed = false;
currentButtonState = digitalRead(buttonPin);
if (currentButtonState != previousButtonState) {
if (currentButtonState == BUTTON_DOWN) {
if (millis() - lastButtonCheckTime >= buttonDebounceTime) {
wasPressed = true;
}
}
previousButtonState = currentButtonState;
lastButtonCheckTime = millis();
}
return wasPressed;
}