Drive stepper motors at different speed

I want to run two stepper motors using a CNC shield with a DRV8825 driver. The condition is, the first motor will increase the speed (for example 50 to 200rpm) and need to complete 5revloutions. At the same time, the second motor will maintain a constant speed for 5revloutions (for example 150rpm). Once the code is started both motors will go in the forward direction and the 1sec delay then will be in the reverse direction.

Any suggestions? Sorry, I am a beginner in coding.

either there is a library function where you can specify a speed or you can modify a delay/timer value between steps

@vasanthk230

you should not open a second thread on the same question.
This is called cross-posting.
If repeat cross-posting you are in danger of getting temporarly or permanent banned from the forum.

I flag this thread to the moderator that the moderator should merge the two threads

This ithe other thread where you already received some answers
https://forum.arduino.cc/t/2-stepper-motors-at-different-speed/1089752/7

best regards Stefan

Hi Stefan,

I am sorry. Herein anymore I will follow the same. Thank you.

Regards,
Vasanth

Hi everyone,

I am Vasanth. I am a beginner at Arduino.

I wanted to implement, two stepper motors that will start at the same time and also will stop at the same time. But the stepper motor 1 will run different speed (gradually increase the speed from 60 to 200 rpm). And also, stepper motor 2 will run at constant speed at 200rpm.

Both stepper motors can be triggered by Push-button. Once the button is pressed both motors will start moving.

I tried stepper motor1 coding. It's fine working now. I don't know what to do for stepper motor 2.

Any leads will be very useful for me.

This is my code for stepper motor 1:

const int A = 8;
const int A_bar = 9;
const int B = 10;
const int B_bar = 11;
const int steps1 = 200;
void setup() {
pinMode(A, OUTPUT);
pinMode(A_bar, OUTPUT);
pinMode(B, OUTPUT);
pinMode(B_bar, OUTPUT);
pinMode(A0, INPUT_PULLUP);
}
void motor1() {
if (digitalRead(A0) == LOW) {
for (int x = 3500; x >= 1500; x = x - 500) {
for (int i = 0; i < (steps1 / 4); i++) {
digitalWrite(A, HIGH);
digitalWrite(A_bar, LOW);
digitalWrite(B, HIGH);
digitalWrite(B_bar, LOW);
delayMicroseconds(x);

    digitalWrite(A, LOW);
    digitalWrite(A_bar, HIGH);
    digitalWrite(B, HIGH);
    digitalWrite(B_bar, LOW);
    delayMicroseconds(x);


    digitalWrite(A, LOW);
    digitalWrite(A_bar, HIGH);
    digitalWrite(B, LOW);
    digitalWrite(B_bar, HIGH);
    delayMicroseconds(x);


    digitalWrite(A, HIGH);
    digitalWrite(A_bar, LOW);
    digitalWrite(B, LOW);
    digitalWrite(B_bar, HIGH);
    delayMicroseconds(x);

    }
  }
}  

}

void loop(){
motor1();
}

Do the same code for the second stepper motor. By the way, to make your program more readable and easier to debug, use meaningful names for your pins and for variables.

Hi Paul,

Thank you very much for your reply.

But, the stepper motor 2 has to operate at a constant speed. If I do the stepper motor 2 also the same code I provide, first stepper motor 1 will run then follow stepper motor 2. But I want to run both stepper motors at the same time.

Any idea, Paul ..?

Thank you for your valuable time.

Regards,
Vasanth

Try this.
For every stepper motor 1 line of code, add a similar line of code for motor 2. Then begin to debug the code if you find problems. Motor 2 can be slowed by making the delay after a step pulse a bit linger than the same for motor 1.

Hi @vasanthk230,

welcome to the arduino-Forum.

Do you use the two stepper-motors for exact positioning something or for something else?
You should post an overview about what your project is.
Depending on your overall project different solutions fit best.

It is very likely that using the MobaTools-library will make driving the two stepper-motors much easier.

The MobaTools-library creates the step-pulses based on a timer-interrupt in the background.

You do a simple single call of a function and the library is creating all the step-pulses.
infinitely or a specified amount of steps

whenever you want to stop the motors make a single call to function .stop()

If you want to move two stepper-motors based on elementary function-calls like
digitalWrite()

Your can't use two for-loops. You have to use a single loop and the best thing is to use void loop() as the loop that is looping because

void loop() IS looping anway all the time

You have two functions. One for motor1 one for motor2
These two functions were repeatedly called by
void loop()

with each call of these two functions the following things must be done:

1.) checking if enough time has passed by to create the next step
2.) if the time has come to do a step going one further in the switching sequence switching the outputs LOW/HIGH

this means void loop() must run very fast to be able to check multiple times faster if it is time to create a new step and if the time has come to do so.

