[SOLVED] Reversing Direction and Setting Distance with AccelStepper

I am currently running a very basic program in order to try and get my stepper motor to move and accelerate how I want it to.

I am using an Arduino Uno with a DRV8825 motor driver and Nema 11 stepper.

I have activated 1/16th step resolution and done a quick sum to calculate 1 rotation of the motor = 84.2 steps = 38mm linear movement.

The short code I have written/edited SHOULD move the motor to the desired 'distanceToMove', then move it back the same distance in the opposite direction.

However, when I run the program it moves a fraction over 1 revolution, pauses for the 1 second delay, then moves 1 revolution again in the same direction.

Why is it only moving one revolution for that many steps? Why doesn't (-numberOfSteps) cause it to move in the negative direction? - I have tried simply (-12630) but it still moves in the positive direction.

Here is the code I am using;

#include <AccelStepper.h>

#define STEPPER_X_DIR_PIN 2
#define STEPPER_X_STEP_PIN 3
byte Step16 = 12; //pin 12 enables 1/16th step resolution

// 1mm = (no. of steps per rev)/(linear distance moved per rev)
// 1/16th resolution so 1mm = 3200/38 = 84.2 steps

int distanceToMove = 150; //(mm)
int numberOfSteps = distanceToMove*84.2; 

// Define a stepper and the pins it will use
AccelStepper stepper; 
AccelStepper stepperX(AccelStepper::DRIVER, STEPPER_X_STEP_PIN, STEPPER_X_DIR_PIN);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(Step16, OUTPUT);
  digitalWrite(Step16, HIGH);

  stepper.setMaxSpeed(30000);
  stepper.setAcceleration(6000);

}

void loop() {
  // put your main code here, to run repeatedly:

  // go forwards
  stepper.move(numberOfSteps);
  stepper.runToPosition(); // stepper shall start from speed 200, but it starts from speed 0;

delay(1000);

  // Now go backwards
  stepper.move(-numberOfSteps);
  stepper.runToPosition();

  delay(1000);

}

Thanks for your help!

Will

This calculation

int numberOfSteps = distanceToMove*84.2;

will actually be calculated as

int numberOfSteps = distanceToMove*84;

because you are using integer maths

Assuming it is a 200 step motor then with 1/16th microstepping it will require 3,200 steps for one revolution.

I suggest you start simple, with full steps and get things working so it will do a full turn in both directions.

And try a very much lower maximum speed - perhaps 10 steps per second to start with. And note that the AccelStepper library cannot do very high step rates.

...R
Stepper Motor Basics
Simple Stepper Code

Robin2:
Assuming it is a 200 step motor then with 1/16th microstepping it will require 3,200 steps for one revolution.

It is definitely a 200 step motor and that is what is confusing me. I set it to full step mode and told it to move to '200' but it only moves a 1/4 turn before stopping?

I was able to get it to travel to exact locations when simply running it at a fixed speed. This issue with incorrect movement has only started since trying to accelerate the motor. Any idea why this might be?

#include <AccelStepper.h>

#define STEPPER_X_DIR_PIN 2
#define STEPPER_X_STEP_PIN 3
byte Step16 = 12; //pin 12 enables 1/16th step resolution

// 1mm = (no. of steps per rev)/(linear distance moved per rev)
// 1/16th resolution so 1mm = 3200/38 = 84.2 steps

//int distanceToMove = 150; //(mm)
//float numberOfSteps = distanceToMove*84.2;

// Define a stepper and the pins it will use
AccelStepper stepper; 
AccelStepper stepperX(AccelStepper::DRIVER, STEPPER_X_STEP_PIN, STEPPER_X_DIR_PIN);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

//  pinMode(Step16, OUTPUT);
//  digitalWrite(Step16, HIGH);

  stepper.setMaxSpeed(100);
  stepper.setAcceleration(10);

}

void loop() {
  // put your main code here, to run repeatedly:

  // go forwards
  stepper.move(200);
  stepper.runToPosition(); // stepper shall start from speed 200, but it starts from speed 0;

delay(1000);

//  // Now go backwards
//  stepper.move(-200);
//  stepper.runToPosition();
//
//  delay(1000);

}

What does this version do?

#include <AccelStepper.h>

#define STEPPER_X_DIR_PIN 2
#define STEPPER_X_STEP_PIN 3
byte Step16 = 12; //pin 12 enables 1/16th step resolution

// 1mm = (no. of steps per rev)/(linear distance moved per rev)
// 1/16th resolution so 1mm = 3200/38 = 84.2 steps

//int distanceToMove = 150; //(mm)
//float numberOfSteps = distanceToMove*84.2;

// Define a stepper and the pins it will use
AccelStepper stepper;
AccelStepper stepperX(AccelStepper::DRIVER, STEPPER_X_STEP_PIN, STEPPER_X_DIR_PIN);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

//  pinMode(Step16, OUTPUT);
//  digitalWrite(Step16, HIGH);

  stepper.setMaxSpeed(100);
  stepper.setAcceleration(10);
  
  stepper.move(200);
  stepper.runToPosition(); 

}

void loop() {
 
}

If it still only moves one quarter turn then post a very clear diagram showing how you have everything connected.

...R

Robin2:
If it still only moves one quarter turn then post a very clear diagram showing how you have everything connected.

Yep just a quarter turn.. :confused:

Here's the diagram;

Thanks

willduino:
Yep just a quarter turn.. :confused:

That seems very strange. It appears that the driver is doing 1/4 steps.

Have you tried connecting the micro-stepping pins in the arrangement that would give full steps?

...R

Robin2:
Have you tried connecting the micro-stepping pins in the arrangement that would give full steps?

Full step is all three pins 'LOW' anyway but for good measure I wired them up and set them to LOW but still no difference. I tried another stepper as well but the same problem..

Have you used an Ohmeter to ID the motor leads? Wires from 1 coil to AOUT1 and AOUT2, other pair to BOUT1 and BOUT2. Can you post a link to the motor?

willduino:
I tried another stepper as well but the same problem..

Changing the motor should not make any difference.

Try a different stepper driver - my guess is that the one you have been trying has a fault.

...R

Probably a short on the DRV8825 board or a defective chip - often these are dodgy eBay purchases,
I would not be surprized if some are counterfeit. Generally people seem to find they are fine, but
no-one would expect high levels of quality control for such budget items!

outsider:
Have you used an Ohmeter to ID the motor leads?

Have tried an ohmmeter and they're definitely wired up correctly.

outsider:
Can you post a link to the motor?

This is the motor;

Robin2:
Try a different stepper driver - my guess is that the one you have been trying has a fault.

I got them in a pack of 5 and so far 3 of them have showed the exact same results.

The weird thing is that I've never experienced any problems with them doing linear motion, only trying to accelerate.

willduino:
The weird thing is that I've never experienced any problems with them doing linear motion, only trying to accelerate.

Then post the program that works properly with linear motion

And separately post the program that uses acceleration and does not work properly so we can compare them side by side.

...R

Linear motion;

byte directionPin1 = 2;
byte stepPin1 = 3;

byte ledPin = 13;
int millisbetweenSteps = 15; 

int numberOfSteps = 200;

void setup() { 

  digitalWrite(ledPin, LOW);
  
  delay(2000);

  pinMode(directionPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  
  }

void loop() { 

  digitalWrite(directionPin1, HIGH);

  for(int n = 0; n < numberOfSteps; n++) {
   
    digitalWrite(stepPin1, HIGH);
    digitalWrite(stepPin1, LOW);
   
    delay(millisbetweenSteps);
    
    digitalWrite(ledPin, !digitalRead(ledPin));
    
  }

  delay(1000);

  }

Acceleration;

#include <AccelStepper.h>

#define STEPPER_X_DIR_PIN 2
#define STEPPER_X_STEP_PIN 3
//byte Step16 = 12; //pin 12 enables 1/16th step resolution

// Define a stepper and the pins it will use
AccelStepper stepper;
AccelStepper stepperX(AccelStepper::DRIVER, STEPPER_X_STEP_PIN, STEPPER_X_DIR_PIN);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  stepper.setMaxSpeed(100);
  stepper.setAcceleration(10);
  
  stepper.move(200);
  stepper.runToPosition(); 

}

void loop() {
 
}

I have also just noticed that the two programs turn the motor in opposite directions..

Don't worry about the direction. That is easily fixed.

Just so I am completely clear, are you saying that the "linear" program causes the motor to rotate an exact revolution, pause for 1 second, and repeat?

And, the "acceleration" code causes the motor to move exactly 1/4 turn? - and obviously it does not repeat because the code is in setup()

Also, am I correct to assume that there has been no change to the wiring when you change the code?

I note that the linear program works at 66.67 steps per second (one step every 15 millisecs) and the acceleration program is set for 100 steps per second. I can't see that it makes a difference, but change the acceleration program just to make sure.

...R

Robin2:
Just so I am completely clear, are you saying that the "linear" program causes the motor to rotate an exact revolution, pause for 1 second, and repeat?

And, the "acceleration" code causes the motor to move exactly 1/4 turn? - and obviously it does not repeat because the code is in setup()

Also, am I correct to assume that there has been no change to the wiring when you change the code?

Yes all of that is exactly correct.

I changed the max speed of the acceleration program to match the linear motion program but as you suspected, there was no difference there..

The project deadline that this system is intended for is approaching quite rapidly so I think I may just make a start on the positioning using 800 steps/revolution and maybe a solution will be found later..

However the other problem I encountered which I listed at the top of this thread was getting the motor to reverse direction with the AccelStepper library. Could you please indicate how this is done? As I said, I have tried moveTo(-200) for example, but the negative makes no difference to the direction of rotation.

Thanks,
Will

BOTH ISSUES SOLVED.

I had defined the stepper as 'stepperX' when initialising pins and then proceeded to refer to just 'stepper' throughout the program.

For whatever reason this was causing the motor to only do a quarter turn - it is now working as it should.

Reversing the motion with a (-) is now working also.

Thanks for your help!

I had not noticed this (from Reply #12

AccelStepper stepper;
AccelStepper stepperX(AccelStepper::DRIVER, STEPPER_X_STEP_PIN, STEPPER_X_DIR_PIN);

You have actually created two separate AccelStepper instances, one called stepper and one called stepperX.

I presume you realize that you only need to create one instance for one motor.

...R

Robin2:
I presume you realize that you only need to create one instance for one motor.

I do now.. the code that was from was cut from code I found elsewhere. My understanding of the AccelStepper library is now much better and I realise why that was not working!