Adafruit Motorshield V2 indpendent stepper speed

Hi guys,

I need some help please. I have the Adafruit motor shield V2 and the Leonardo connected to two stepper motors with a 100:1 gearbox. I have a rc Turnigy 9x transmitter and receiver connected to the Leonardo, I am receiving all inputs fine etc. essentially, at different joy stick positions on the controller, the code interprets the two channel readings and controls the motors respectively and independently.

I am having much trouble controlling the motors simultaneously, because even if I have them both alternating each step, the motion for the motors is not very fluent.

Depending on how "far" the joystick has been pressed, will determine how "fast" the motors turn. Does anybody know a good way to change the speed of each motor independently.

I have tried changing the "motor speed (rpm) depending on the joystick position, and I've also tried increasing the motor step ratio, for example, if M1 needs to go faster than M2, M1 will go two steps for each one step of M2. Neither of which have worked.

I there is a solution with the accel stepper library il happy to do that but I've never managed to get the constant speed example working for simultaneous motors.

So yeah, how can I change the "speed" of each motor independently. Btw, direction control works brilliantly.

Also, because the gearing is 100:1 I changed used 20,000 steps in the code rather than 200 (yes, without he gearbox it is 1.8deg/step), is that correct.

Here is my attempted and failed code, I've been at it for a month now, please help !

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

@Harry_Stuart , there is no code with the Original Post. Please post your code in your next Reply

If you want high performance it would be better to use specialized stepper motor drivers such as the Pololu DRV8825.

...R
Stepper Motor Basics
Simple Stepper Code

#include <Wire.h>
#include <Bridge.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_StepperMotor *myMotor1 = AFMS.getStepper(20000, 2); 
Adafruit_StepperMotor *myMotor2 = AFMS.getStepper(20000, 1); 
int motorSpeed1 = 0;
int motorSpeed2 = 0;
int pin1 = 7
int pin2 = 8;
int amountSteps1 = 3;
int amountSteps2 = 3;
int stepDirection1;
int stepDirection2;

void setup() {
  
pinMode(pin1, INPUT);
pinMode(pin2, INPUT);
 
AFMS.begin(); 
myMotor1->setSpeed(motorSpeed1);   
myMotor2->setSpeed(motorSpeed2);

}


void loop() {

int altitudeValue = pulseIn(pin1, HIGH);
int azimuthValue = pulseIn(pin2, HIGH);

//M1
if (altitudeValue >= 1020 && altitudeValue < 1140){
  
motorSpeed1 = 6;
amountSteps1 = 1;
  stepDirection1 = BACKWARD;
  }
if (altitudeValue >= 1140 && altitudeValue < 1260){
  amountSteps1 = 1;
 motorSpeed1 = 4;

  stepDirection1 = BACKWARD;
  }
if (altitudeValue >= 1260 && altitudeValue < 1380){
  amountSteps1 = 1;
motorSpeed1 = 2;

  stepDirection1 = BACKWARD;
  }
if (altitudeValue >= 1380 && altitudeValue < 1500){
  amountSteps1 = 0;
motorSpeed1 = 0;

  stepDirection1 = BACKWARD;
  }
if (altitudeValue >= 1500 && altitudeValue < 1620){
  amountSteps1 = 1;
motorSpeed1 = 2;

  stepDirection1 = FORWARD;
  }
if (altitudeValue >= 1620 && altitudeValue < 1740){
  amountSteps1 = 1;
motorSpeed1 = 4;

  stepDirection1 = FORWARD;
  }
if (altitudeValue >= 1740 && altitudeValue < 1860){
  amountSteps1 = 1;
 motorSpeed1 = 6;

  stepDirection1 = FORWARD;
  }

//M2
if (azimuthValue >= 1020 && azimuthValue < 1140){
 motorSpeed2 = 6;
  amountSteps2 = 1;
  stepDirection2 = FORWARD;
  }
if (azimuthValue >= 1140 && azimuthValue < 1260){
 motorSpeed2 = 4;
  amountSteps2 = 1;
  stepDirection2 = FORWARD;
  }
if (azimuthValue >= 1260 && azimuthValue < 1380){
 motorSpeed2 = 2;
amountSteps2 = 1;
  stepDirection2 = FORWARD;
  }
if (azimuthValue >= 1380 && azimuthValue < 1500){
   motorSpeed2 = 0;
  amountSteps2 = 0;
  stepDirection2 = FORWARD;
  }
if (azimuthValue >= 1500 && azimuthValue < 1620){
   motorSpeed2 = 2;
  amountSteps2 = 1;
  stepDirection2 = BACKWARD;
  }
if (azimuthValue >= 1620 && azimuthValue < 1740){
   motorSpeed2 = 4;
  amountSteps2 = 1;
  stepDirection2 = BACKWARD;
  }
if (azimuthValue >= 1740 && azimuthValue < 1860){
  motorSpeed2 = 6;
  amountSteps2 = 1;
  stepDirection2 = BACKWARD;
  }

myMotor1->step(amountSteps1, stepDirection1, DOUBLE);
myMotor2->step(amountSteps2, stepDirection2, DOUBLE);

}

