// https://wokwi.com/projects/372326413257367553
// https://forum.arduino.cc/t/make-an-output-pin-behave-like-a-monostable-multivibrator/1155428/12
# define IR_Pin 2
# define LED_Pin 13
// just tosee that we are looping.
# define heartBeatLED_Pin 12
enum {IDOL = 0, LED_ON, LED_OFF, WAIT,};
unsigned long timer;
# define LED_ON_TIME 5000
# define NO_OBSTAKLE_WAIT_TIME 2000
void setup() {
Serial.begin(115200);
Serial.println("Hello World!\n");
pinMode(IR_Pin, INPUT);
pinMode(LED_Pin, OUTPUT);
pinMode(heartBeatLED_Pin, OUTPUT);
}
byte state = IDOL;
bool irActive;
unsigned long now;
bool ledOn;
void loop() {
delay(50);
digitalWrite(heartBeatLED_Pin, (millis() & 512) ? HIGH : LOW);
// I. inputs to the model - time and motion activity
now = millis();
irActive = digitalRead(IR_Pin) == HIGH;
// P. process the inputs given the current state and inputs
theFSM();
// O. use the process to set the outputs.
digitalWrite(LED_Pin, ledOn ? HIGH : LOW);
}
void theFSM() {
long elapsedTime = 0;
switch (state) {
case IDOL :
if (irActive) {
Serial.println("motion turns LED on");
state = LED_ON;
timer = now;
}
break;
case LED_ON :
ledOn = true;
elapsedTime = now - timer;
if (elapsedTime >= LED_ON_TIME) {
Serial.println("time turns LED off");
ledOn = false;
state = LED_OFF;
}
break;
case LED_OFF :
if (!irActive) {
Serial.println("IR signal gone, so");
timer = now;
state = WAIT;
}
break;
case WAIT :
elapsedTime = now - timer;
if (elapsedTime >= NO_OBSTAKLE_WAIT_TIME) {
Serial.println("after a bit more time, we reset");
timer = now;
state = IDOL;
}
break;
}
}