// https://wokwi.com/projects/372337626147389441
// https://forum.arduino.cc/t/make-an-output-pin-behave-like-a-monostable-multivibrator/1155428/12
// this is meant to be the state diagram in post #12
// the PIR delayTime is set to 2 seconds in the *.json file
# define IR_Pin 2
# define LED_Pin 13
// just to see 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("A. 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("B. time turns LED off");
ledOn = false;
state = LED_OFF;
}
break;
case LED_OFF :
if (!irActive) {
Serial.println("C. IR signal gone, so");
timer = now;
state = WAIT;
}
break;
case WAIT :
elapsedTime = now - timer;
if (irActive) {
Serial.println("D. IR signal still or again, so");
timer = now;
state = WAIT;
}
else if (elapsedTime >= NO_OBSTAKLE_WAIT_TIME) {
Serial.println("E. after a bit more time, we reset");
timer = now;
state = IDOL;
}
break;
}
}
Heartbeat
The LED
PIR OUTPUT