Slow code, makes slow steppers?

Hi all,

Im trying to make a program. It will control five axis driven by steppers. The steppers should all reach there final position at the same time independet off how far they have to travel. Right now i do this by calculating the biggest amount of steps a motor have to do. And then i calculate how many steps each motor have to do for each step of the biggest move. This is done by using the map function which seem to make the code very slow and therefore i cannot rotate the motors as fast as i want.

do you have any suggestion on how to simplify it or other solution?

edit:you should look at the code under the comment "//for loop handle stepping"

  //pos axlar
  int pos1 = 0;
  int pos2 = 0;
  int pos3 = 0;
  int pos4 = 0;
  int pos5 = 0;


  //stores most amount of steps in a move
  int mostStep;
  //stores which axle, not in use ccurrently
  int longestAxle;

  //delay between step pin high and low
  const int delayStep = 1;

  //stepper drivare
  const int stepPin1 = 22; 
  const int dirPin1 = 23; 
  const int enPin1 = 24;

  const int stepPin2 = 25; 
  const int dirPin2 = 26; 
  const int enPin2 = 27;

  const int stepPin3 = 28; 
  const int dirPin3 = 29; 
  const int enPin3 = 30;

  const int stepPin4 = 31; 
  const int dirPin4 = 32; 
  const int enPin4 = 33;

  const int stepPin5 = 34; 
  const int dirPin5 = 35; 
  const int enPin5 = 36;

void setup() {
  // put your setup code here, to run once:

  pinMode(stepPin1, OUTPUT);
  pinMode(dirPin1, OUTPUT);
  pinMode(enPin1, OUTPUT);

  pinMode(stepPin2, OUTPUT);
  pinMode(dirPin2, OUTPUT);
  pinMode(enPin2, OUTPUT);

  pinMode(stepPin3, OUTPUT);
  pinMode(dirPin3, OUTPUT);
  pinMode(enPin3, OUTPUT);

  pinMode(stepPin4, OUTPUT);
  pinMode(dirPin4, OUTPUT);
  pinMode(enPin4, OUTPUT);

  pinMode(stepPin5, OUTPUT);
  pinMode(dirPin5, OUTPUT);
  pinMode(enPin5, OUTPUT);

  //enable drivers
  digitalWrite(enPin1, LOW);
  digitalWrite(enPin2, LOW);
  digitalWrite(enPin3, HIGH);
  digitalWrite(enPin4, HIGH);
  digitalWrite(enPin5, HIGH);


  Serial.begin(9600);
  Serial.println("starta");
}

void loop() {
  // put your main code here, to run repeatedly:

  //move command (delay between step cycles, join1, joint2, joint3, joint4, joint5)
  movJ(1, 500, 300, 50, 30, 30);
  delay(10000);

}

//moves axles
void movJ(int sped, int newPos1, int newPos2, int newPos3, int newPos4, int newPos5){

  //calculates most amount of step on an axle in the move and also which axle, stores in global variable
  longest(newPos1, newPos2, newPos3, newPos4, newPos5);

  //tar fram axeln som är långsammast och tid  spara till slowestAxle, slowesTime
  //slowest(newPos1, newPos2, newPos3, newPos4, newPos5);


  //determines direction off move and sets driver accordingly
  if(newPos1-pos1 > 0){
    //step positiv
    digitalWrite(dirPin1, HIGH);
  }else{
    //step negativ
    digitalWrite(dirPin1, LOW);
  }
  if(newPos2-pos2 > 0){
    //step positiv
    digitalWrite(dirPin2, HIGH);
  }else{
    //step negativ
    digitalWrite(dirPin2, LOW);
  }
  if(newPos3-pos3 > 0){
    //step positiv
    digitalWrite(dirPin3, HIGH);
  }else{
    //step negativ
    digitalWrite(dirPin3, LOW);
  }
  if(newPos4-pos4 > 0){
    //step positiv
    digitalWrite(dirPin4, HIGH);
  }else{
    //step negativ
    digitalWrite(dirPin4, LOW);
  }
  if(newPos5-pos5 > 0){
    //step positiv
    digitalWrite(dirPin5, HIGH);
  }else{
    //step negativ
    digitalWrite(dirPin5, LOW);
  }

  
  //stores how many steps we have taken from last position
  int currPos1 = 0;
  int currPos2 = 0;
  int currPos3 = 0;
  int currPos4 = 0;
  int currPos5 = 0;

  //for loop handle stepping

  for(int i = 1; i <= mostStep ; i++){
    //time between step cycles
    delayMicroseconds(sped);

    //testprint
    Serial.println(map(i, 0, mostStep, 0, abs(pos1-newPos1)));

    if(map(i, 0, mostStep, 0, abs(pos1-newPos1)) > currPos1){
      //step axle 1
      digitalWrite(stepPin1, HIGH);
      delayMicroseconds(delayStep);
      digitalWrite(stepPin1, LOW);
      currPos1++;
    }if(map(i, 0, mostStep, 0, abs(pos2-newPos2)) > currPos2){
      //step axle 2
      digitalWrite(stepPin2, HIGH);
      delayMicroseconds(delayStep);
      digitalWrite(stepPin2, LOW);
      currPos2++;
    }if(i*abs(pos3-newPos3)/mostStep > currPos3){
      //step axle 3
      digitalWrite(stepPin3, HIGH);
      delayMicroseconds(delayStep);
      digitalWrite(stepPin3, LOW);
      currPos3++;
    }if(i*abs(pos4-newPos4)/mostStep > currPos4){
      //step axle 4
      digitalWrite(stepPin4, HIGH);
      delayMicroseconds(delayStep);
      digitalWrite(stepPin4, LOW);
      currPos4++;
    }if(i*abs(pos5-newPos5)/mostStep > currPos5){
      //step axle 5
      digitalWrite(stepPin5, HIGH);
      delayMicroseconds(delayStep);
      digitalWrite(stepPin5, LOW);
      currPos5++;
    }
  }

  //puts in the new position in pos variabale
  pos1 = pos1+currPos1;
  pos2 = pos2+currPos2;
  pos3 = pos3+currPos3;
  pos4 = pos4+currPos4;
  pos5 = pos5+currPos5;

  

  Serial.println(pos1);
  
  Serial.println(pos2);
  
  Serial.println(pos3);
 
  Serial.println(pos4);
  
  Serial.println(pos5);
  
}

