Homing two Stepper Motors with two optical sensors and AccelStepper Libary

Hello everyone,

I am relatively new to this and am stuck with my project.

In my project, I have two stepper motors with magnetic brakes. These motors move a part in the x and y directions. The movement itself works fine, but I want to implement a homing process. The motors should move until the optical sensor triggers, then this position should be set as the zero point.

In my homing function, I use a while loop to move the respective motor until the optical sensor triggers. However, when I start the function, the brakes are released , but the motors do move in very little steps (I assume it is one step per second) although I set an higher speed (int speed is 500). The while loop seems to run correctly, as I even get the feedback that the loop is running. I suspect that something is wrong with my settings in AccelStepper.

Here is my Homing function:

// Homing Process
void home() {
  // Homing X axis
  homeAxis(stepperX, X_BRAKE_PIN, X_HOME_PIN, 500, -100);
  // Homing Y axis
  homeAxis(stepperY, Y_BRAKE_PIN, Y_HOME_PIN, -500, 100);

  // Give feedback when homing complete
  Serial.println("Homing complete");
}

// Homing individual axis
void homeAxis(AccelStepper &stepper, int brakePin, int homePin, int speed, int backoffSteps) {
  stepper.setCurrentPosition(0);
  digitalWrite(brakePin, HIGH); // disable Brakes
  stepper.setSpeed(speed); // Set speed and direction
  Serial.println("function start"); // Test to check if loop function is starting
  while (digitalRead(homePin) == LOW) {   
    stepper.runSpeed();
    Serial.println("loop is running"); // Test to check if loop is running
    delay(1); // Small delay because why not
  }

  
  stepper.stop();
  stepper.setCurrentPosition(0);
  stepper.runToNewPosition(backoffSteps);
  stepper.setCurrentPosition(0);
  digitalWrite(brakePin, LOW);
}

Does anyone have an idea where the problem might be?

Thank you!

Because when the serial output buffer fills, your whole process will stop until there is room for another character in the buffer. Take out this serial.Print() and try it.

and delay not needed too

When I remove Serial.print from the loop, the motor doesn't run at all. Only the brakes disable and enable, and I receive the output "Homing complete".

Edit: Perhaps the motor moves one step, but I cannot accurately determine or verify it.

Then it is time to rethink your whole homing process!

you set too short step pulses
try

stepper.setMinPulseWidth(100);

did not work either.. :confused:

  while (digitalRead(homePin) == LOW) {   
    digitalWrite(stepPin, 1);
    delayMicroseconds(10); 
    digitalWrite(stepPin, 0);
    delayMicroseconds(10); 
  }
  Serial.println("loop done"); // Test to check if loop is running

It might be a hardware problem. I tried using interrupts, but that didn’t work either. Now, I have found a solution that is not elegant but works most of the time. However, even with this solution, the motor sometimes stops before the sensor can even be triggered. I suspect that the sensor might be sending a faulty signal, or there might be a slight error in the sensor signal due to the wiring. Therefore, I tried adding a time delay in the condition of the while loop to bypass a potential faulty signal from the sensor.

I am also attaching my complete code in case someone can spot the error directly or find a solution for themselves.

#include <AccelStepper.h>

// Define stepper motor connections and motor interface type
#define motorInterfaceType 1

// Define the stepper motor control pins
#define X_STEP_PIN     60
#define X_DIR_PIN      61
#define X_ENABLE_PIN   56
#define Y_STEP_PIN     46
#define Y_DIR_PIN      48
#define Y_ENABLE_PIN   62

// Initialize the stepper library
AccelStepper stepperX(motorInterfaceType, X_STEP_PIN, X_DIR_PIN);
AccelStepper stepperY(motorInterfaceType, Y_STEP_PIN, Y_DIR_PIN);

// Define brake pins for X and Y motors
#define X_BRAKE_PIN 45
#define Y_BRAKE_PIN 10

// Stepper Motor
const int steps_per_rev = 200;
const int pitch = 4;

// Define optical sensor (endstop) pins
#define Y_HOME_PIN 19
#define X_HOME_PIN 2

