I'm trying to make a box that revolves around a pivot point using a NEMA17 stepper motor. The idea is straightforward: US1881 Hall effect sensor will change state based on magnets on the base of the box acting as an end stop, when the PIR sensor detects movement the stepper should move until the status of the Hall effect sensor changes, then wait 10 seconds before accepting any new movement.
I tried multiple times but something doesn't work. either the stepper won't move, or the trigger is not working properly, I assume there is an issue in the logic but I can't quite get it, and last attempt basically bricked the Arduino since RX and TX are always active.
This is the latest iteration of my code:
#include <AccelStepper.h>
// Define pins
#define HALL_SENSOR_PIN 2
#define PIR_SENSOR_PIN 3
#define STEP_PIN 4
#define DIR_PIN 5
// Create stepper object
AccelStepper stepper(1, STEP_PIN, DIR_PIN); // 1 is the half-step mode
// Define variables
volatile bool hallTriggered = false; // Interrupt flag
bool pirTriggered = false;
unsigned long pirStartTime = 0;
int motorState = 0; // 0: stopped, 1: moving forward, -1: moving backward
int cycleCount = 0;
bool initialMoveComplete = false; // Flag for initial movement
bool hallPreviousState; // Declare hallPreviousState globally
void setup() {
pinMode(HALL_SENSOR_PIN, INPUT_PULLUP);
pinMode(PIR_SENSOR_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN), hallInterrupt, CHANGE); // Interrupt on any state change
stepper.setMaxSpeed(1000); // Adjust as needed
stepper.setAcceleration(100); // Adjust as needed
// Initial movement: Move until Hall sensor state changes
hallPreviousState = digitalRead(HALL_SENSOR_PIN); // Initialize previous state
while (digitalRead(HALL_SENSOR_PIN) == hallPreviousState) {
stepper.run();
}
stepper.stop();
motorState = 0;
}
void loop() {
handlePIRTrigger();
if (hallTriggered) {
handleHallTrigger();
hallTriggered = false; // Reset the interrupt flag
}
stepper.run();
}
void hallInterrupt() {
hallTriggered = true;
}
void handlePIRTrigger() {
if (digitalRead(PIR_SENSOR_PIN) == HIGH &&!pirTriggered && millis() - pirStartTime > 10000) {
pirTriggered = true;
if (motorState == 0) { // Only start moving if currently stopped
motorState = 1;
stepper.run(); // Start motor continuously
}
}
}
void handleHallTrigger() {
if (motorState!= 0) { // If moving, stop immediately
stepper.stop();
motorState = 0;
// Check for 4 cycles and reverse
cycleCount++;
if (cycleCount == 4) {
cycleCount = 0;
stepper.move(-stepper.currentPosition()); // Reverse direction using move()
}
pirTriggered = false; // Reset PIR trigger
pirStartTime = millis(); // Start 10-second delay after Hall trigger
}
}
The sensors are working correctly, I tested them in isolation, but they don't seem to play nicely together or I'm missing something.
This is how everything is connected:
