AccelStepper Program Problem Using Stepper Motors

I’m trying to get a robot to drive straight for a distance, then turn 90 degrees, then repeat. When trying to run the two voids, goStraight() and ninetyDegrees(), inside the void loop(), the stepper motors just lockup. Running the two voids individually, the stepper motors function properly. Any help would be appreciated.

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 5, 12);
AccelStepper stepper2(AccelStepper::DRIVER, 8, 9);
int y=1;// constant to set travel distance y=3 is 3 rotations of the motors
float r = .400; //Change this multipier to change rotation of the robot. 3200 is one revolution of the wheels
//r=.400 provides close to a 90 degree turn
//One revolution = 7.8" traveled
int pos = 3600;
long pos1 = .400;
long pos2 = .400;
void setup()
{
//Motor 1
pinMode(6,OUTPUT); // Enable
pinMode(5,OUTPUT); // Step
pinMode(12,OUTPUT); // Dir (pin 4 was damaged - switched to 12)
digitalWrite(6,LOW); // Set Enable low

//Motor 2
pinMode(10,OUTPUT); // Enable
digitalWrite(10,LOW); // Set Enable low
pinMode(9,OUTPUT); // Dir Motor 2
pinMode(8,OUTPUT); // Step Motor 2
//int y = 0;
//Motor1
digitalWrite(12, HIGH); //Direction
//Motor2
digitalWrite(9, HIGH);// Direction

stepper1.setMaxSpeed(1000);
stepper1.setAcceleration(10000);
stepper2.setMaxSpeed(1000);
stepper2.setAcceleration(10000);
}

void loop()
{
//delay(1000);
goStraight();
ninetyDegrees();
}

//Go Straight******************************
void goStraight()
{
if (stepper1.distanceToGo() == 0)
pos = 3200;
stepper1.moveTo(pos);
stepper2.moveTo(pos);
stepper1.run();
stepper2.run();
}

//Turn 90 degrees**************************
void ninetyDegrees()
{
if (stepper1.distanceToGo() == 0)
pos1 = 3200;
stepper1.moveTo(-pos1);
stepper2.moveTo(pos1);
stepper1.run();
stepper2.run();
}

UsingAccelStepperFeb7.ino (1.64 KB)

You should not be calling stepper.run() inside your functions. Those calls should be in loop(). The purpose of the functions should simply be to set the destination for the movements of the motors.

Note that the correct name is "function" rather than "void". The word void just tells the compiler that the function will not be returning a value.

...R

Robin2

I made the changes the way I interpreted post. Please look it over because the stepper motors still don't run.

chuckl72:
Robin2

I made the changes the way I interpreted post. Please look it over because the stepper motors still don't run.

I have no intention of looking over your improperly posted code now that you have changed the code in the original post, making Robin2 look foolish.

NEVER replace code that someone has commented on. You are not charged for each reply, so add your code, IN CODE TAGS (read the stickies!) in a new reply.

Besides, your functions are STILL calling run(). Only loop() should be calling run().

chuckl72:
Robin2

I made the changes the way I interpreted post. Please look it over because the stepper motors still don't run.

Please reinstate the original code in your Original Post and post the revised code in a new Reply. That way someone reading the Thread from top to bottom can make sense of it.

...R

This is the revised code including the changes that Paul S pointed out, however the stepper motors still don’t work. I’ve also attached the ino files for both the original (Feb7) and revised sketch (Feb 10). Obviously I need to learn the correct way to post on this site. I couldn’t find anything that lays out the proper etiquette.

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 5, 12);
AccelStepper stepper2(AccelStepper::DRIVER, 8, 9);
int y=1;// constant to set travel distance y=3 is 3 rotations of the motors
float r = .400; //Change this multipier to change rotation of the robot. 3200 is one revolution of the wheels
//r=.400 provides close to a 90 degree turn
//One revolution = 7.8" traveled
int pos = 3600;
long pos1 = .400;
long pos2 = .400;
void setup()
{
//Motor 1
pinMode(6,OUTPUT); // Enable
pinMode(5,OUTPUT); // Step
pinMode(12,OUTPUT); // Dir (pin 4 was damaged - switched to 12)
digitalWrite(6,LOW); // Set Enable low

//Motor 2
pinMode(10,OUTPUT); // Enable
digitalWrite(10,LOW); // Set Enable low
pinMode(9,OUTPUT); // Dir Motor 2
pinMode(8,OUTPUT); // Step Motor 2
//int y = 0;
//Motor1
digitalWrite(12, HIGH); //Direction
//Motor2
digitalWrite(9, HIGH);// Direction

stepper1.setMaxSpeed(10000);
stepper1.setAcceleration(10000);
stepper2.setMaxSpeed(10000);
stepper2.setAcceleration(10000);
}

