/*
Arduino Forum
Topics: Make an output pin behave like a monostable multivibrator
Category: Using Arduino
Sub-Category: Programming Questions
Link: https://forum.arduino.cc/t/make-an-output-pin-behave-like-a-monostable-multivibrator/1155428
*/
#define detectedPin 5
#define enablePin 4
#define statusPin 3
#define irPin 2
#define EN_TIME_DELAY 1000
#define OFF_TIME_DELAY 5000
#define BLINK_TIME_DELAY 500
#pragma region TIMER-ON
typedef struct {
unsigned long timeDelay;
unsigned long startTime;
bool input;
bool state;
bool timerOn(bool enable);
} timer_t;
bool timer_t::timerOn(bool enable) {
bool prevInput = input;
input = enable;
if (input) {
if (!state) {
unsigned long currTime = millis();
if (!prevInput) startTime = currTime;
if (currTime - startTime >= timeDelay) state = true;
}
} else {
state = false;
}
return state;
}
#pragma endregion TIMER-ON
timer_t blinkTimer;
timer_t enableTimer;
timer_t detectedTimer;
bool enabled;
bool detected;
bool blink;
void setup() {
pinMode(irPin, INPUT_PULLUP);
pinMode(detectedPin, OUTPUT);
enabled = true;
pinMode(statusPin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
blink = true;
enableTimer.timeDelay = EN_TIME_DELAY; // Set enable detection time delay
detectedTimer.timeDelay = OFF_TIME_DELAY; // Set detected time delay off
blinkTimer.timeDelay = BLINK_TIME_DELAY; // Set BLINK delay
}
void loop() {
bool irValue = !digitalRead(irPin); // Read the state of the sensor.
enableTimer.timerOn(!irValue); // Enable the detection timer by IR state.
enabled = (enabled | enableTimer.state ) & !detected; // Reset-Set the enabled sensor detection.
detected = (detected | (enabled & irValue)) & !detectedTimer.state; // Reset-Set the detected status
detectedTimer.timerOn(detected); // Enable the detected timer by detected state.
digitalWrite(statusPin, irValue);
digitalWrite(detectedPin, detected);
digitalWrite(enablePin, enabled);
if (blinkTimer.timerOn(!blinkTimer.state)) blink = !blink; // Toggle the blink state
digitalWrite(LED_BUILTIN, blink);
}DETECTED
ENABLE
IR