Go Down

Topic: Simultanious Acceleration of two stepper Motors fails with Accelstepper (Read 11910 times) previous topic - next topic

sanktangus

Hi everyone!

I'm Max and new to the Arduino Community. I've been searching for an answer to my problem for a while now, but cannot find anything useful.

So I'm building a robot for my Master Thesis which should do some machine learning stuff. Here is the setup:

Arduino Due
Adafruit Motorshield 2.3
2*Adafruit Stepper Motor 12V 350mA 200steps/rev

I'm sending Integers via Serial Port from a PC and the Arduino controlls the Steppers with different Movement Commands. At first it works well but after a few movement commands the acceleration for each motor does not work simultaneously anymore. So if the Robot ("Robert") should go a straight line, it will do it in a wave because one motor will accelerate faster.

I used an Arduino Uno first and read somewhere, that its CPU Clockspeed is too low for two accelerated steppers so i switched to the Due. The Problem is still the same... Has anyone another idea?

Code: [Select]
#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>

Adafruit_MotorShield AFMSbot(0x60); // Rightmost jumper closed

// Connect two steppers with 200 steps per revolution (1.8 degree)
// to the top shield
Adafruit_StepperMotor *myStepper1 = AFMSbot.getStepper(200, 1);
Adafruit_StepperMotor *myStepper2 = AFMSbot.getStepper(200, 2);

char recValue;
char inByte = 0;
int n;
int c = 0; // collision status
int d1; //distance motor1
int d2; // distance motor2
int sg = 400; //speed general [400->15cm/s]
int s1; //speed motor1
int s2; //speed motor2
int dt1; //distance travelled motor1
int dt2; //distance travelled motor2


void forwardstep1() { 
  myStepper1->onestep(FORWARD, DOUBLE);
}
void backwardstep1() { 
  myStepper1->onestep(BACKWARD, DOUBLE);
}
// wrappers for the second motor!
void forwardstep2() { 
  myStepper2->onestep(FORWARD, DOUBLE);
}
void backwardstep2() { 
  myStepper2->onestep(BACKWARD, DOUBLE);
}


//wrap the 2 steppers in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);


void setup()


//MOTOR 
  AFMSbot.begin(); // Start the shield
  stepper1.setMaxSpeed(sg);
  stepper1.setAcceleration(50.0);
   
  stepper2.setMaxSpeed(sg);
  stepper2.setAcceleration(50.0);

void loop()
{



  while(!Serial.available()){} // wait for serial input
 
  if(Serial.available())
  {
    recValue=Serial.read();
 
 
    switch(recValue)
{
case 1: d1 = 10; d2 = -10;  s1 = sg; s2 = -sg; break; // straight 10s

case 2: d1 = 100; d2 = -100; s1 = sg; s2 = -sg; break; // straight 100s
 
case 3: d1 = 1000; d2 = -1000; s1 = sg; s2 = -sg; break; // straight 1000s

case 4: d1 = -10; d2 = -10; s1 = -sg; s2 = -sg; break; // left 3deg
 
case 5: d1 = -34; d2 = -34; s1 = -sg; s2 = -sg; break; // left 10deg
 
case 6: d1 = -152; d2 = -152; s1 = -sg; s2 = -sg; break; // left 45deg

case 7: d1 = 10; d2 = 10; s1 = sg; s2 = sg; break; // right 3deg
 
case 8: d1 = 34; d2 = 34; s1 = sg; s2 = sg; break; // right 10deg
 
case 9: d1 = 152; d2 = 152; s1 = sg; s2 = sg; break; // right 45deg
   }

    stepper1.moveTo(d1);
    stepper2.moveTo(d2);

//RUN..........................................................
    while(stepper1.currentPosition() != d1 && stepper2.currentPosition() != d2 && c == 0)
    {
      stepper1.run();
      stepper2.run();

    }
//.............................................................   



  delay(100);     //avoid slip

//RESET VARIABLES..............................................
    myStepper1->release();
    myStepper2->release();
    d1 = 0;
    d2 = 0;
    s1 = 0;
    s2 = 0;
    c = 0;
    stepper1.setCurrentPosition(0);
    stepper2.setCurrentPosition(0);
//.............................................................   


Thanks, hugs and kisses
Max

Robin2

I'm sure someone at Adafruit believes that their libraries makes things easier but to my mind they just make everything more complicated.

I suggest you try writing a program that just uses the AccelStepper library.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

sanktangus

How do I do that by using the adafruit motorshield? Even in the examples of the Accelstepper Lib, they use the adafruit motorshield lib....

Robin2

Even in the examples of the Accelstepper Lib, they use the adafruit motorshield lib....
Please post a link to that.

AFAIK to use the AccelStepper library all you need to know about the motorshield is which Arduino pins control the motor coils, but I confess that I don't have a motorshield.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MarkT

You should be calling run() methods every time through loop(), not busy-waiting for serial input,
not calling delay(), and not resetting the stepper positions - I think you meant to use move() - relative, not
moveTo() which is absolute.

You shouldn't be waiting for the movements to complete, if you need to know if the movement is
complete, check there and then.

Basically no use of 'while', replace with 'if'.  Loop is supposed to run 10's to 100's of thousand
times a second, it is the only looping construct you need.

You should be able to set the movement at any time, so long as the run methods are being called
frequently each motor will do its thing as it should whilst your code is free to do other stuff/housekeeping.

400 steps a second shouldn't cause issues, that's 20000 clock cycles per step per motor.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up