How to control a NEMA 17 with PIR light sensor

Hi there

Any help would be really appreciated, I am a novice at using arduinos.

I am trying to make an Arduino UNO, Nema 17 alongside an A4988 driver to be controlled through a PIR light sensor.

Any help as to achieve this would be much appreciated. WOuld it also be possible to use a CNC shield alongside a PIR sensor?

Thanks so much in advance! :slight_smile:

Welcome to the forum

What do you want the motor to do in respect of the PIR ?

  • start ?
  • stop ?
  • change speed ?
  • change direction ?
  • something else ?

What electronics and computing experience do you have ?

2 Likes

Yes, you can use a PIR detector with a CNC shield. Here is the pin mapping between the CNC shield V3 and the Uno. Digital inputs are available using the limit pin inputs, unused step and dir pins or analog inputs (abort, hold, resume, coolant enable).

Thanks for the response - for now, I would love to just trigger a rotation of a predetermined number of steps.

I have some experience using motion sensors and LEDs as well as simple Stepper motor set-ups. BUt I would say I am very inexperienced but I am keen to learn. I have little coding experience but I have done quite a lot of dowloading and tweaking code for game design and arduinos

Where are you stuck ?

Can you read and print the state of the PIR ?
Can you print a message when the state changes ?
Have you got code to move the stepper a fixed number of steps in one direction ?
Do you know how to move the stepper in the other direction ?

Here is a simple demo that will have a stepper rotate one turn CW when motion is detected by a PIR motion detector (active high). The stepper will pause at the one turn position for 10 seconds then return to the starting (zero) point. The demo uses the MobaTools stepper library (available via the IDE library manager), the blink without delay method (see below for more info) for timing and the a finite state machine to define the sequence of events.

The PIR sensor is wired to the X+ limit switch position on the header. Optional LED (to show PIR state) is wired to the Abort position on the header.

Does your stepper need to start at a particular starting position (home)?

This code tested on real hardware, Uno, CNC shield V3 and HC-SR501 PIR motion sensor.

// turn stepper one turn on PIR activation (active high), pause and return to 0
// by groundFungus aka c.goulding

#include <MobaTools.h>

const byte ledPin = A0;
const byte pirPin = 9;
const byte stepPin = 2;
const byte dirPin = 5;
const byte enablePin = 8;

const unsigned int motorStepsPerRev = 200;
const unsigned int microstepMultiplier = 4;
const int STEPS_REVOLUTION = motorStepsPerRev * microstepMultiplier;

MoToStepper stepper( STEPS_REVOLUTION, STEPDIR );

byte mode = 0;

unsigned long timer = 0;  // pause timer
unsigned long interval = 10000;  // pause at position, ms

void setup()
{
   Serial.begin(115200);
   pinMode(ledPin, OUTPUT);
   stepper.attach( stepPin, dirPin );
   stepper.attachEnable(enablePin, 0, 1);
   stepper.setSpeed(1000);  // rpm /10
   stepper.setRampLen(10);
   stepper.setZero();
}

void loop()
{
   static unsigned long loopTimer = 0;
   unsigned long loopInterval = 100;
   if (millis() - loopTimer >= loopInterval)
   {
      loopTimer = millis();

      if (mode == 0)
      {
         Serial.println("mode = 0");
         bool pirState = digitalRead(pirPin);
         
         digitalWrite(ledPin, pirState);
         if (pirState == 1)
         {
            mode = 1;
         }

      }

      else if ( mode == 1)
      {
         Serial.println("mode = 1");
         stepper.moveTo(STEPS_REVOLUTION); // one rev
         mode = 2;
      }

      else if ( mode == 2)
      {
         Serial.println("mode = 2");
         if (stepper.distanceToGo() == 0)
         {
            timer = millis();
            mode = 3;
         }
      }

      else if ( mode == 3)
      {
         Serial.println("mode = 3");
         if (millis() - timer > interval)
         {
            mode = 4;
         }
      }

      else if ( mode == 4)
      {
         Serial.println("mode = 4");
         stepper.moveTo(0);
         mode = 0;
      }
   }
}

Some non-blocking timing tutorials:
Blink without delay().
Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

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