Commanding a stepper motor to make a series of movements in a specific order

So, IM trying to program a stepper motor to move XX CW, and then back to 0 - then i want to go YY steps CW and then back to 0, and THEN i want to go ZZ steps CW and then back to 0, and THEN i want to Delay for XXX seconds - and then start the loop over.

i have found some code that makes the motion i want - now im trying to string it together. the issue im having is that it runs... but its not going in order... its jumping all over the place.

// Include AccelStepper Library
#include <AccelStepper.h>

//Define motor pin connections
const int dirPin = 2;
const int stepPin = 4;
const long targetPos1 = 10000;
const long targetPos2 = 5000;
const long targetPos3 = 2500;
const long targetPos4 = 1;
const long targetPos5 = 2;
const long targetPos6 = 3;
#define motorInterfaceType 1

// Creates an instance
AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(10000);
  myStepper.setAcceleration(2000);
 //  myStepper.setSpeed(250);   // This is useless, as .run() only follows maxSpeed!
  myStepper.moveTo(5000);

    }
void loop() {
  // Change direction once the motor reaches target position
  if (myStepper.distanceToGo() == 0) {
    if (myStepper.currentPosition() == 0) {
      myStepper.moveTo(targetPos1);
    } else {
      myStepper.moveTo(targetPos4);
    }
  }
    myStepper.run(); 
    if (myStepper.distanceToGo() == 0) {
      if (myStepper.currentPosition() == targetPos4) {
        myStepper.moveTo(targetPos2);
      } else {
        myStepper.moveTo(targetPos5);
      }    
  }
      myStepper.run(); 
      if (myStepper.distanceToGo() == 0) {
        if (myStepper.currentPosition() == targetPos5) {
          myStepper.moveTo(targetPos3);
        } else {
          myStepper.moveTo(0);
        }
      myStepper.run();
      delay(1000); 
      }  
  // Move the motor one step
  
  }

Do you have the original code?
Just wondering how it knows where it is initially.

What board are you using? An UNO/Nano isn't able to step the motor that fast.

You should learn about arrays. Your code can be much simpler with an array:

Yes, a homing procedure at the beginning may be useful :wink:

[Edit]

The problem of your code is, that it loops while the motor is moving, and it is pure coincidence at which of your

if (myStepper.distanceToGo() == 0) {

the motor has reached its target.

look this over (but guessing you want to do more than just on sequence);

#include <AccelStepper.h>

#define dirPin              2
#define stepPin             4
#define motorInterfaceType  1
AccelStepper myStepper (motorInterfaceType, stepPin, dirPin);

// -----------------
struct Position {
    int             nStep;
    unsigned long   msec;
    const char     *desc;
};

Position pos [] = {
    {  5000,  500, "pos  0" },
    {     0,  500, "origin" },
    { 10000,  500, "pos  1" },
    {     0,  500, "origin" },
    {  5000,  500, "pos  2" },
    {     0,  500, "origin" },
    {  2500,  500, "pos  3" },
    {     0,  500, "origin" },
    {     1,  500, "pos  4" },
    {     2,  500, "pos  5" },
};
const int Npos = sizeof(pos)/sizeof(Position);

int idx;

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);

    myStepper.setMaxSpeed      (10000);
    myStepper.setAcceleration (2000);

    for (int idx = 0; idx < Npos; idx++)  {
        Serial.println   (pos [idx].desc);
        myStepper.moveTo (pos [idx].nStep);
        myStepper.run    ();
        delay            (pos [idx].msec);
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
}

Sorry, but this will not work because run does only 1 step at max. If you want a blocking move you could do

    for (int idx = 0; idx < Npos; idx++)  {
        Serial.println   (pos [idx].desc);
        myStepper.runToNewPosition (pos [idx].nStep);
        delay            (pos [idx].msec);
    }
1 Like

Here is a code-version that is well structured into functions and uses self-explaining names for variables and functions etc.

It uses a so called stateMachine.
stateMachines have the advantages of

  • minimizing the number of if-conditions
  • very easy to maintain and to expand

This is done through using a simplified version of "if-conditions"
The condition is simplified to if a variable has
value 1
value 2
value 3
...

and as for all conditions the same variable is used
it is enough to say

if variable "myState"

  • has value 1
  • has value 2
  • has value 3

But you do not use the keyword "if"
you use the keyword "switch" in combination with "case" instead
.
.
You can imagine "switch" like a multi-position-switch with positions
1, 2, 3, 4, 5 .....
Where each switch-position make the "machine" run in a different mode of operation

if "switch" is in position 1 machine works in operation-mode 1
if "switch" is in position 2 machine works in operation-mode 2
if "switch" is in position 3 machine works in operation-mode 3

you don't use numbers like 1,2,3 ...
You use constants that represent the numbers.
This has the advantage that the constant-name already explains the mode of operation.

if "switch" is in position "StepToPosition" machine works in operation-mode 1 (which is mode StepToPosition

if "switch" is in position "returnToZero" machine works in operation-mode 2 (which is mode returnToZero

if "switch" is in position "wait" machine works in operation-mode 3 ( which is mode "waiting"

So here is a WokSim with this code-version

here is the code i started with. effectively it sets a accel speed, and a max speed, and then it moves the stepper motor so far in the setup loop

then it starts oscilating the motor back and forth by the targetpseed - which is GREAT - this is exactly what i need for my project... but then i also want to change the target speed a couple times - and then i want to delay for an hour.

im new to this coding stuff, and i have watched my fair share of tutorials - and i can understand most of the basics when your trying to do simple things.... but when i want to string concepts together i get lost.

// Include AccelStepper Library
#include <AccelStepper.h>

//Define motor pin connections
const int dirPin = 2;
const int stepPin = 3;
const long targetPos = 5000;
// Define motor interface type
#define motorInterfaceType 1

// Creates an instance
AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(350);
  myStepper.setAcceleration(50);
 //  myStepper.setSpeed(250);   // This is useless, as .run() only follows maxSpeed!
  myStepper.moveTo(5000);
}

void loop() {
  // Change direction once the motor reaches target position
  if (myStepper.distanceToGo() == 0) {
    if (myStepper.currentPosition() == 0) {
      myStepper.moveTo(targetPos);
    } else {
      myStepper.moveTo(0);
    }
  }
  // Move the motor one step
  myStepper.run();
}

here is the origional thread for that code:

First code for oscillating motor...Be gentle! - Using Arduino / Programming Questions - Arduino Forum

that's kind of what i was thinking - it doesn't know "which distance to go" to go to next.

i have not watched videos on arrays yet. thank you for the advice, ill take a look!

i also was thinking some sort of homing technique would be useful - so i tried to use so/while loops an increment an integer to trigger the code to move on... and that didn't work... but it was probably still an issue with the "0" terms.

Thanks!

yeah i was looking into this last night aafter i posted my question and was going to investigate it more..... sounds like i have two homework actions today.

  1. look at arrays
    2 look at the example you posted for switch case.

i really appreciate all this feedback folks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.