1

I have three stepper motors connected to the drv8825 drivers to an arduino uno.

I am using the example code below (from here), which works fine for moving multiple stepper motors at the same time BUT they all move for the same number of steps and in the same direction. I would like to tweak the code so that all of them move at the same time but each one for a different number of steps and in different directions. The motor with the least steps would probably have to wait for the motor with the most steps to finish its movement before going again.

int dirPin = 8;
int stepperPin = 7;
int bdirPin = 6;
int bstepperPin = 5;

void setup() {
 pinMode(dirPin, OUTPUT);
 pinMode(stepperPin, OUTPUT);
 pinMode(bdirPin, OUTPUT);
 pinMode(bstepperPin, OUTPUT);
}
 void step(boolean dir,int steps){
 digitalWrite(dirPin,dir);
 digitalWrite(bdirPin,dir);
 delay(50);
 for(int i=0;i<steps;i++){
 digitalWrite(stepperPin, HIGH);
 digitalWrite(bstepperPin, HIGH);
 delayMicroseconds(800);
 digitalWrite(stepperPin, LOW);
 digitalWrite(bstepperPin, LOW);
 delayMicroseconds(800);
 }
}
void loop(){
 step(true,1600);
 delay(500);
 step(false,1600*5);
 delay(500);
}

Thank you in advance for your help!

James Waldby - jwpat7
  • 8,840
  • 3
  • 17
  • 32
the_plds
  • 13
  • 1
  • 1
  • 5

3 Answers3

2

You need a struct for each stepper with a timestamp, a position and rate of change and a loop that updates the postion based on rate which is the change in position over some time:

struct stepper {
  unsigned long timestamp;
  int position;
  int rate;
};

// init steppers array

while (keepGoing()) {
  unsigned long now = millis();
  int si;

  delay(10);

  for (si = 0; si < 3; si++) {
    struct stepper *stepper = &steppers[si];

    if (steppers[si].timestamp > now) {
       steppers[si].position += steppers[si].rate;
       steppers[si].timestamp = now + 100;
    }
  }

This is a back-of-a-napkin sketch of course. It is only supposed to illustrate how you can update any number of things concurrently.

The important thing is that you only call delay once. And presumably it would be only a very short delay compared to the unit of time for the rate. In the above example it would adjust the stepper position every 100ms. You would need to experiment with the timing to find a good behavior given the speed of the stepper, speed of the code and maximum permitted rate.

Beware that there is a lot to think about beyond this. For example, you should initialize the timstamps with different timestamps so that the motors are not all running at the same instant and thus try to minimize the total power consumed by the motors at any particular time.

Note that I have never played around with stepper motors but this type of loop is a common programming idiom for handling things concurrently.

squarewav
  • 191
  • 5
  • Your stepper pointer is a good idea: using it would make the code shorter and easier to read. But you forgot to use it... 2. You should not compare timestamps: this is bound to fail when millis() rolls over. You should compare durations instead.
  • – Edgar Bonet Feb 07 '16 at 09:12