void loop()
{
//delay(1000);
goStraight();
stepper1.run();
stepper2.run();
ninetyDegrees();
stepper1.run();
stepper2.run();
}

//Go Straight******************************
void goStraight()
{
if (stepper1.distanceToGo() == 0)
pos = 3200;
stepper1.moveTo(pos);
stepper2.moveTo(pos);\

}

//Turn 90 degrees**************************
void ninetyDegrees()
{
if (stepper1.distanceToGo() == 0)
pos1 = 3200;
stepper1.moveTo(-pos1);
stepper2.moveTo(pos1);\

}

UsingAccelStepperFeb10.ino (1.64 KB)

UsingAccelStepperFeb7.ino (1.64 KB)

You are calling goStraight(), and telling the steppers that they need to end up stepping 3200 times each. Then, you return, and maybe take one step. Then, you call ninetyDegrees(), and tell the steppers that there new target is 3200 steps more for one, and 3200 steps less for the other. Then, you return, and maybe take one step. Then, you do it all over again.

Clearly, that is NOT what you want to have happen.

You should NOT call either function if the distance to go for EITHER motor is not 0.

You shouldn’t be calling moveTo() all the time, that’s really going to slow things down.

Call moveTo() only when the destination position has changed.

You might want to use move() rather than moveTo(), as relative moves make more sense for
this sort of control.

I’m worried by the line continuations in goStraight and ninetyDegrees, that suggests these functions
were translated from macros at some point.

@chuckl72, when posting code please use the code button </>
codeButton.png

so your code looks like this

and is easy to copy to a text editor See How to use the Forum

Also please use the AutoFormat tool to indent your code for easier reading.

...R

Robin2 - thanks for the link

MarkT
I’ve tried the both move() and moveTo() and get the same error message.

no matching function for call to ‘AccelStepper::move()’

I’ve searched Safari and didn’t fine any help on this error message. Also, I haven’t been very successfull finding help using the AccelStepper.

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 5, 12);
AccelStepper stepper2(AccelStepper::DRIVER, 8, 9);
int y = 1; // constant to set travel distance y=3 is 3 rotations of the motors
float  r = .400; //Change this multipier to change rotation of the robot.  3200 is one revolution of the wheels
//r=.400 provides close to a 90 degree turn
//One revolution = 7.8" traveled
int pos = 3600;
long pos1 = .400;
long pos2 = .400;
void setup()
{
  //Motor 1
  pinMode(6, OUTPUT); // Enable
  pinMode(5, OUTPUT); // Step
  pinMode(12, OUTPUT); // Dir (pin 4 was damaged - switched to 12)
  digitalWrite(6, LOW); // Set Enable low

  //Motor 2
  pinMode(10, OUTPUT); // Enable
  digitalWrite(10, LOW); // Set Enable low
  pinMode(9, OUTPUT); // Dir  Motor  2
  pinMode(8, OUTPUT); // Step  Motor 2
  //int y = 0;
  //Motor1
  digitalWrite(12, HIGH); //Direction
  //Motor2
  digitalWrite(9, HIGH);// Direction

  stepper1.setMaxSpeed(10000);
  stepper1.setAcceleration(10000);
  stepper2.setMaxSpeed(10000);
  stepper2.setAcceleration(10000);
}

void loop()
{
  goStraight();
  stepper1.run();
  stepper2.run();

  ninetyDegrees();
  stepper1.run();
  stepper2.run();

}


//Go Straight******************************
void goStraight()
{
  for (int x = 0;  x <= 3200; x++)
  {
    if (stepper1.move() == 0)
    {
      pos = 3200;
      stepper1.moveTo(pos); \
      stepper2.moveTo(pos); \
      stepper1.run();
      stepper2.run();
    }
  }
}


//Turn 90 degrees**************************
void ninetyDegrees()
{
  for (int x = 0;  x <= 3200; x++)
  {
    if (stepper1.move() == 0)
    {
      pos1 = 3200;
      stepper1.moveTo(-pos1); \
      stepper2.moveTo(pos1); \
      stepper1.run();
      stepper2.run();
    }

  }
}

chuckl72:
no matching function for call to ‘AccelStepper::move()’

I bet you did not post the complete error message

You don’t use the move() function like this

if (stepper1.move() == 0)

the function for that is distanceToGo().

The move() function is for giving the library a new destination.

…R

no matching function for call to ‘AccelStepper::move()’

So, why do you think that AccelStepper has such a method? You CAN look at the header file(s) to see what methods it really has, and you can look at the examples to see how to use them.

The move() function is for giving the library a new destination.

