I have to make a door controlled by a photo interrupter. The door needs to open only after the photointerrupter is blocked for 4 seconds or more. The door will be open or close with the help of a motor which is connected to a relay module. So far the codes that I have tried only work when the photo interrupter is initially blocked with no regard to how long it is blocked. I am very new to Arduino coding, so any help is appreciated. Thank you. Attached is the code that I think should work.
const int PIRInterrupt = 2;
const int Relay = 8;
unsigned long startTime;
volatile byte relayState = LOW;
void setup() {
pinMode(Relay, OUTPUT);
digitalWrite(Relay, LOW); // Set relay initially OFF
pinMode(PIRInterrupt, INPUT);
Serial.begin(9600);
}
void loop() {
if (digitalRead(PIRInterrupt) == LOW) {
startTime = millis(); // Record the time when PIR sensor is blocked
while (digitalRead(PIRInterrupt) == LOW && (millis() - startTime) <= 4000) {
// Wait for 4 seconds while the PIR sensor is blocked
// Do nothing during this time
}
if (digitalRead(PIRInterrupt) == LOW) {
// If the PIR sensor is still blocked after 4 seconds,
// then turn the relay ON
digitalWrite(Relay, HIGH);
relayState = HIGH;
delay(2000);
digitalWrite(Relay, LOW); // Turn the relay OFF
relayState = LOW;
}
} else {
digitalWrite(Relay, LOW); // Turn the relay OFF if no motion detected
relayState = LOW;
}
}
const int P_PIR = 2;
const int P_RELAY = 8;
unsigned long tmrBlocked = 0;
void setup() {
pinMode(P_RELAY, OUTPUT);
digitalWrite(P_RELAY, LOW); // Set P_RELAY initially OFF
pinMode(P_PIR, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
bool Blocked = (digitalRead(P_PIR) == LOW);
if (tmrBlocked == 0 && Blocked) {
// If sensor detects an obstacle and it's the first time, set/start the timer
tmrBlocked = millis();
Serial.println("Starting timer...");
} else {
// If there is a timer active
if (tmrBlocked > 0) {
// if the obstacle is still there after 4 seconds
if (millis() - tmrBlocked > 4000 && Blocked) {
Serial.println("Activating relay!");
// then turn the P_RELAY ON
digitalWrite(P_RELAY, HIGH);
delay(2000);
// then turn the P_RELAY OFF
digitalWrite(P_RELAY, LOW);
// Now wait for the Blocked to get away...
Serial.println("Waiting for obstacle moving away...");
while (digitalRead(P_PIR) == LOW) {
delay(200);
}
Serial.println("Ok, done!");
// Reset the timer
tmrBlocked = 0;
} else {
// If the obstacle got away before the 4 seconds timeout, clear the timer
if (millis() - tmrBlocked <= 4000 && !Blocked) {
tmrBlocked = 0;
Serial.println("Obstacle gone! Timer canceled.");
}
}
}
}
}
Please note "INPUT_PULLUP" and the relayState variable missing (there's no need of such variable, you can still digitalRead() the replay pin to get its state)...
PS: What is exactly a "photo interrupter" for you? In the sketch you call it "PIR" but a PIR is a "Passive Infrared Sensor", aka motion detector so I suppose you don't really mean a PIR, neither an infrared reflector detector (they're made for detect obstacles for short distance), than a real barrier sensor to be able to know if someone is between the IR transmitter and the sensor (with or without a reflective panel). Please always give complete information about the sensors (and cabling) you're using.
PS2: why don't you test your code using TinkerCad or WokWi? to make things easier, replace the sensor with a pushbutton, and the relay with a LED....