Go Down

Topic: Need help stopping function after x times, thanks (Read 539 times) previous topic - next topic

huntajav

Aug 22, 2017, 12:10 am Last Edit: Aug 22, 2017, 12:19 am by huntajav
Hi guys, I hope my post finds everyone well. I am currently on a project where I am trying to build an applicator that will deliver liquid onto a membrane at a certain speed. So here are the specs:

Two zyltech stepper motors:
-1 to drive my syringe
-1 to drive my stage

Stepper Driver: 2x DRV8825
Board: Arduino Mega 2560

Ultimately, I am trying to make the stage drive motor move from point A to point B and vice versa.
Everything is great except for this one problem, which I need help on:
I only need the stage motor to move to position 1000 and 5000 back and forth for a total of 8 times.
As it stands, the stage moves back and forth without stopping. How can I make this happen?

here is my code:

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

// AccelStepper Setup
AccelStepper stageStep(1, 5, 4);   // (DRIVER=1,STEP=5, DIR=4)
AccelStepper syringeStep(1, 6, 7);   // (DRIVER=1,STEP=6, DIR=7)


const int stageswitch = 3; //black wire for homestage
const int syringeswitch = 2; //red wire for syringe
long initial_homing = -1; // Used to Home Stepper at startup
long initial_home = -1;

int track = 0;
int stageset = 5000;


void setup() {
  pinMode(stageswitch, INPUT_PULLUP);
  pinMode(syringeswitch, INPUT_PULLUP);

  //Set Max Speed and Acceleration of each Steppers at startup for homing
  stageStep.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stageStep.setAcceleration(4000.0);  // Set Acceleration of Stepper
  syringeStep.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  syringeStep.setAcceleration(4000.0);  // Set Acceleration of Stepper


  stagehome();
  syringehome();


  stageStep.moveTo(1000); //from limit switch move to start location
  stageStep.setSpeed(1000);
  syringeStep.moveTo(4000); //move syringe plunger to start position
  syringeStep.setSpeed(1000);

  while (stageStep.distanceToGo() != 0) {
    stageStep.run();
  }
  while (syringeStep.distanceToGo() != 0) {
    syringeStep.run();
  }
  stageStep.moveTo(5000); //preset movement for stage
  stageStep.setSpeed(800);
  syringeStep.moveTo(0); //preset syringe speed
  syringeStep.setSpeed(1000);

}
void loop() {
  if (stageStep.distanceToGo() != 0)
    stageStep.run();
  if (syringeStep.distanceToGo() != 0)
    syringeStep.run();

for(int track = 0; track < 7; track ++){
  if (stageStep.distanceToGo() == 0)
    stageStep.moveTo(5000);
  if (stageStep.distanceToGo() == 0)
    stageStep.moveTo(1000);

}

}


void stagehome() {
  stagehoming code
  stageStep.setCurrentPosition(0);
}

void syringehome()
  syringe homing code
  syringeStep.setCurrentPosition(0);


To recap my question is this:
How would I modify my code so that the stage moves from position 1000 and 5000 for a total of 8 times?

Ultimately I would use a pushbutton that would trigger both steppers to initiate the movement protocol.

Your help is greatly appreciated. Thank you!
-hunter


MorganS

Without doing a major overhaul of your code, this might work...
Code: (Not Tested) [Select]

const int PinRestartButton = 2; //put the 'restart' button on this pin, connect the other side of the button to ground
...
void setup() {
  ...
  pinMode(PinRestartButton, INPUT_PULLUP);
}
void loop() {
  if (stageStep.distanceToGo() != 0)
    stageStep.run();
  if (syringeStep.distanceToGo() != 0)
    syringeStep.run();

  for(int track = 0; track < 7; track ++){
    if (stageStep.distanceToGo() == 0)
      stageStep.moveTo(5000);
    if (stageStep.distanceToGo() == 0)
      stageStep.moveTo(1000);

  }

  while(digitalRead(PinRestartButton) == HIGH) {
    //wait 'forever' until the button is pushed (becomes LOW)
  }

}


Actually, you may want to make it a "start" button and put that extra while loop at the top of the loop().
"The problem is in the code you didn't post."

huntajav

hi MorganS. Thank you for the response. I followed your instructions and added a pushbutton between GND and PIN12 and placed it during the beginning of void loop(). I now have a trigger to start the motion of the motors. However I still face the original problem:
The back and forth motion never stops. In essence violating the "for" statement saying do not exceed 7 times. Would you happen to know how to remedy this?

Code: [Select]

#include <AccelStepper.h>


AccelStepper stageStep(1, 5, 4);   // (DRIVER=1,STEP=5, DIR=4)
AccelStepper syringeStep(1, 6, 7);   // (DRIVER=1,STEP=6, DIR=7)

const int stageswitch = 3; //black wire for homestage
const int syringeswitch = 2; //red wire for syringe
const int PinRestartButton = 12;
long initial_homing = -1; // Used to Home Stepper at startup
long initial_home = -1;

int track = 0;


void setup() {
  pinMode(stageswitch, INPUT_PULLUP);
  pinMode(syringeswitch, INPUT_PULLUP);
  pinMode(PinRestartButton, INPUT_PULLUP);

  //Set Max Speed and Acceleration of each Steppers at startup for homing
  stageStep.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stageStep.setAcceleration(4000.0);  // Set Acceleration of Stepper
  syringeStep.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  syringeStep.setAcceleration(4000.0);  // Set Acceleration of Stepper


  stagehome();
  syringehome();




  stageStep.moveTo(1000); //from limit switch move to start location
  stageStep.setSpeed(1000);
  syringeStep.moveTo(4000); //move syringe plunger to start position
  syringeStep.setSpeed(1000);

  while (stageStep.distanceToGo() != 0) {
    stageStep.run();
  }
  while (syringeStep.distanceToGo() != 0) {
    syringeStep.run();
  }
  stageStep.moveTo(5000); //preset movement for stage
  stageStep.setSpeed(800);
  syringeStep.moveTo(0); //preset syringe speed
  syringeStep.setSpeed(1000);

}


void loop() {

  while(digitalRead(PinRestartButton) == HIGH) {
    //wait 'forever' until the button is pushed (becomes LOW)
  }
 
  if (stageStep.distanceToGo() != 0)
    stageStep.run();
  if (syringeStep.distanceToGo() != 0)
    syringeStep.run();

  for(int track = 0; track < 7; track ++){
    if (stageStep.distanceToGo() == 0)
      stageStep.moveTo(5000);
    if (stageStep.distanceToGo() == 0)
      stageStep.moveTo(1000);

  }

}



To recap:
-pushbutton recommendation worked
-still have the issue of back and forth motion not stopping  after 7 times
-need help with stopping the loop after 7 times or making the program follow the "for statement."

PaulS

You need to loop 8 times, but you need to do more than call moveTo() on each iteration of the loop. You MUST wait for the motor(s) to get to the commanded position BEFORE you tell it/them to move to a new position.
The art of getting good answers lies in asking good questions.

huntajav

PaulS, thank you for the response. Per your post, are you saying that commands cannot be given in a queue-like fashion where the program waits for the next command to execute in the queue? If this is the case, is this why the "for" loop in my code above is being ignored? Are you able to provide an example of such application given the parameters below?

If it takes the stage stepper 18s (800steps/s) over 180 mm, then would I use the "delay()" feature after I called moveTo()? Where would I place this?

Again I appreciate your help. Thanks.
-Hunter

MorganS

Look at the documentation for the library you are using. It has functions to do this for you. stepper.runToPosition() is probably appropriate.
"The problem is in the code you didn't post."

PaulS

Quote
are you saying that commands cannot be given in a queue-like fashion where the program waits for the next command to execute in the queue?
The code is executed in the order defined. If the code calls the function to turn on pin 3 and the next call is to the function to turn on pin 4, you can be sure that the calls will be made in that order.

If the next instruction is a blocking instruction, it will complete before the next instruction is executed.

The run() method is NOT a blocking function. Each time it is called, it might, or it might not, cause the stepper to take a step. ONE step maximum for each call to run().

You need to make sure that the stepper has completed ALL of the commanded steps BEFORE you command it to go to a new position.

Quote
If it takes the stage stepper 18s (800steps/s) over 180 mm, then would I use the "delay()" feature after I called moveTo()?
Absolutely not. delay() will just cause the stepper to sit there, making you look stupid.

Do you REALLY need the acceleration and deceleration that AccelStepper provides? If not, and I doubt that you so, quit using it. Use Stepper, instead. Stepper is a blocking library, which relieves you of the burden of using a non-blocking library (AccelStepper) in a blocking fashion.
The art of getting good answers lies in asking good questions.

MarkT

Speed ramping is mechanically necessary in most stepper applications, stick with AccelStepper...
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up