Running a motor for a 3 seconds continuously with and without interrupt

I have interfaced a dc motor and IR sensor to my nano. The DC motor is supposed to run only if the IR sensor detects an obstacle. Now, I'm trying to get the motor to turn off if continuously obstructed for 3 seconds, and exit the interrupt (in case of the first code with interrupt), and again wait for the sensor to go low again (falling edge). I have implemented this using millis(), but the code doesnt seem to be working consistently, as the timing seems to have gone for a toss(random behavior; sometimes it keeps running continuously and sometimes it stops). Can anyone on this forum please review it and suggest me a correction. Also, would it be possible to use a LOW trigger instead of falling edge to achieve this ?

#include <LowPower.h>

int out1 = 5; 
int IRSensor = 3; 
int LED = 6; 
int Switch = 2;
volatile int statusSensor=1;
volatile int switchSensor=1;
unsigned long delayStart = 0;
boolean motorRunning = false;
static unsigned long motorStartMillis;
static unsigned long motorRunMillis = 3000;
static unsigned long motordiff;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
  pinMode(out1,OUTPUT);
  //pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
  attachInterrupt(1,IRinterrupt,FALLING);
  //attachInterrupt(1,Switchinterrupt,FALLING);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println ("zloop");
  //Interrupts();
  LowPower.powerDown(SLEEP_FOREVER , ADC_OFF, BOD_OFF); 
  //Serial.println ("loop 1");
 

}


void IRinterrupt()
{
    // put your main code here, to run repeatedly:
  switchSensor = digitalRead (Switch);
  //Serial.println (switchSensor);
  
  statusSensor = digitalRead (IRSensor);
  //Serial.println (statusSensor);
  
  Serial.println ("ir interupt");
   if (statusSensor == 0 and switchSensor == 0){
     Serial.println ("ir low");
     digitalWrite(LED, LOW);
     digitalWrite(out1,HIGH);
     if (motorRunning == false){
     motorStartMillis = millis();
     Serial.println (motorStartMillis);}
     motorRunning = true;
     
     
   }
   else if (statusSensor == 0 and switchSensor == 1) {
      Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      }
   else if (statusSensor == 1 and switchSensor == 0) {
      Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, LOW);
      analogWrite(out1,0);
      }
    else {
      Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      }
  motordiff=millis()-motorStartMillis;
  Serial.println(motordiff);
  if (motorRunning == true and (motordiff >= motorRunMillis)){
        digitalWrite(out1,LOW);
        Serial.println ("motor timing");
        motorRunning = false;
        //noInterrupts();
     }
}

I have written another piece of code without interrupts. How do I achieve the same timing part for this too ?

int out1 = 5; //motor
int IRSensor = 3; // connect ir sensor to arduino pin 6
int LED = 6; // conect Led to arduino pin 9
int Switch = 2;
int statusSensor=1;
int switchSensor=1;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
  pinMode(out1,OUTPUT);
  //pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  switchSensor = digitalRead (Switch);
  //Serial.println (switchSensor);
  
  statusSensor = digitalRead (IRSensor);
  //Serial.println (statusSensor);
  delayStart = millis();
  //Serial.println ("ir interupt");

   if (statusSensor == 0 and switchSensor == 0){
     Serial.println ("ir low");
     analogWrite(out1,120);
     digitalWrite(LED, LOW);
   }
      else {
      Serial.println ("ir high");
      analogWrite(out1,0);
     
      }
     
}

Not to certain on interrupts myself, but the non-interrupt form of this would be:

#define IR_Pin 2

unsigned long prevTime;
bool prevState = false;

void setup() { }
void loop() {
  if (digitalRead(IR_Pin) && (!prevState)) { prevTime = millis(); }
  if (millis() - prevTime > 3000) { doSomething(); }
  prevState = digitalRead(IR_Pin);
  doSomethingElse();
}

void doSomething() {};
void doSomethingElse() {};

please review it and suggest me a correction

There is no need for an interrupt in this case. But if you insist, your approach needs to be completely rewritten.

Basic rules for using interrupts:

  1. avoid using interrupts if you don't need them. Use of interrupts will introduce new problems.

  2. Interrupts should be as small and fast as possible, just determine what the main program should do, set flags in shared variables, and exit.

  3. declare variables shared between the main program and the interrupt as "volatile". If you forget to do this, the program may not work at all.

  4. never print from within an interrupt. Printing generally depends on interrupts, which are turned OFF in an interrupt routine. delay() won't work, and millis() is frozen in an interrupt.

  5. multibyte shared variables, like "motorStartMillis" that can be changed by an interrupt must be protected from corruption. In the main program, turn off the interrupts, make a copy of the variable, turn the interrupts back on, then use the copy.

Finally:
  attachInterrupt(1,IRinterrupt,FALLING);Refer to the Arduino Reference Page for the proper way to use attachInterrupt().

@Technokid2000

I tried writing a code which will stop the motor if it continuously runs for 3 seconds using your method. I am using two variables count and count1, where count is incremented by one every time the motor is run (first if command in dosomething loop). So the timer variable (prevTime) in the main loop record the time only when count1=1 (first time motor starts), and then keeps checking if 3 seconds are elapsed to stop the motor if still running. This logic is not working. Can you guys please correct me ?

int out1 = 5; //motor
int IRSensor = 3; // connect ir sensor to arduino pin 6
int LED = 6; // conect Led to arduino pin 9
int Switch = 2;
int statusSensor=1;
int switchSensor=1;
unsigned long prevTime;
 int count =0;
int count1=0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
  pinMode(out1,OUTPUT);
  //pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
}


void loop() {
  // put your main code here, to run repeatedly:
  switchSensor = digitalRead (Switch);
  Serial.println ("zloop");
  
  statusSensor = digitalRead (IRSensor);
  //Serial.println (statusSensor);
  if (count1==1) 
  { prevTime = millis();
    Serial.println(prevTime);
  }
  if (millis() - prevTime > 3000) 
  { doSomethingElse();
  }
  doSomething();
   
}

void doSomething(){
  if (statusSensor == 0 and switchSensor == 0){
     //Serial.println ("ir low");
     //prevState = true;
     analogWrite(out1,150);
     //digitalWrite(out1,HIGH);
     count1=count++;
     Serial.println(count);
     digitalWrite(LED, LOW);
  }
   else if (statusSensor == 0 and switchSensor == 1) {
      Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      count=0;
      count1=0;
      }
   else if (statusSensor == 1 and switchSensor == 0) {
      Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, LOW);
      analogWrite(out1,0);
      count=0;
      count1=0;
      }
    else {
      Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      count=0;
      count1=0;
      }
} 
void doSomethingElse(){
      Serial.println ("ir high else");
      analogWrite(out1,0);
      count=0;
      count1=0;
      //analogWrite(out1,0);
  }

Serial.println(count); Always keeps printing 1. Does'nt get incremented.