I am sorry guys the code was not working, maybe because I'm on my phone.

Hi,
Please use code tags.
Read post #1.

Thanks... Tom.. :slight_smile:

Updated code window* @Robin2 @TomGeorge

Thanks for the code.

I am not familiar with the Adafruit stepper library. They seem to delight in making simple things complicated. They could use the AccelStepper library that more people are familiar with.

It looks like your code in loop() does a bunch of things and then gets the motors to move several steps. In that bunch of things are 2 calls to pulseIn() which AFAIK is a blocking function. That may mean that there is an appreciable interval between the motor movements.

It is probably unrelated to your problem but you have a huge number of IF statements in loop(). At the very least it seems they could be simplified like this

   if (altitudeValue < 1140){
     
        motorSpeed1 = 6;
        amountSteps1 = 1;
        stepDirection1 = BACKWARD;
    }
    else if (altitudeValue < 1260){
        amountSteps1 = 1;
        motorSpeed1 = 4;

        stepDirection1 = BACKWARD;
    }
    else if (altitudeValue < 1380){
        amountSteps1 = 1;

However I suspect it may be possible to calculate the speed and number of steps mathematically so there is no need for any IF statements. Maybe something like

amountSteps1 = altitudeValue / 1200;

that is almost certainly incorrect - I just want to put the idea in your mind.

...R

Thanks Robin,

I am how to actually change the speed, calculating it is not necessarily a concern. I can change the speed of one stepper fine. But when I introduce another one, I have to have the steppers alternating. This introduces problems because the step function is blocking. Meaning, I if M1 and M2 are to go 1000 steps simultaneously, I have to have M1 go 1 step, then M2 go 1 step, 1000 times, rather than M1 go 1000 steps and M2 go 1000 steps at the same time.

Harry_Stuart:
This introduces problems because the step function is blocking. Meaning, I if M1 and M2 are to go 1000 steps simultaneously, I have to have M1 go 1 step, then M2 go 1 step, 1000 times, rather than M1 go 1000 steps and M2 go 1000 steps at the same time.

If you are getting inconsistent behaviour when moving 1 step at a time it is almost certainly due to the time taken by other code in loop(). And I don't think you have posted the code that does 1 step at a time.

I am tempted to suggest that you modify the program to use the AccelStepper library. Or, if you need the motors to move in a synchronized way (for example M1 should move 273 steps in the same time that M2 moves 813 steps} you will need to use the MultiStepper version of the AccelStepper library. However that would also be affected by any blocking code elsewhere in loop().

One thought is that you may not need to call pulseIn() in every iteration of loop(). Maybe 2 or 3 times per second would be sufficient. And maybe you can arrange the code so that both pulseIn() calls are not in the same iteration of loop()

...R

Yes, I agree that the accell stepper library is probably the best way to go. How can I prevent PulseIn from disrupting the motors? Twice a second would be sufficient accuracy. I believe that the motors would "stutter" each time pulseIn is called?

Thanks, Harry

Harry_Stuart:
Yes, I agree that the accell stepper library is probably the best way to go. How can I prevent PulseIn from disrupting the motors? Twice a second would be sufficient accuracy. I believe that the motors would "stutter" each time pulseIn is called?

Thanks, Harry

You need to post the code with single steps so we can see what you can see.

...R