A4988 could not control accurate direction

Hi,
I want the stepper motor to move one time clockwise and then one time anti-clockwise. It look likes back and forth.
But I found that the motor sometimes move two times clockwise or anti-clockwise.
I use AccelStepper library. Here is my code. Please help.

#include <AccelStepper.h>
int dir = 1;
int pos = 600;

AccelStepper stepper(1, 2, 3);

void setup() {
  pinMode(7,OUTPUT); //MS1
  pinMode(6,OUTPUT); //MS2
  pinMode(5,OUTPUT); //MS3
  digitalWrite(7,LOW);
  digitalWrite(6,LOW); 
  digitalWrite(5,LOW); 

  stepper.setMaxSpeed(9000);
  stepper.setAcceleration(13000);
}

void loop() {  

if(stepper.distanceToGo()==0)
{ 
  stepper.move(pos*dir);
  dir = dir*(-1);
  delay(200); 
}

stepper.run();
  
}

You forgot to post the motor type and characteristics, wiring diagram (schematic, not Fritzing) and power supply characteristics.

I follow the web's diagram.

I use an arduino nano and a 16v/1.2A power supply.
A4988 Vref is 0.6V

I suggest you arrange for your code to print the value of pos*dir so that you can see what might be causing the problem.

...R

You must not use delay(), nothing happens to the motor during delay.

The run() method must be called very frequently, at least every time through loop() and avoid
any delay() calls.

Why use dir and why multiply to negate, why not the simple:

  if(stepper.distanceToGo()==0)
  {
    stepper.move (pos) ;
    pos = -pos ;
  }
  stepper.run () ;

MarkT:
You must not use delay(), nothing happens to the motor during delay.

That occurred to me, but in this case the delay() is only called when the motor is stopped.

...R

Robin2:
That occurred to me, but in this case the delay() is only called when the motor is stopped.

...R

No, delay() is called after a call to move(), so its intended to do the move....

MarkT:
No, delay() is called after a call to move(), so its intended to do the move....

I have looked at the code again. The call to stepper.run() is unaffected by the delay() as far as I can see.

Or, perhaps, the delay() should go before the call to stepper.move() so that it can immediately go from stepper.move() to stepper.run().

...R

I have looked at the code again. The call to stepper.run() is unaffected by the delay() as far as I can see.

Look again - delay is called between move and run, so the AccelStepper library ramping calculations will
be nonsensed I reckon.

if(stepper.distanceToGo()==0)
{
  stepper.move(pos*dir);
  dir = dir*(-1);
  delay(200);
}

stepper.run();

The ramp is calculated w.r.t. the time move() is called and run() has to run often enough
to be able to feed out the actual steps in realtime.

MarkT:
The ramp is calculated w.r.t. the time move() is called and run() has to run often enough
to be able to feed out the actual steps in realtime.

Then I'm guessing that this would be OK - and would have the effect the OP is looking for.

if(stepper.distanceToGo()==0)
{
  delay(200);
  stepper.move(pos*dir);
  dir = dir*(-1);
}

stepper.run();

...R