//tar fram flest antal steg baserat på nuvarande pos
void longest(int newPos1, int newPos2, int newPos3, int newPos4, int newPos5){
  mostStep = abs(newPos1-pos1);
  longestAxle = 1;

  if(abs(newPos2-pos2) > mostStep){
    mostStep = abs(newPos2-pos2);
    longestAxle = 2;
  }if(abs(newPos3-pos3) > mostStep){
    mostStep = abs(newPos3-pos3);
    longestAxle = 3;
  }if(abs(newPos4-pos4) > mostStep){
    mostStep = abs(newPos4-pos4);
    longestAxle = 4;
  }if(abs(newPos5-pos5) > mostStep){
    mostStep = abs(newPos5-pos5);
    longestAxle = 5;
  }
}


//tar fram långsammast axel baserat på hastigheten
/*void slowest(int newPos1, int newPos2, int newPos3, int newPos4, int newPos5){
  slowestTime = abs(newPos1-pos1)/speed1;
  slowestAxle = 1;

  if(abs(newPos2-pos2)/speed2 > slowesTime){
    slowestTime = abs(newPos2-pos2)/speed2
    slowestAxle = 2;
  }if(abs(newPos3-pos3)/speed3 > slowesTime){
    slowestTime = abs(newPos3-pos3)/speed3
    slowestAxle = 3;
  }if(abs(newPos4-pos4)/speed4 > slowesTime){
    slowestTime = abs(newPos4-pos4)/speed4
    slowestAxle = 4;
  }if(abs(newPos5-pos5)/speed5 > slowesTime){
    slowestTime = abs(newPos5-pos5)/speed5
    slowestAxle = 5;
  }
}*/

;

Start by commenting out all the Serial.print statements inside the part that moves your steppers. Then see what speed you get.

there is only one inside the for loop that does the stepping. i did comment it out and there is big difference, atleast 5 times faster now. if i do 1/2 stepping instead off 1/16 im starting to get good speed. Thank you alot! :slight_smile:

Any more suggestions are welcome

marntell:
do you have any suggestion on how to simplify it or other solution?

I have written code to move 3 motors in a coordinated fashion. I suggest that as the first thing in your movJ() function you should calculate the total time for the motor that will take the longest time to complete its move and then calculate the number of millis() or micros() between steps for that motor and all of the others. That gets all the slow stuff done before the motors start moving.

The code to move the motors can then be something like

currentMillis = millis(); // so same time is used for all motors -- or use micros() if appropriate
if (currentMIllis - motorsStartTime < totalMoveDuration) {
   for (byte n = 0; n < numMotors; n++) {
      if (currentMillis - lastMotorMoveTime[n] >= motorInterval[n]) {
         stepMotor(n);
      }
   }
}

If you know how to create an array of structs you could make the code neater.

Note that there are no delay()s anywhere.

...R