Accel Stepper Library Forward and Backward Motion

Hi, all. I have been troubleshooting this program for a long time now. I've referenced some of the older forum post and I am still having trouble incorporating some of the approaches into my code.

My goal is to create a moving stage that can have the user select three modes: (Mode 1) forward motion; (Mode 2) forward motion, backward motion, pause, and then repeat; (Mode 3) No motion (stop). The stage uses a pulley-belt system and requires a conversion factor which I calculated. I want to user to be able to input the desired speed in steps, the translational distance in mm, and the mode. I have programmed the Arduino to achieve all of these things. However, mode (1) and (3) work properly, but mode (2) does not work in any capacity. Please, any help will be appreciated.

Is there any code that has a motor simply move forward, pause, move backwards, pause, and repeats this? I am willing to pay someone for help.

You have removed your previous posted code which was not a full sketch.

No paying needed for such s small tip:
Lookup the GiPo (my short for GitHub-repository of accelstepper

there is a subfolder examples
with an example called bounce
best regards Stefan

'steps' would be a measure of distance. Did you mean 'steps per minute'? You could also save them trouble by letting them set the speed in mm per minute and doing the math for them.

Hi, I tried the code for mode 2. However, it appears to have an issue with loop and the movements are not repeated. Do you think it would be best to put the different modes into separate files? Or, is there a way for me to still have the three modes in the same file, and have looping with forward motion, pause, back motion, pause repeatedly?

#include <AccelStepper.h>



const byte enablePin = 8; //enable pin on the DRV8825
AccelStepper Xaxis(1, 2, 5); // pin 2 = stepper pin, pin 5 = direction pin,

const float pi = 3.1415926535897932384626433832795;
const float r = 2.5 ; //Diameter of timing pulley. Here it is 5 mm for the GT2 Timing Belt Pulley (20 teeth) with 2 mm Pitch 6 mm wide belt
const float convF2 = 12.732 ; //Units are mm/steps which is the conversion factor; previously: (2 * pi * r) * (1/200); now: (200)/(2 * pi * r) units: steps/mm 

float ArdDist;  //converted distance in steps


const int maxspd = 300;  //Set Maximum Speed;  steps per second
//
bool askedForData1 = false;
bool gotData1 = false;
float Dist; //User-input distance in 
const float maxDist = 222.816920329; //Maximum distance for stage in steps based on current configuration and conversion factor (max: ~35mm = 445.63 steps); 
//
bool askedForData2 = false;
bool gotData2 = false;
//
float spd; //
int incomingByte = 0;   // for incoming serial data
//
bool askedForData3 = false;
bool gotData3 = false;
float M;
//







void MotorSpdfinder() { //motor speed for moving stage
  if (!askedForData1) {
    Serial.println("Please enter the desired stage speed in steps: ");
    askedForData1 = true;
  }

  if (askedForData1 && !gotData1) {
    if (Serial.available()) {
      // delay(10);
      spd = Serial.parseFloat(SKIP_ALL, ','); //
      gotData1 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}

void  Distfinder() { //translational distance for the moving stage
  if (!askedForData2) {
    Serial.println("Please enter the desired distance in mm (less than 35 mm): ");
    askedForData2 = true;
  }

  if (askedForData2 && !gotData2) {
    if (Serial.available()) {
      // delay(10);
      Dist = Serial.parseFloat(SKIP_ALL, ',');
      gotData2 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}

void Mfinder() { //select the mode for the moving stage
      if (!askedForData3) {
      Serial.println("Pick your Mode (1,2,3): ");
      askedForData3 = true;
    }

    if (askedForData3 && !gotData3) {
      if (Serial.available()) {
        // delay(10);
        M = Serial.parseFloat(SKIP_ALL, ',');
        Serial.println(M);
        gotData3 = true;
        while (Serial.available()) {
          Serial.read();
        }
      }
    }
}
void ArdFinder() { //Arduino distance finder
  if (askedForData1 && gotData1 && askedForData2 && gotData2 && askedForData3 && gotData3) {
    ArdDist = int(Dist * convF2); //Dist = mm, pow(convF2) = steps/mm, ArdDist = steps
    Serial.print("This is your distance in steps: ");
    Serial.println(ArdDist);
    Serial.println("");
    // delay(1000);
    askedForData1 = false;
    gotData1 = false;
    askedForData2 = false;
    gotData2 = false;
    askedForData3 = false;
    gotData3 = false;
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(enablePin, OUTPUT); //Must enable pins on DRV8825
  digitalWrite(enablePin, LOW); //Must enable pins on DRV8825
  Xaxis.setMaxSpeed(maxspd); //Max speed
  MotorSpdfinder(); // 
  Distfinder(); //
  Mfinder(); //
  ArdFinder(); //
  Xaxis.setSpeed(-spd);
  //Xaxis.setCurrentPosition(0);
}
void loop()
{
  MotorSpdfinder();
  Distfinder();
  Mfinder();
  ArdFinder();
  //Xaxis.setSpeed(-spd);
  if ( abs( M - 1)  < 0.01 ) { //distanceToGo()
      Xaxis.setSpeed(spd);
      Xaxis.run();
  }
  if (  abs(M - 2)  < 0.01) {
       if (Xaxis.distanceToGo() == 0)
        Xaxis.moveTo(-Xaxis.currentPosition());
        Xaxis.run(); 
  }
  if ( abs(M - 3)  < 0.01) {
    //Serial.print("Mode 3: ");
    Xaxis.setSpeed(0);
    Xaxis.run();
  }

}

Hi, the user can set the distance in mm which will then convert to steps. However, I am also looking into letting them set the speed in mm/s or mm/minute. I meant steps per second before, sorry for the confusion. Is there a way for me to be able to convert mm/min or mm/s into steps?

#include <AccelStepper.h>



const byte enablePin = 8; //enable pin on the DRV8825
AccelStepper Xaxis(1, 2, 5); // pin 2 = stepper pin, pin 5 = direction pin,

const float pi = 3.1415926535897932384626433832795;
const float r = 2.5 ; //Diameter of timing pulley. Here it is 5 mm for the GT2 Timing Belt Pulley (20 teeth) with 2 mm Pitch 6 mm wide belt
const float convF2 = 12.732 ; //Units are mm/steps which is the conversion factor; previously: (2 * pi * r) * (1/200); now: (200)/(2 * pi * r) units: steps/mm 

float ArdDist;  //converted distance in steps


const int maxspd = 300;  //Set Maximum Speed;  steps per second
//
bool askedForData1 = false;
bool gotData1 = false;
float Dist; //User-input distance in 
const float maxDist = 222.816920329; //Maximum distance for stage in steps based on current configuration and conversion factor (max: ~35mm = 445.63 steps); 
//
bool askedForData2 = false;
bool gotData2 = false;
//
float spd; 
int incomingByte = 0;   // for incoming serial data
//
bool askedForData3 = false;
bool gotData3 = false;
float M;
//







void MotorSpdfinder() { //motor speed for moving stage
  if (!askedForData1) {
    Serial.println("Please enter the desired stage speed in steps: ");
    askedForData1 = true;
  }

  if (askedForData1 && !gotData1) {
    if (Serial.available()) {
      // delay(10);
      spd = Serial.parseFloat(SKIP_ALL, ','); //
      gotData1 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}

void  Distfinder() { //translational distance for the moving stage
  if (!askedForData2) {
    Serial.println("Please enter the desired distance in mm (less than 35 mm): ");
    askedForData2 = true;
  }

  if (askedForData2 && !gotData2) {
    if (Serial.available()) {
      // delay(10);
      Dist = Serial.parseFloat(SKIP_ALL, ',');
      gotData2 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}

void Mfinder() { //select the mode for the moving stage
      if (!askedForData3) {
      Serial.println("Pick your Mode (1,2,3): ");
      askedForData3 = true;
    }

    if (askedForData3 && !gotData3) {
      if (Serial.available()) {
        // delay(10);
        M = Serial.parseFloat(SKIP_ALL, ',');
        Serial.println(M);
        gotData3 = true;
        while (Serial.available()) {
          Serial.read();
        }
      }
    }
}
void ArdFinder() { //Arduino distance finder
  if (askedForData1 && gotData1 && askedForData2 && gotData2 && askedForData3 && gotData3) {
    ArdDist = int(Dist * convF2); //Dist = mm, pow(convF2) = steps/mm, ArdDist = steps
    Serial.print("This is your distance in steps: ");
    Serial.println(ArdDist);
    Serial.println("");
    // delay(1000);
    askedForData1 = false;
    gotData1 = false;
    askedForData2 = false;
    gotData2 = false;
    askedForData3 = false;
    gotData3 = false;
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(enablePin, OUTPUT); //Must enable pins on DRV8825
  digitalWrite(enablePin, LOW); //Must enable pins on DRV8825
  Xaxis.setMaxSpeed(maxspd); //Max speed
  MotorSpdfinder(); // 
  Distfinder(); //
  Mfinder(); //
  ArdFinder(); //
  Xaxis.setSpeed(-spd);
  //Xaxis.setCurrentPosition(0);
}
void loop()
{
  MotorSpdfinder();
  Distfinder();
  Mfinder();
  ArdFinder();
  //Xaxis.setSpeed(-spd);
  if ( abs( M - 1)  < 0.01 ) { //distanceToGo()
      Xaxis.setSpeed(spd);
      Xaxis.run();
  }
  if (  abs(M - 2)  < 0.01) {
       if (Xaxis.distanceToGo() == 0)
        Xaxis.moveTo(-Xaxis.currentPosition());
        Xaxis.run(); 
  }
  if ( abs(M - 3)  < 0.01) {
    //Serial.print("Mode 3: ");
    Xaxis.setSpeed(0);
    Xaxis.run();
  }

}

Multiply by 'steps per mm' to get steps/min or steps/s.

Thank you for the help.

I am wondering if there is a way that I could fix 'Mode 2 'so that there is a forward and backwards motion with pausing? I tried implementing a while loop based on the 'quickstop' example provided in the accel stepper library examples. I have also tried using the 'bounce' example code.

You are pretty short on information.
What was the result of testing the bounce examle?

What exactly did you test?

Post you latest sketch. Not a single potential helper of you has a glas-sphere to look into to see what you have coded / tested.

I really recommend reading this

best regards Stefan

Sorry, I am new here and thank you for the helpful link.

Bounce:

  • I tested if the motors would move back and forth within Mode 2 of the double if statements (based on the bounce example)
  • The motors did not move at all. I believe it is not registering with Arduino inside the double if-statements.
  • The code is posted in the last comment.

Quickstop:

  • The motors did move back and forth repeated. However, the speed did not change at all. I varied the speed and acceleration to test this.
  • I tested if the motors would move back and forth repeatedly.

Question:

  • Can I implement a for-loop or some other code within the if-statements to create these movements?
  • Is it better to separate the modes into separate files so there is no issues with the looping?
    -I do not understand the reason why the bounce example did not work. Is it because it uses two if-statements repeatedly?
    Example Code:
int counter = 0;

void loop() {

// go forwards 100 steps at speed 50
stepper.setSpeed(50); 
while (counter++ < 100) {
    stepper.runSpeed();
}

// stop
stepper.setSpeed(0); 
stepper.runSpeed();

// go backwards 100 steps at speed 50
stepper.setSpeed(-50); 
while (counter-- > 0) {
    stepper.runSpeed();
}

// stop
stepper.setSpeed(0); 
stepper.runSpeed();

}
type or paste code here

Hi,
you are asking specific questions. this is very good. From your questions I can conclude that your knowledge about programming is improvable.

You can combine any commands in almost any order you like. For-loops inside if conditions or if-conditions inside for-loops, or while-loops, or... or... or....
the commands can be in one file or distributed in multiple files.
In most cases it makes sense to have all the code in one file.

what you have posted is not a complete sketch. And beause it is uncomplete it is hard to say what the reason is why the motors didn't moeved
best regards
Stefan

Sorry, it must be something with the text or my computer? Should I post the code as a download link/file?

no. donwload-links are suspected to be malicious.
You should post code by using code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

best regards Stefan

#include <AccelStepper.h>



const byte enablePin = 8; //enable pin on the DRV8825
AccelStepper Xaxis(1, 2, 5); // pin 2 = stepper pin, pin 5 = direction pin,

const float pi = 3.1415926535897932384626433832795;
const float r = 2.5 ; //Diameter of timing pulley. Here it is 5 mm for the GT2 Timing Belt Pulley (20 teeth) with 2 mm Pitch 6 mm wide belt
const float convF2 = 12.732 ; //Units are mm/steps which is the conversion factor; previously: (2 * pi * r) * (1/200); now: (200)/(2 * pi * r) units: steps/mm

float ArdDist;  //converted distance in steps


const int maxspd = 300;  //Set Maximum Speed;  steps per second
//
bool askedForData1 = false;
bool gotData1 = false;
float Dist; //User-input distance in
const float maxDist = 222.816920329; //Maximum distance for stage in steps based on current configuration and conversion factor (max: ~35mm = 445.63 steps);
//
bool askedForData2 = false;
bool gotData2 = false;
//
float spd; //calculated syringe pump speed in steps/sec since (mm/s) *(steps/mm)
int incomingByte = 0;   // for incoming serial data
//
bool askedForData3 = false;
bool gotData3 = false;
float M;
//







void MotorSpdfinder() { //motor speed for moving stage
  if (!askedForData1) {
    Serial.println("Please enter the desired stage speed in steps: ");
    askedForData1 = true;
  }

  if (askedForData1 && !gotData1) {
    if (Serial.available()) {
      // delay(10);
      spd = Serial.parseFloat(SKIP_ALL, ','); //
      gotData1 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}

void  Distfinder() { //translational distance for the moving stage
  if (!askedForData2) {
    Serial.println("Please enter the desired distance in mm (less than 35 mm): ");
    askedForData2 = true;
  }

  if (askedForData2 && !gotData2) {
    if (Serial.available()) {
      // delay(10);
      Dist = Serial.parseFloat(SKIP_ALL, ',');
      gotData2 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}

void Mfinder() { //select the mode for the moving stage
  if (!askedForData3) {
    Serial.println("Pick your Mode (1,2,3): ");
    askedForData3 = true;
  }

  if (askedForData3 && !gotData3) {
    if (Serial.available()) {
      // delay(10);
      M = Serial.parseFloat(SKIP_ALL, ',');
      Serial.println(M);
      gotData3 = true;
      while (Serial.available()) {
        Serial.read();
      }
    }
  }
}
void ArdFinder() { //Arduino distance finder
  if (askedForData1 && gotData1 && askedForData2 && gotData2 && askedForData3 && gotData3) {
    ArdDist = int(Dist * convF2); //Dist = mm, pow(convF2) = steps/mm, ArdDist = steps
    Serial.print("This is your distance in steps: ");
    Serial.println(ArdDist);
    Serial.println("");
    // delay(1000);
    askedForData1 = false;
    gotData1 = false;
    askedForData2 = false;
    gotData2 = false;
    askedForData3 = false;
    gotData3 = false;
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(enablePin, OUTPUT); //Must enable pins on DRV8825
  digitalWrite(enablePin, LOW); //Must enable pins on DRV8825
  Xaxis.setMaxSpeed(maxspd); //Max speed
  MotorSpdfinder(); //
  Distfinder(); //
  Mfinder(); //
  ArdFinder(); //
  Xaxis.setSpeed(-spd);
  //Xaxis.setCurrentPosition(0);
}
void loop()
{
  MotorSpdfinder();
  Distfinder();
  Mfinder();
  ArdFinder();
  //Xaxis.setSpeed(-spd);
  if ( abs( M - 1)  < 0.01 ) { //distanceToGo()
    Xaxis.setSpeed(spd);
    Xaxis.run();
  }
  if (  abs(M - 2)  < 0.01) {
    if (Xaxis.distanceToGo() == 0)
      Xaxis.moveTo(-Xaxis.currentPosition());
    Xaxis.run();
  }
  if ( abs(M - 3)  < 0.01) {
    //Serial.print("Mode 3: ");
    Xaxis.setSpeed(0);
    Xaxis.run();
  }

}


////         Xaxis.moveTo(ArdDist);
//         Xaxis.run();
//         if (Xaxis.distanceToGo() == 0){
//          Xaxis.moveTo(-Xaxis.currentPosition());
//          Xaxis.run();
// pause & play button (now) when running with the code; userinput time (later)
// manual button to send in manual direction and to stop (forward and backward button sliding control), set the speed manually as finite value
// emergency stop button (exception - c -  interrupt based keyboard)


//Extra Notes:
//Steps per second is the setSpeed(spd) (in units steps per second) -> need to back calculate ; convert rpm to ul/min
//Speed of Stepper: Revolutions per second = steps per second * microstepping / steps per revolution
//check on this -> Speed of Stepper: Revolutions per second = setSpeed(spd) / 200 ->
// const int spd = 100; //Set Current Speed;  steps per second; (+) value

Hopefully, I pasted the above code correctly. Thanks

So if you run this sketch what results do you get?
describe it step by step:

you start the program
you enter .... what?
I press the enter-key then.....
etc. etc. etc.
best regards Stefan

  1. Upload/verify sketch into Arduino
  2. Open serial port/board on Arduino interface (Ctrl+M)
  3. Prompts user to enter speed (steps/s), distance (mm), and mode (1,2,or 3). More specifically, the user enters speed and then presses 'enter key'. The user enters distance and presses 'enter key'. The user enters mode then presses 'enter key'.
  4. User enters random speed, distance, and mode. The Arduino prints out the user's inputs and the converted distance in steps.
  5. For this example, the user has entered mode 2.
  6. Once the user enters all three, the mode is selected in the void loop and the program executes.
  7. Mode 2 results in the motor creating a sound but no movement is created. (in contrast, mode 1 creates a forward movement)

Mode two doesn't set speed.

This may have been the problem. Should I set speed inside the first if-statement or inside the second if-statement? Also is there a reason why delays do not work inside the void loop of my program?

All three I would think.