Motors Don't Run At Defined Speed

Hi I’m trying to run 2 motors at the same speed simultaneously with 1 button. I wrote a code for 1 motor first and it runs just fine, but when I added the second motor, both motors run at the same time but the speed caps around 3000 to 4000 step per second and any number higher would not change the speed. Lower speeds are controllable. The speed and acceleration in both codes are exactly the same.

both motors’ resolutions are 1/8 step.

I wonder if it has anything to do with the run function of AccelStepper. I found this tutorial (brainy bits tutorial), it used 2 run functions one after another and worked, so I thought I don’t have to use state machines to run 2 motors simultaneously.

Here is my code for 1 motor, and a video of what it looks like when it runs.
1 motor video

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

AccelStepper stepperB (1,10,11);

int buttonPin = 2;
int stopPin = 3;
int ledPin = 12;

int val;
int val2;
int buttonState;
int motorMode = 0;

void setup() {
  Serial.begin(9600);
  
  stepperB.setMaxSpeed(9600);
  stepperB.setAcceleration(5000);

  pinMode(buttonPin, INPUT);
  buttonState = digitalRead(buttonPin);

  pinMode(stopPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(stopPin), QuickStop, CHANGE);

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,LOW);
}

void loop() {
  val = digitalRead(buttonPin);
  delay(10);
  val2 = digitalRead(buttonPin);
  if (val == val2) {
    if(val != buttonState){
      if (val == HIGH) {
        if (motorMode == 0) {
          motorMode = 1;
        } else {
          motorMode = 0;
        }
      }
  }
 }

  while (motorMode == 1 && stepperB.currentPosition()<25000) {
    digitalWrite(ledPin, HIGH); 
    stepperB.moveTo(25000);

    stepperB.run();
 }
 motorMode = 0;
 stepperB.setCurrentPosition(0);
}

void QuickStop() {
  digitalWrite(ledPin, LOW);
  
// code in progress
}

Here’s my code for 2 motors, and what they look like when they run.
2 motors video

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

AccelStepper stepperA (1,8,9);
AccelStepper stepperB (1,10,11);

int buttonPin = 2;
int stopPin = 3;
int ledPin = 12;

int val;
int val2;
int buttonState;
int motorMode = 0;

void setup() {
  Serial.begin(9600);
  
  stepperA.setMaxSpeed(9600);
  stepperA.setAcceleration(5000);

  stepperB.setMaxSpeed(9600);
  stepperB.setAcceleration(5000);

  pinMode(buttonPin, INPUT);
  buttonState = digitalRead(buttonPin);

  pinMode(stopPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(stopPin), QuickStop, CHANGE);

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,LOW);
}

void loop() {
  val = digitalRead(buttonPin);
  delay(10);
  val2 = digitalRead(buttonPin);
  if (val == val2) {
    if(val != buttonState){
      if (val == HIGH) {
        if (motorMode == 0) {
          motorMode = 1;
        } else {
          motorMode = 0;
        }
      }
  }
 }

  while (motorMode == 1 && stepperA.currentPosition()<25000 && stepperB.currentPosition()<25000) {
    digitalWrite(ledPin, HIGH); 
    stepperA.moveTo(25000);     
    stepperB.moveTo(25000);
    
    stepperA.run();
    stepperB.run();
 }
 motorMode = 0;
 stepperA.setCurrentPosition(0);
 stepperB.setCurrentPosition(0);
}

void QuickStop() {
  digitalWrite(ledPin, LOW);
  
// code in progress
}

There's a good chance you don't have enough horsepower to run two stepper motors that fast with 1/8 stepping and acceleration.

Are you using an Uno, or something faster like a Due or Teensy? AccelStepper needs a fast microcontroller.

Yes, AccelStepper has a maximum step rate due to use of floating point, and because it relies on
you calling run() methods frequently enough which may be a problem if you have other hardware
to handle that takes time.

Thank you for the replies.

ytmnic:
There's a good chance you don't have enough horsepower to run two stepper motors that fast with 1/8 stepping and acceleration.

Are you using an Uno, or something faster like a Due or Teensy? AccelStepper needs a fast microcontroller.

I'm using Arduino Mega, and a A4988 for each stepper motor. Should I use a faster microcontroller or even rasberry pi? I have a 3D printer and it runs 3 stepper motors with acceleration at the same time with Arduino Mega, that's why I thought this is possible. Is it because they don't hit that high of an RPM or they have a more efficient algorithm?

MarkT:
Yes, AccelStepper has a maximum step rate due to use of floating point, and because it relies on
you calling run() methods frequently enough which may be a problem if you have other hardware
to handle that takes time.

So if I want to run multiple stepper motors at fast speeds simultaneously with acceleration, accelStepper is not the way to go? Is there a better code for acceleration or do I need to upgrade hardware?

Thank you again for you time.

From AccelStepper Class Reference

The fastest motor speed that can be reliably supported is about 4000 steps per second at a clock frequency of 16 MHz on Arduino such as Uno etc. Faster processors can support faster stepping speeds. However, any speed less than that down to very slow speeds (much less than one per second) are also supported, provided the run() function is called frequently enough to step the motor whenever required for the speed set. Calling setAcceleration() is expensive, since it requires a square root to be calculated.

Gregor Christandl reports that with an Arduino Due and a simple test program, he measured 43163 steps per second using runSpeed(), and 16214 steps per second using run();

So a Due or a Teensy would be fast enough for you, or no acceleration with your current hardware.

ytmnic:
From AccelStepper Class Reference

So a Due or a Teensy would be fast enough for you, or no acceleration with your current hardware.

Thank you so much! I will try my code with a Due.

ratherwok:
Should I use a faster microcontroller or even rasberry pi? I have a 3D printer and it runs 3 stepper motors with acceleration at the same time with Arduino Mega, that's why I thought this is possible. Is it because they don't hit that high of an RPM or they have a more efficient algorithm?

AccelStepper uses floats, which is unfortunately bad news on an 8 bit microcontroller with no
float support.

There are ways to do this without float calculations per step (for instance using a look up table), but
that consumes RAM. Another approach is DDS style step sequencing which is easy integer operations
but needing a timer interrupt running at a fairly high frequency.

works on the 328 ok if youre not trying to sync two steppers, ie 2 axis

Atmel stepper code.pdf (153 KB)