// Cooling Fan
const int pin_fan1 = 7;


void setup() {
  // Set the maximum speed and acceleration:
  stepperX.setMaxSpeed(1000);
  stepperX.setAcceleration(500);
  stepperY.setMaxSpeed(1000);
  stepperY.setAcceleration(500);

  // Disable the motor 
  pinMode(X_ENABLE_PIN, OUTPUT);
  digitalWrite(X_ENABLE_PIN, LOW);
  pinMode(Y_ENABLE_PIN, OUTPUT);
  digitalWrite(Y_ENABLE_PIN, LOW);

  // Configure endstop and brake pins
  pinMode(X_HOME_PIN, INPUT_PULLUP);
  pinMode(Y_HOME_PIN, INPUT_PULLUP);
  pinMode(X_BRAKE_PIN, OUTPUT);
  pinMode(Y_BRAKE_PIN, OUTPUT);

  // Engage brakes initially
  digitalWrite(X_BRAKE_PIN, LOW);
  digitalWrite(Y_BRAKE_PIN, LOW);

  // Cooling Fan
  pinMode(pin_fan1, OUTPUT);
  analogWrite(pin_fan1, 180);

  // Start serial communication
  Serial.begin(9600);
}

void loop() {
  // Check if there is any serial input
  if (Serial.available() > 0) {
    // Read the incoming string
    String command = Serial.readStringUntil('\n');

    // Check if the command is "home"
    if (command.equalsIgnoreCase("home")) {
      Serial.println("Homing begin");
      home();
    }
    // Process X motor commands
    else if (command.startsWith("x")) {
      double distance = command.substring(1).toDouble();
      double steps = distanceToSteps(distance);
      Serial.println("Move X " + String(distance) + " mm or " + String(steps) + " steps");
      moveMotor(stepperX, X_BRAKE_PIN, steps);
    }
    // Process Y motor commands
    else if (command.startsWith("y")) {
      double distance = command.substring(1).toDouble();
      double steps = distanceToSteps(distance);
      Serial.println("Move Y " + String(distance) + " mm or " + String(steps) + " steps");
      moveMotor(stepperY, Y_BRAKE_PIN, steps);
    } else {
      Serial.println("Invalid command");
    }
  }
}

// Convert distance to steps
double distanceToSteps(double distance) {
  return distance * steps_per_rev * 32 / pitch;
}

// Move motor with braking control
void moveMotor(AccelStepper &stepper, int brakePin, double steps) {
  stepper.move(steps);
  digitalWrite(brakePin, HIGH);
  delay(100);
  stepper.runToPosition();
  delay(100);
  digitalWrite(brakePin, LOW);
}

// Homing Process
void home() {
  
  // Homing X axis
  homeAxis(stepperX, X_BRAKE_PIN, X_HOME_PIN, 1000, -500);
  // Homing Y axis
  homeAxis(stepperY, Y_BRAKE_PIN, Y_HOME_PIN, -1000, 500);

  // Give feedback when homing complete
  Serial.println("Homing complete");
}

// Homing individual axis
void homeAxis(AccelStepper &stepper, int brakePin, int homePin, int speed, int backoffSteps) {
  stepper.setCurrentPosition(0);
  digitalWrite(brakePin, HIGH); // disable Brakes
  delay(100);
  stepper.setSpeed(speed); // Set speed and direction
  
  unsigned long startTime = millis();

  while (millis() - startTime < 100 || !digitalRead(homePin)) { // Wait until sensor triggers
    stepper.runSpeed();
    delay(1); // Will not run without delay!

    // Check if interrupt was triggered
    if (digitalRead(homePin) == HIGH) {
      Serial.println("Sensor activated");
      break;
    }
  }
  stepper.stop();
  stepper.setCurrentPosition(0);
  stepper.runToNewPosition(backoffSteps); // Move steps back
  stepper.setCurrentPosition(0); // Set Position to zero
  digitalWrite(brakePin, LOW); // Engage Brakes
}

Thanks, I'm going to try that tomorrow :smiley:

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