What? Once more, in English, please.

The move() method is to increment, or decrement, the target position.

PaulS:
What? Once more, in English, please.

The move() method is to increment, or decrement, the target position.

I was using the word "destination" to mean "target position". I'm not sure there is much difference between them as far a comprehension is concerned.

In my little world the concepts of distanceToGo() and destination are compatible bedfellows.

...R

I'm not sure there is much difference between them as far a comprehension is concerned.

You said that move() "is for giving the library a new destination.". A library is a collection of source and header files. Giving those files a new destination implies moving or copying them. Quite a bit different interpretation, on my part at least, from giving an instance a new target position.

PaulS:
You said that move() "is for giving the library a new destination.". A library is a collection of source and header files. Giving those files a new destination implies moving or copying them. Quite a bit different interpretation, on my part at least, from giving an instance a new target position.

Pedant !

...R

Robin2:
Pedant !

...R

Guilty!

Sorry, but I’m really frustrated with trying to solve this coding problem. There is some fundamental point that I’m missing in the operation of a processor. I simply do not know how to implement what PaulS wrote on Feb 10. Can someone show me how to correct the code? it would be greatly appreciated.

Chuck

Posted by PaulS - Feb 10, 2019, 11:37 pm Quote
You are calling goStraight(), and telling the steppers that they need to end up stepping 3200 times each. Then, you return, and maybe take one step. Then, you call ninetyDegrees(), and tell the steppers that there new target is 3200 steps more for one, and 3200 steps less for the other. Then, you return, and maybe take one step. Then, you do it all over again.

Clearly, that is NOT what you want to have happen.

You should NOT call either function if the distance to go for EITHER motor is not 0.

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 5, 12);
AccelStepper stepper2(AccelStepper::DRIVER, 8, 9);
int y = 1; // constant to set travel distance y=3 is 3 rotations of the motors
float  r = .400; //Change this multipier to change rotation of the robot.  3200 is one revolution of the wheels
//r=.400 provides close to a 90 degree turn
//One revolution = 7.8" traveled
int pos = 3600;
long pos1 = .400;
long pos2 = .400;
void setup()
{
  //Motor 1
  pinMode(6, OUTPUT); // Enable
  pinMode(5, OUTPUT); // Step
  pinMode(12, OUTPUT); // Dir (pin 4 was damaged - switched to 12)
  digitalWrite(6, LOW); // Set Enable low

  //Motor 2
  pinMode(10, OUTPUT); // Enable
  digitalWrite(10, LOW); // Set Enable low
  pinMode(9, OUTPUT); // Dir  Motor  2
  pinMode(8, OUTPUT); // Step  Motor 2
  //int y = 0;
  //Motor1
  digitalWrite(12, HIGH); //Direction
  //Motor2
  digitalWrite(9, HIGH);// Direction

  stepper1.setMaxSpeed(1000);
  stepper1.setAcceleration(10000);
  stepper2.setMaxSpeed(1000);
  stepper2.setAcceleration(10000);
}

void loop()
{
  //delay(1000);

  goStraight();
  stepper1.run();
  stepper2.run();

  ninetyDegrees();
  stepper1.run();
  stepper2.run();
}


//Go Straight******************************
void goStraight()
{
  if (stepper1.distanceToGo() == 0)
    pos = 3200;
  stepper1.moveTo(pos); \
  stepper2.moveTo(pos); \

}

//Turn 90 degrees**************************
void ninetyDegrees()
{
  if (stepper1.distanceToGo() == 0)
    pos1 = 0;
  stepper1.moveTo(pos1); \
  stepper2.moveTo(pos1); \
 
}

You should have all the code in the function inside the IF

void goStraight()
{
  if (stepper1.distanceToGo() == 0) {
      pos = 3200;
      stepper1.moveTo(pos); 
      stepper2.moveTo(pos); 
   }
}

However it would probably be more usual to have the test in loop() - like this

void loop()
{
  
  if (stepper1.distanceToGo() == 0) {
     goStraight();
  }
 
  if (stepper1.distanceToGo() == 0) {
       ninetyDegrees();
  }
  stepper1.run();
  stepper2.run();
}

but I think you will now see that you need a variable to keep track of which part of the action you are in. That could be as simple as moveNumber = 1 (or 2) . So you get something like this

[code]void loop()
{
    
    if (stepper1.distanceToGo() == 0) {
        if (moveNum == 1) {
            goStraight();
            moveNum = 2;
        }
        else if (moveNum == 2) {
            ninetyDegrees();
        }
    }
    stepper1.run();
    stepper2.run();
}

...R[/code]

EDIT 14 Feb 2019 to add the missing () to distanceToGo() Apologies for any confusion