PIR sensor to move stepper if there is movement sensed

Hello,

I'm building an automatic door.

To do so I have an Arduino Nano, L298N driver, Nema17 Stepper Motor and a PIR sensor.

So far, I can make the motor move to a desired position (door is open) if the PIR senses movement. Then, the motor goes back to the initial position (door is closed).

My problem is that I don't want the motor to move back to initial position if the PIR still sensing movement. For now, with my code, door always go back despite sensing or not sensing movement.

Thanks!!

This is my code

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define the AccelStepper interface type:
#define MotorInterfaceType 4

int PIR = 2;
int mov = 0; 
int movAnt;
// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(MotorInterfaceType, 8, 9, 10, 11);

void setup() {
  // Set the maximum steps per second:
  stepper.setMaxSpeed(1000);
  // Set speed
  stepper.setSpeed(200);
  // Set the maximum acceleration in steps per second^2:
  stepper.setAcceleration(900); 

  stepper.setCurrentPosition(0);
  
  pinMode(PIR, INPUT);
}

void loop() {

int mov = digitalRead(PIR);

if (mov == HIGH){

  // Set target position:
  stepper.moveTo(1000);
  // Run to position with set speed and acceleration:
  stepper.runToPosition();
  
  delay(500);

  int movAnt = mov;
  int mov = digitalRead(PIR);

  delay(1000);
}
if (mov == LOW && movAnt == LOW)  {
  // Move back to original position:
  stepper.moveTo(0);
  // Run to position with set speed and acceleration:
  stepper.runToPosition();

  delay(1000);
}

}

You are declaring a second variable mov inside your if() statement. It has nothing to do with the first declaration (although you might thing they are the same). Just do the assignment. Same is true for movAnt

mov = digitalRead(PIR)

Also, how to you have it wired up. It may need a pull-up or pull-down resistor

You created a new variable that is only in scope inside that code block.
Drop the "int"

You have to ask yourself and the sensor how long will the sensor continue to indicate movement after it reports movement. Is it just a momentary pulse or will it hold for several seconds after movement is reported?
If just a momentary report, then you may need a different or a secondary sensor to report IR from what ever had been moving.

They are hardly compatible. Buy a current controlled driver.

here's a sim..
added a sensor check just before door close..
seems to do what you wanted..

Test it here..

Yeah, that sim makes just as I wish. I'll try it.

Sadly, doesn't work for me...

Which one do you recommend?

Thanks

Right, done.
Thanks.

Yes, I believe this may be my problem. Actually, I expected the sensor to measure constantly. The condition to go back to origin would be not sensing movement during X period of time when door open.

bool DoorOpened = false;

unsigned long openMilli = 0;
int closeDelay = 5000;

unsigned long lastSample = 0;
int intervalSample = 1000;


void setup() {
  // Set the maximum steps per second:
  stepper.setMaxSpeed(1000);
  // Set speed
  stepper.setSpeed(200);
  // Set the maximum acceleration in steps per second^2:
  stepper.setAcceleration(900);

  stepper.setCurrentPosition(0);

  pinMode(PIR, INPUT);
}

void loop() {
  if (millis() - lastSample >= intervalSample ) {
    lastSample = millis();
    int mov = digitalRead(PIR);

    if (mov == HIGH) {
      OpenDoor();
    } else
    {
      CloseDoor();
    }
  }

}


void OpenDoor() {
  openMilli = millis();
  if (!DoorOpened) {
    DoorOpened = true;
    // Set target position:
    stepper.moveTo(1000);
    // Run to position with set speed and acceleration:
    stepper.runToPosition();
  }
}

void CloseDoor() {
  if (DoorOpened) {
    if (millis() - openMilli >= closeDelay)
    {
      DoorOpened = false;
      // Move back to original position:
      stepper.moveTo(0);
      // Run to position with set speed and acceleration:
      stepper.runToPosition();
    }
  }
}

seems good.. ~q

don't like the runToPosition() as it blocks..
could step the close and stop mid swing to reopen..
does the door interrupt the sensor??

You need to test your theory!

This one works fine. Thanks. It's quite different of my initial logics. :slight_smile:

you're welcome..
updating the sim still..
got the door closing routine doing a bit more..
swings back open quicker, but gonna play with having a slower closing speed..
can't seem to stop door mid swing..
have fun.. ~q

Yeah, stop the motion if senses movement while closing the door was another feature I considered. Although, the door itself makes the sensor move a bit so... gets a bit hard in the end.

this seems to do just that..
if you can figure out at which steps we start seeing sensor, can try to block out..

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define the AccelStepper interface type:
#define MotorInterfaceType 4

int PIR = 2;
int mov = 0;
int movAnt;
// Create a new instance of the AccelStepper class: step ,dir
AccelStepper stepper = AccelStepper(1, 10, 11);

//AccelStepper stepper = AccelStepper(MotorInterfaceType, 8, 9, 10, 11);
bool DoorOpened = false;

unsigned long openMilli = 0;
int closeDelay = 5000;

unsigned long lastSample = 0;
int intervalSample = 1000;

byte DoorState = 0;


void setup() {
  // Set the maximum steps per second:
  stepper.setMaxSpeed(1000);
  // Set speed
  stepper.setSpeed(200);
  // Set the maximum acceleration in steps per second^2:
  stepper.setAcceleration(800);

  stepper.setCurrentPosition(0);

  pinMode(PIR, INPUT);
}

void loop() {

  int mov = 0;

  if (millis() - lastSample >= intervalSample ) {
    lastSample = millis();
    mov = digitalRead(PIR);
  }

  if (mov == HIGH) {
    OpenDoor();
  } else
  {
    CloseDoor();
  }




}


void OpenDoor() {
  if (DoorState == 0) {
    openMilli = millis();
  }
  else {
    DoorOpened = false;
    stepper.stop();
  }
  if (!DoorOpened) {
    DoorOpened = true;
    DoorState = 0;
    // Set the maximum steps per second:
    stepper.setMaxSpeed(1000);
    // Set speed
    stepper.setSpeed(200);
    // Set the maximum acceleration in steps per second^2:
    stepper.setAcceleration(800);

    // Set target position:
    stepper.moveTo(1000);
    // Run to position with set speed and acceleration:
    stepper.runToPosition();
  }
}

void CloseDoor() {
  if (DoorOpened) {
    if (millis() - openMilli >= closeDelay)
    {
      switch (DoorState) {
        case 0:   // Move back to original position:
          // Set the maximum steps per second:
          stepper.setMaxSpeed(500);
          // Set speed
          stepper.setSpeed(100);
          // Set the maximum acceleration in steps per second^2:
          stepper.setAcceleration(400);
          stepper.moveTo(0);
          DoorState++;
          break;
        case 1:  stepper.run();
          if (stepper.currentPosition() == stepper.targetPosition()) {
            DoorOpened = false;
          }
          break;
      }

    }
  }
}
1 Like

Looks good! I got to go now, tomorrow I’ll apply and get back here!

Thanks to all for help

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.