All these details are managed by the mobatools-library and you don't have to care about these details

The mobaTools-library can be installed with the library-manager of the arduino-IDE

If you post precise information how the gradually changing speed shall happen I can write a small demo-code that shows how this can be coded with the mobatools-library

example-description for gradually changing speed:
starting at 60 rpm and once every 10 seconds increase speed by 1 rpm

0:00 60 rpm
0:01 60 rpm
0:02 60 rpm
...
0:09 60 rpm
0:10 61 rpm
0:11 61 rpm
0:12 61 rpm
...
0:19 61 rpm
0:20 62 rpm
etc.
or you draw a timing-diagram that shows it

best regards Stefan

But don’t use delay()

It sounds like stepper motors may not be the best choice of motor for your application.

Look into the Bresenham algorithm. Since motor2 runs at 200RPM and is Motor1 is no faster than motor2, every time you do a motor2 step, you either do a motor1 step or wait.

From looking at your code, maybe 1500us/step is your fastest step rate. 1500us per step at 200RPM gives 60*1e6/1500= 40000steps/min, divided by 200rev/min = 200 step/rev.

The Bresenham line-drawing algorithm keeps track of the different times in order to know when to step the slower device coordinated with the faster device. So you accumulate the 200us for each step of the faster motor, and whenever the sum gets higher than the step interval for the slower motor, you step it and subtract its interval from the Bresenham sum.

I'm confused about your speed changing logic, but it looks like it changes every quarter turn of the slower motor.

Here is some untested snippets of code.

const uint32_t interval = 1500; //us
uint32_t slowInterval = 3500; // us for slower-speed motor
uint32_t last = 0;
int bres = 0;  // bresenham sum.
int running = 0; // start off not running
uint32_t stepsA = 0;
uint32_t stepsB = 0;

