MultiStepper - Motor Shield V2.3 - steppers not always synchronized

I am having a tough time getting my steppers to consistently reach their destination at the same time. Certain combinations of positions work perfectly:

I.e.:
positions[0] = 1000;
positions[1] = 50;
followed by:
positions[0] = -100;
positions[1] = 100;
Works fine. Both steppers arrive at their intended destinations at the same time.

But:
positions[0] = 850;
positions[1] = 1450;
followed by:
positions[0] = 0;
positions[1] = 0;
Doesn't work as I would expect. positions[1] is reached way before positions[0] of the other stepper.

With [850,1450], if I increase the max stepper speed from 100 to 200, the steppers actually both run at the same speed until stepper1 reaches its destination. Then stepper2 speeds up and completes. But it will work correctly for the first set of coordinates [1000,50] to [100,100] .

Confused and frustrated.

Arduino Uno
Motor Shield V2.3
200 step 1.8 degree Arduino 12V steppers
Running right at 12V. About .6A draw when the steppers move and .8A when stationary.
AccelStepper 1.58.0
Adafruit Motor Shield V2 Library 1.0.5

Any suggestions greatly appreciated!

Thanks!

// MultiStepper.pde
// -*- mode: C++ -*-
// Use MultiStepper class to manage multiple steppers and make them all move to 
// the same position at the same time for linear 2d (or 3d) motion.

#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>
#include <MultiStepper.h>

Adafruit_MotorShield AFMS(0x60); // Default address, no jumpers

Adafruit_StepperMotor *myStepper1 = AFMS.getStepper(200, 2);
Adafruit_StepperMotor *myStepper2 = AFMS.getStepper(200, 1);

// wrappers for the stepperX
void forwardStep1() {
  myStepper1->onestep(FORWARD, DOUBLE);
}
void backwardStep1() {  
  myStepper1->onestep(BACKWARD, DOUBLE);
}

// wrappers for the stepperY
void forwardStep2() {  
  myStepper2->onestep(FORWARD, DOUBLE);
}
void backwardStep2() {  
  myStepper2->onestep(BACKWARD, DOUBLE);
}

// Wrap the steppers in an AccelStepper object
AccelStepper stepper1(forwardStep1, backwardStep1);
AccelStepper stepper2(forwardStep2, backwardStep2);

MultiStepper steppers;

void setup() {
  Serial.begin(9600);
  AFMS.begin();
  
  // Configure each stepper
  stepper1.setMaxSpeed(100);
  stepper2.setMaxSpeed(100);
  
  // Then give them to MultiStepper to manage
  steppers.addStepper(stepper1);
  steppers.addStepper(stepper2);
}

void loop() {
  long positions[2]; // Array of desired stepper positions
  
  positions[0] = 1000;
  positions[1] = 50;
  //positions[0] = 850;
  //positions[1] = 1450;
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
  delay(1000);
  
  // Move to a different coordinate
  positions[0] = -100;
  positions[1] = 100;
  //positions[0] = 0;
  //positions[1] = 0;
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
  delay(1000);
}

Adafruit seem to impose some code between you and the AccelStepper/Multistepper library.

Have you tried the Multistepper examples without any of the Adafruit stuff?

You would probably be better off using specialized stepper motor drivers such as the Pololu A4988 or Pololu DRV8825. The motor shield is really intended for DC motors.

...R
Stepper Motor Basics
Simple Stepper Code

Thanks Robin2!

It didn't occur to me to look for examples that didn't use AccelStepper/Multistepper. I thought they were required. It appears to me they're just wrapping the Adafruit_MotorShield.h library. I will try using that library directly and see where that leads: Library Reference | Adafruit Motor Shield V2 | Adafruit Learning System

I'll consider moving to the Pololu drivers if I can't make headway eliminating the AccelStepper and Multistepper libraries.

Really appreciate your feedback!
PN

Pablonoob:
It didn't occur to me to look for examples that didn't use AccelStepper/Multistepper.

That is the opposite of what I was trying to suggest. My suggestion is to get rid of the Adafruit stuff and use the examples from the Multistepper library directly.

...R

I'm a bit confused then.

I am under the impression that to use the Motor Shield V2.3 I have to include Adafruit_MotorShield.h

I have tried all the examples labeled with "multistepper" or "stepper" but the only ones I can get a stepper to move with on the Motor Shield V2.3 use Adafruit_MotorShield.h.

Appears I'd have to wire up controllers to get away from the Adafruit libraries?

I have looked at all of the libraries and I have not found any reason for the behavior you are seeing. The .onestep() function in the Adafruit library does not implement any speed constraints. The .runSpeed() function of the AccelStepper library uses the _stepInterval set in .setSpeed(). The MultiStepper library calls .setSpeed() to get each stepper to reach the destination at the same time, based on the maximum of how long it would take each axis to cover its distance at maximum speed. This should set one axis to maximum speed and the others to slower speeds.

Could you have any out-of-date libraries? Go to the library manager (Sketch->Include Library->Manage Libraries...) and select Type; Updatable. Then select each one and click on the Update button.

Pablonoob:
I am under the impression that to use the Motor Shield V2.3 I have to include Adafruit_MotorShield.h

I suspect not, but I have no experience with any motor shield. As I said earlier a specialized stepper driver would be a better choice.

...R