Stuck and it almost works - motor, Quadrature, millis, pir

I’ve spent countless hours on the Google and come a long way in the last month. I’ve managed to cobble together some code that almost does what I want it to.

Arduino UNO (will get ported to a Nano in the final build)
Small Printer motor (with photo interrupts & encoder wheel)
panasonic pir sensor
relay
tip122 for motor control
bc547B for relay control

I’m able set it up so when the pir detects movement the motor moves forward for X number of pulses, and then after no movement detected the motor reverses back to it’s start position. However I’m now attempting to incorporate millis so that the system waits a certain amount of time after the pir stops detecting movement. I’ve attempted a handful of examples similar to what I’m shooting for. So far below is the closest I’ve come to what I’m after. I’m able to have an led turn on and off reliable using this method, but as soon as I attempt to incorporate the quadrature motor control, it doesn’t completely work. The motor moves to the forward position as planned, and after the assigned wait time (of no movement) the motor spins in reverse indefinitely as though the UNO is not longer reading the interrupt pulses.

int in_a = 2;
int in_b = 4;

int pirPin = 8;    //the digital pin connected to the PIR sensor's output
const int motSpeed = 9;
const int motFowRev = 12;
//const int motRev = 11;

// Initialize the counter
volatile int pulses = 0;

long unsigned int lowIn;   
long unsigned int stillPause = 10000;

boolean lockLow = true;
boolean takeLowTime; 

void count() {
  // This function is called by the interrupt
  // If in_b is HIGH increment the counter
  // otherwise decrement it
  if (digitalRead(in_b)) {
    pulses++;
  }
  else {
    pulses--;
  }
}
void motOpen() {
  digitalWrite(motFowRev, HIGH);
  analogWrite(motSpeed, 255);
}

void motClose() {
    digitalWrite(motFowRev, LOW);
    delay(10);
    analogWrite(motSpeed, 255);
}

void motStop() {
  digitalWrite(motSpeed,LOW);
  digitalWrite(motFowRev, LOW);
}

void popOpen() {
  if ((pulses) <12000) {
    motOpen();
  }
  else {
    motStop();
  }
}

void popClosed() {
  if ((pulses) >100) {
    motClose();
  }
  else {
    motStop();
  }
}
void setup() {
  Serial.begin(9600);
  pinMode(pirPin, INPUT);     // declare sensor as input
  pinMode(motSpeed, OUTPUT);
  pinMode(motFowRev, OUTPUT);
  pinMode(in_a, INPUT);
  pinMode(in_b, INPUT);
  attachInterrupt(0, count, RISING);
  digitalWrite(pirPin, LOW);
  digitalWrite(motFowRev, LOW);
      }
void loop() {
  if(digitalRead(pirPin) == HIGH){
    if ((pulses) <12000) {
    motOpen();
  }
  else {
    motStop();
  }
      if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         }         
         takeLowTime = true;
       }

     if(digitalRead(pirPin) == LOW){       
       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > stillPause){  
       //attachInterrupt(0, count, RISING);
    if ((pulses) >100) {
    motClose();
  }
  else {
    motStop();
  }                    
           lockLow = true;  
           }
       }
  }

Any insight on what I don’t seem to be grasping here is greatly appreciated. Thanks!

Does 'pirPin' have a pull-up?

Show us a good schematic of your circuit.

Show us a good image of your wiring.

Hey Larryd. Thanks for the super fast response!

I’m using a pulldown resistor on the pir. It behaves reliably as far as what it reads out when connected. Right now I’v just got a button in place of the pir for simplicity of testing the circuit out until I sort out this issue I’m having. My issue didn’t arrive until adding the code to attempt a delayed response from the pir reading going LOW. For example using the same circuit with the following code below (with either the pir sensor or the button) the system works as expected. As soon as the pir detected movement the motor would move to it’s allotted forward position and as soon as the pir stopped detecting movement, the motor would reverse back to it’s start position.

This code works as expected on the same circuit:

int in_a = 2;
int in_b = 4;

const byte pirPin = 8; // choose the input pin (for PIR sensor)
const int motSpeed = 9;
const int motFowRev = 12;

// Initialize the counter
volatile int pulses = 0;

int pirRead;

void count() {
  // This function is called by the interrupt
  // If in_b is HIGH increment the counter
  // otherwise decrement it
  if (digitalRead(in_b)) {
    pulses++;
  }
  else {
    pulses--;
  }
}

void motOpen() {
  digitalWrite(motFowRev, HIGH);
  //delay(10);
  analogWrite(motSpeed, 255);
  //digitalWrite(motRev, LOW);
}

void motClose() {
    digitalWrite(motFowRev, LOW);
    delay(10);
    analogWrite(motSpeed, 255);
    //digitalWrite(motFow, LOW);
}

void motStop() {
  digitalWrite(motSpeed,LOW);
  digitalWrite(motFowRev, LOW);
  //digitalWrite(motFow, LOW);
}

void popOpen() {
  //hopefully this will be all needed to open the popup
  if ((pulses) <12000) {
    //motStop();
    //delay(10);
    motOpen();
  }
  else {
    motStop();
  }
}

void popClosed() {
  if ((pulses) >100) {
    //motStop();
    //delay(10);
    motClose();
  }
  else {
    motStop();
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(pirPin, INPUT);     // declare sensor as input
  pinMode(motSpeed, OUTPUT);
  pinMode(motFowRev, OUTPUT);
  //pinMode(motRev, OUTPUT);
  pinMode(in_a, INPUT);
  pinMode(in_b, INPUT);
  attachInterrupt(0, count, RISING);
}

void loop() {
  //    delay(10);
  pirRead = digitalRead(pirPin);
  Serial.print(pulses);
  Serial.print(" ");
  Serial.println(pirRead);
  //Serial.print(irSwitchRead);
  //delay (10);
  //irSwitchRead = digitalRead(irSwitch);
  unsigned long currentMillis = millis();

  //if (digitalRead(pirPin) == HIGH) 
  if (pirRead ==HIGH) {
    popOpen();
  }
if (pirRead == LOW){
    popClosed();
  }

}

I’m confident the physical circuit & pir are connected in a functioning manner. But once I attempt to add the additional code (in my original post) the motor return position ends up getting ignored & it just continues to run in reverse never stopping. I’m confused as to what I’m doing wrong with that code implementation that’s causing it to seem to not register the interrupt pulse position for the reverse portion at the end.

I’ve attached a photo of the circuit but it’s not really that clear to follow the rats nest of hookup wire I’ve got going on here. If I get a good enough window of time this evening I’ll try to sketch out the circuit in a way that could be understood visually. Through the trial and error I’ve done thus far I’m quite certain my problem is within the code in my initial post. I just can’t wrap my head around why that is. Perhaps a conflict with the use of millis while also using external interrupts?

I’ve attempted using detachInterrupts() & attachinterrupts() on either side of the section of the loop that uses millis with no luck. I also attempted a using no interrupts & interrupts similarly also with no luck.