void loop(void){
  uint32_t now = micros();
  
  if (!running && digitalRead(A0){
   running = 1;
   slowInterval = 3500;
  }

  if(running && now - last >= interval){
     last = now;
     bres+= interval;
     stepsA++;
     doStepA();
     if (bres >= slowInterval){
        bres -= slowInterval;
        stepsB++;
        doStepB();
     }
   }
   // adjust slowInterval based
   slowInterval = 3500 - 500*(stepsB%50);
}

void doStepA(void){
    digitalWrite(A, LOW);
    digitalWrite(A_bar, HIGH);
    digitalWrite(B, LOW);
    digitalWrite(B_bar, HIGH);
}
...

Without answering to the question you have been ask to specify more precise what you exactly want
here a little demo-sketch that shows how to run two stepper-motors an different speeds.

I keep this posting short to put you into the situation of having additional questions to really understand.

/* ====== minimumStepper =======================================
 *  Bare minimum to get a stepper with step/dir driver turning
 */
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.
const byte stepPin1 = 6; // muss je nach microcontroller evtl. angepasst werden
const byte dirPin1  = 5; // muss je nach microcontroller evtl. angepasst werden

const byte stepPin2 = 7; // muss je nach microcontroller evtl. angepasst werden
const byte dirPin2  = 8; // muss je nach microcontroller evtl. angepasst werden

const int stepsPerRev = 200;    // Steps per revolution - may need to be adjusted

MoToStepper stepper1( stepsPerRev, STEPDIR );  // create a stepper instance
MoToStepper stepper2( stepsPerRev, STEPDIR );  // create a stepper instance

void setup() {
  stepper1.attach( stepPin1, dirPin1 );
  stepper1.setSpeed( 300 );              // 30 rev/min (if stepsPerRev is set correctly)
  stepper1.setRampLen( stepsPerRev / 2); // Ramp length is 1/2 revolution

  stepper2.attach( stepPin2, dirPin2 );
  stepper2.setSpeed( 800 );              // 30 rev/min (if stepsPerRev is set correctly)
  stepper2.setRampLen( stepsPerRev / 2); // Ramp length is 1/2 revolution
  
  stepper1.rotate(1);                    // start turning, 1=vorward, -1=backwards                    
  stepper2.rotate(1);                    // start turning, 1=vorward, -1=backwards                    
}

void loop() {
}

You should post a timing chart that shows timely dependencies of the two motors, delays() etc.

best regards Stefan

Hello Dave,

Thank you for your reply. I am not familiar Bresenham algorithm.

My condition is, want to synchronize two stepper motors. One motor will increase the speed gradually (for example 50rpm to 200rpm) and the other will maintain a constant speed (for example 200rpm). Both motors have to start and end time will be same. I am using CNC shield with DRV8825 driver.

Any suggestions Dave..??

Thank you.

Regards,
Vasanth

bresenham is for a constant difference in speed.
You are describing a permantly changing difference in speed.

You did not specifiy in any way how long it takes for the second motor to increase speed from 50 rpm to 200 rpm
you did not describe in how many steps of the constant rotating stepper-motor that runs at 200 rpm the rpm-increasing from 50 rpm to 200 rpm shall happen

This information is needed to give more detailed advice

Hi Stefan,

Thank you for your reply.

Within 5 sec (for both Motor 1 and Motor 2), I want to achieve 5 revolutions.

For the constant motor, steps will be 200 steps/revolution, and for the variable speed motor 400 steps/revolution.

Your two or more topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you also take a few moments to Learn How To Use The Forum.

It will help you get the best out of the forum in the future.

  • Your OS and version can be valuable information, please include it along with extra security you are using.

  • Always list the version of the IDE you are using and the board version if applicable.

  • Use quote or add error messages as an attachment NOT a picture.

  • How to insert an image into your post. ( Thanks @sterretje )

  • Add your sketch where applicable but please use CODE TAGS ( </> )

  • Add a SCHEMATIC were needed even if it is hand drawn

  • Add working links to any specific hardware as needed (NOT links to similar items)

  • Remember that the people trying to help cannot see your problem so give as much information as you can

COMMON ISSUES

  • Ensure you have FULLY inserted the USB cables.

  • Check you have a COMMON GROUND where required. ( Thanks @Perry)

  • Where possible use USB 2.0 ports or a USB 2.0 POWERED HUB to rule out USB 3.0 issues.

  • Try other computers where possible.

  • Try other USB leads where possible.

  • You may not have the correct driver installed. CH340/341 or CP2102 or FT232 VCP Drivers - FTDI

  • There may be a problem with the board check or remove your wiring first.

  • Remove any items connected to pins 0 and 1.

COMPUTER RELATED

  • Close any other serial programs before opening the IDE.

  • Ensure you turn off any additional security / antivirus just to test.

  • There may be a problem with the PC try RESTARTING it.

  • You may be selecting the wrong COM port.

  • Avoid cloud/network based installations where possible OR ensure your Network/Cloud software is RUNNING.

  • Clear your browsers CACHE.

  • Close the IDE before using any other serial programs.

  • Preferably install IDE’s as ADMINISTRATOR or your OS equivalent

ARDUINO SPECIFIC BOARDS

  • CH340/341 based clones do not report useful information to the “get board info” button.

  • NANO (Old Types) some require you to use the OLD BOOTLOADER option.

  • NANO (ALL Types) See the specific sections lower in the forum.

  • NANO (NEW Types) Install your board CORE’s.

  • Unless using EXTERNAL PROGRAMMERS please leave the IDE selection at default “AVRISP mkII”.

  • Boards using a MICRO usb connector need a cable that is both DATA and CHARGE. Many are CHARGE ONLY.

CREATE editor install locations.

  • On macOs ~/Applications/ArduinoCreateAgent-1.1/ArduinoCreateAgent.app/Contents/MacOS/config.ini

  • On Linux ~/ArduinoCreateAgent-1.1/config.ini

  • On Windows C:\Users[your user]\AppData\Roaming\ArduinoCreateAgent-1.1

Performing the above actions may help resolve your problem without further help.

Language problem ?

Try a language closer to your native language:

Thanks to all those who helped and added to this list.

The Bresenham line drawing algorithm is good for coordinating the motion of discrete steps based on the slope between the variables. It is good for Steppers because it each time it makes a discrete step with the faster stepper, it decides whether or not to move the slower motion.

Can you sketch a graph of how you want the speeds (or positions) to behave?

A back-of-the-envelope sketch with times on the X-axis, and speeds of the two motors on the Y axis is what I'm asking for.

Even if the speed is constantly changing, at any particular point in time, there is a slope between the two variables. A non-constant speed would mean that the ratio between the steps would change, and you could change that ratio by varying the dx or dy in the Bresenham algorithm. If that's not essentially Bresenham, maybe we could call it the DaveX curved line drawing algorithm.

Hi Dave,

Here is my sketch.

The drawing certainly does not match these descriptions

My condition is, want to synchronize two stepper motors. One motor will increase the speed gradually (for example 50rpm to 200rpm) and the other will maintain a constant speed (for example 200rpm).

Within 5 sec (for both Motor 1 and Motor 2), I want to achieve 5 revolutions.
For the constant motor, steps will be 200 steps/revolution, and for the variable speed motor 400 steps/revolution.

Please try to provide a consistent definition of what you want.

1 Like

Hi,

Thank you very much for your reply.

Both motors need to complete the revolutions in 5 sec. One motor will maintain a constant speed (linear) and another motor will gradually increase the speed (non-linear).