I am trying to run two stepper motor at same time with different RPM. I decided to use two rotary encoder for change the RPM separately.

But, I am in problem with driving stepper at same time due to the delay time of the step pulse.

How can I generate separate(different duty cycle) step pulses for stepper motors? It's the main problem that I faced.

I have used some Arduino libraries and all of that library has same system for step pulse generation. But, I couldn't understand those well.

void AH_EasyDriver::setSpeedRPM(long RPM)
   float DIV = RPM*this->MOTOR_RESOLUTION;  
    this->STEP_DELAY =  60000000.0L/DIV;

This function calculate the step time for given specific RPM

void AH_EasyDriver::move(int NUMBER_OF_STEPS)
   while(STEPS > 0) {
    if (micros() - this->LAST_STEP_TIME >= this->STEP_DELAY) {
      this->LAST_STEP_TIME = micros();


This function rotate the motor the motor in STEP_DELAY using stepMotor() function.

void AH_EasyDriver::stepMotor()
  digitalWrite(this->STEP_pin, HIGH);
  digitalWrite(this->STEP_pin, LOW);

This function makes CONSTANT step pulses.

I removed some lines in the function. This is the link for original .cpp file. All of stepper controlling libraries has this functions. I couldn't understand how this functions can change the RPM. Can someone explain this?

  • 1
    This is a complex task; if you want to see an example of multi-motor coordinated movement, look at an open-source Arduino based 3d printer or light duty CNC machine firmware. – Chris Stratton Apr 2 '18 at 17:52

When using a normal stepper driver, you say the driver to do one step, by sending him one pulse. The length of these pulses does not have a meaning. they are constructed, so that the driver can sense them. The driver does not make smaller steps than 1 full step, if you don't tell him on extra pins (The library you use can utilize those pins too). So the stepMotor() function is correct. You can drive the motors with different speeds by doing a step for each motor in different intervals (different number of steps per time).

Your move() function blocks the execution of other code, until the motion is completed. You are doing this with the while( STEPS > 0 ) loop. You need to modify your code to be non-blocking. This is normally done in the way, that is shown by the BlinkWithoutDelay example of the Arduino IDE. You are using it too: You have to use the millis() or micros() function, to check if it is time to do a step.

Replace the while with an ´if´-statement:

if( STEPS > 0 )

and make the STEPS variable a member variable of the class instance. Then make sure you execute the function often enough, so that it will not miss the time to do a step. Do the same with the second motor. For example something that looks like this:

void setup(){

void loop(){

Here in the setup function the steppers are told to move 100 and 200 steps. (You would have to write the function doSteps(int number_of_steps) yourself). The motion is then done by the move() functions, when it is time to do so. Since these two functions are looped very fast, they shouldn't miss the time for a step.

This is also the way the AccelStepper library works, which is also a common stepper library.

  • While the width of a step pulse might not matter within limits, the time between pulses is extremely important, and not trivial to achieve for multiple motors. You don't seem to be explaining a viable mechanism for accomplishing that. – Chris Stratton Apr 2 '18 at 17:51
  • I'm not sure how you mean this. In my understanding the driver goes one step, when it counts one pulse. You do pulses in a slow or faster series, depending on how fast the stepper should run. Surely it this not a method for high speed/high precision, but a way you can go, if the circumstances aren't too tough. Maybe I have misunderstood something how the driver works. Please correct me. I can then edit or remove my answer if it is wrong – chrisl Apr 2 '18 at 19:39
  • In the real world it is often necessary to make coordinated moves between two motors, for example imagine a circle in X and Y axis. – Chris Stratton Apr 2 '18 at 19:44
  • For doing such a motion you would have to modulate the speed of the motors (essentially making the time between the pulses depending on a function). But the OP used it in a more simple way. I think the more complex functionality of drawing circles or anything else is out of the scope of this question. – chrisl Apr 2 '18 at 19:56
  • Though it can also be done with my method by varying the speed of the motors during the motion. But the used function of this library are not good for this, I think – chrisl Apr 2 '18 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.