Re-set stepper position to zero and release stepper

Most of the code was cobbled together to get the Nema 23 steppers working the way I want.

I am using the Serial Monitor to start the code that runs three stepper motors.
When I hit ‘D’ the motors run their routine. If I hit ‘enter’ on my keyboard a second time Lstepper and Rstepper have to reverse 8,000 to get back to position zero.
I know why it does that but I haven’t found an alternative to ‘positions’…so I’d like help with an alternative, or code that will set the three stepper positions to zero.

The second thing I need help with is in releasing power to the steppers so they aren’t using any power.
Nothing is being held so free-wheeling is a good thing.

I’ve been trying a few different things but just have not found anything that works.

Regarding releasing the steppers, I can get the motors to NOT move when placed in the first location here.
example;

AccelStepper Gstepper = AccelStepper(motorInterfaceType, GuideEna, GuideStep, GuideDir);

GuideEna in that first spot keeps the motors from turning but they still make sound.

See the whole code below;

/* Example sketch to control a stepper motor with TB6560 stepper motor driver, AccelStepper library and Arduino: acceleration and deceleration. More info: https://www.makerguides.com */

// Include the AccelStepper library:
#include <AccelStepper.h>
#include <MultiStepper.h>


// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:

#define GuideEna 7
#define GuideDir 6
#define GuideStep 5
#define LEna 10
#define LDir 9
#define LStep 8
#define REna 4
#define RDir 3
#define RStep 2
#define motorInterfaceType 1

int length = 1800;  //steps per revolution


// Create a new instance of the AccelStepper class:
AccelStepper Gstepper = AccelStepper(motorInterfaceType, GuideStep, GuideDir, GuideEna);
AccelStepper Lstepper = AccelStepper(motorInterfaceType, LStep, LDir, LEna);
AccelStepper Rstepper = AccelStepper(motorInterfaceType, RStep, RDir, REna);

MultiStepper steppers;


void setup() {
 Serial.begin(9600);
  // Set the maximum speed and acceleration:
  Gstepper.setMaxSpeed(1000);
  Gstepper.setAcceleration(10000);
  Lstepper.setMaxSpeed(10000);
  Lstepper.setAcceleration(10000);
  Rstepper.setMaxSpeed(10000);
  Rstepper.setAcceleration(10000);


  
  steppers.addStepper(Lstepper);
  steppers.addStepper(Rstepper);
  steppers.addStepper(Gstepper);

digitalWrite(LEna, HIGH);
  
}

void loop() {
  // Set the target position:

  char rx_byte;
  int i;
  if (Serial.available() >1) {
    rx_byte = Serial.read();
    if (rx_byte == 'D') 

 
  delay(10);

 for (i = 0; i<2; i++)   //SET TO NUMBER OF FIGURE EIGHTS
 {
  
  Gstepper.moveTo(200);
    Gstepper.runToPosition();
  Lstepper.moveTo(800);
    Lstepper.runToPosition();
  Rstepper.moveTo(-800);
    Rstepper.runToPosition();
  Gstepper.moveTo(-200);
    Gstepper.runToPosition();
  Lstepper.moveTo(-30);    //Ends pointing forward. Larger negative points the tip lower
    Lstepper.runToPosition();
  Rstepper.moveTo(30);     //Ends pointing forward. Larger positive points the tip lower
    Rstepper.runToPosition();

 }
 delay(10);

 Gstepper.moveTo(100);
 Gstepper.runToPosition();

  // MOVING BOTH MOTORS AT THE SAME TIME

long positions[3]; // Array of desired stepper positions
  
  positions[0] =  8000;
  positions[1] = -8000;
  positions[2] = -100;  //As rope wraps around bundle this is the target before it jumps back to starting point
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
    delay(10);

                           //Resets back to zero location
//  positions[0] =  8000;
//  positions[1] = -8000;
  positions[2] =  0;
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
//     delay(10);


 }
}

This looks like bloatware but that’s ok…I know there are better way’s to write this but it’s outside of my comprehension.
Any help on the two topics would be much appreciated.

spudwastaken: code that will set the three stepper positions to zero.

Do you mean that you want to treat the current position as ZERO and start counting from there

OR

Do you mean that you want to motors to move to some HOME position? If so, how is the home (or zero) position identified - for example are there limit switches?

Moving a motor to a limit switch is generally done with a few lines of code that behave like this

check the switch
if it is not pressed, move one step
repeat as needed

...R

Robin2: Do you mean that you want to treat the current position as ZERO and start counting from there

Yes. Treat the current position as zero near the last line of the sketch.

spudwastaken: Yes. Treat the current position as zero near the last line of the sketch.

The AccelStepper library has a function setCurrentPosition() that is intended for that

...R

Robin2: The AccelStepper library has a function setCurrentPosition() that is intended for that

...R

Just found that;

Lstepper.setCurrentPosition(0);
Rstepper.setCurrentPosition(0);

I tried to beat you but I'm too slow. I was referencing 'steppers' which is not part of accelstepper....duh. So I changed to 'Lstepper' and 'Rstepper'. Thanks.

'position[2]' reaches its destination before the others for some reason.

The reason I used this code was so they all started and finished at the same time. 'position[2]' finishes too early...why?

  void loop();
long positions[3]; // Array of desired stepper positions

  positions[0] =  16000; //As rope wraps around bundle this is the target before it jumps back to starting point
  positions[1] = -16000;
  positions[2] = -100;  

    steppers.moveTo(positions);
    steppers.runSpeedToPosition(); // Blocks until all are in position
      delay(1000);
  positions[2] = 0;
    steppers.moveTo(positions);
    steppers.runSpeedToPosition();

spudwastaken: 'position[2]' reaches its destination before the others for some reason.

The reason I used this code was so they all started and finished at the same time. 'position[2]' finishes too early...why?

Is this question based on the code in your Original Post or in a revised version that includes setCurrentPosition() ? If it is a revised version please post the complete latest program.

What is the time difference between when Gstepper finishes and the others?

What happens if you change the order of the destinations - for example

 positions[0] =  8000;
  positions[1] = -100;
  positions[2] = -8000;

I confess I have not used the MultiStepper library.

...R

Robin2: "Is this question based on the code in your Original Post....."

Yes. I am making changes but the problem was evident prior to my starting this thread. I have a feeling the code I'm cobbling together using both AccelStepper.h and MultiStepper.h are causing the issue but I just don't know.

I think I need to research AccelStepper's method (without MultiStepper) to moving multiple steppers at the same time. Starting and stopping at the same time (not a CNC so close is fine) regardless of steps needed to perform the action.

Problem- position[2] is completing its steps before position[0] and position[1].
Why?

Here is the code in its current state;

/* Example sketch to control a stepper motor with TB6560 stepper motor driver, AccelStepper library and Arduino: acceleration and deceleration. More info: https://www.makerguides.com */

// Include the AccelStepper library:
#include <AccelStepper.h>
#include <MultiStepper.h>


// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:

#define GuideEna 7
#define GuideDir 6
#define GuideStep 5
#define LEna 10
#define LDir 9
#define LStep 8
#define REna 4
#define RDir 3
#define RStep 2
#define motorInterfaceType 1

int length = 1800;  //STEPS PER REVOLUTION


// Create a new instance of the AccelStepper class:
AccelStepper Gstepper = AccelStepper(motorInterfaceType, GuideStep, GuideDir, GuideEna);
AccelStepper Lstepper = AccelStepper(motorInterfaceType, LStep, LDir, LEna);
AccelStepper Rstepper = AccelStepper(motorInterfaceType, RStep, RDir, REna);

MultiStepper steppers;


void setup() {
 Serial.begin(9600);
                          // SPEED AND ACCELERATION
  Gstepper.setMaxSpeed(1500);
  Gstepper.setAcceleration(100000);
  Lstepper.setMaxSpeed(20000);
  Lstepper.setAcceleration(80000);
  Rstepper.setMaxSpeed(20000);
  Rstepper.setAcceleration(80000);
 
  steppers.addStepper(Lstepper);
  steppers.addStepper(Rstepper);
  steppers.addStepper(Gstepper);
  
}

void loop() {
                          // WAIT FOR 'D' KEYPRESS
  char rx_byte;
  int i;
  if (Serial.available() >1) {
   rx_byte = Serial.read();
    if (rx_byte == 'D') 
     delay(10);

 for (i = 0; i<2; i++)   // SET 'i'TO NUMBER OF CYCLES
 {
   Gstepper.moveTo(200);
    Gstepper.runToPosition();
  Lstepper.moveTo(800);
    Lstepper.runToPosition();
  Rstepper.moveTo(-800);
    Rstepper.runToPosition();
  Gstepper.moveTo(-200);
    Gstepper.runToPosition();
  Lstepper.moveTo(-30);    //Ends pointing forward. Larger negative points the tip lower
    Lstepper.runToPosition();
  Rstepper.moveTo(30);     //Ends pointing forward. Larger positive points the tip lower
    Rstepper.runToPosition();
 }
     delay(10);

  Gstepper.moveTo(100); //Location of Gstepper before wrapping begins.
    Gstepper.runToPosition();

//=========================  // MOTORS ARRIVE AT THE SAME TIME  //  ===============================
void loop(); {
long positions[3]; // Array of desired stepper positions

  positions[0] =  16000; //As rope wraps around bundle this is the target before it jumps back to starting point
  positions[1] = -16000;
  positions[2] = -100;  
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
     delay(1000);
  positions[2] = 0;
  steppers.moveTo(positions);
  steppers.runSpeedToPosition();
  
  Lstepper.setCurrentPosition(0); //Sets position of stepper to zero.
  Rstepper.setCurrentPosition(0);
  }
 }
}

Robin2: What is the time difference between when Gstepper finishes and the others?

I increased and decreased the values of position[0] and position[1] to see how it responded. The stepper controlled by position[2] was unaffected. It arrives at its destination at a predetermined speed (not my intent). So it's not coordinating arrival time with the other two.

What happens if you change the order of the destinations - for example Code: [Select]

 positions[0] =  8000;
  positions[1] = -100;
  positions[2] = -8000;

No change.

spudwastaken: I increased and decreased the values of position[0] and position[1] to see how it responded. The stepper controlled by position[2] was unaffected. It arrives at its destination at a predetermined speed (not my intent). So it's not coordinating arrival time with the other two.

Do you mean that the time taken for 8000 steps is the same as it was for 100 steps, or do you mean that the 8000 steps take 80 times as long as the 100 steps?

I don't know why it appears not to be working as stated in the documentation. One thing I would try if it was my problem is to add a 4th phantom motor and a 4th value for the positions[] array and see what happens to the 3 motors in that case. Maybe the problem will move to the non-existent motor ?

I notice that you are using the AccelStepper library in setup() and MultiStepper in loop() - I wonder is that a problem?

It would also be wise to assume the library is doing exactly what it is being told to do and try to figure out why the instructions you are giving it are not what you think they are. At the moment I don't myself see a problem with your code - but that does not mean there is none.

...R

Do you mean that the time taken for 8000 steps is the same as it was for 100 steps, or do you mean that the 8000 steps take 80 times as long as the 100 steps?

What I meant to say is that when I increased the number of steps for 'position[0]' and position[1] that 'position[2]' finished and just waited longer. So increasing or decreasing the steps did nothing to how long it took to 'position[2]' to reach its target.

I notice that you are using the AccelStepper library in setup() and MultiStepper in loop() - I wonder is that a problem?

That's my thought too. A conflict in sharing those two libraries. Sadly I need the steppers to take turns in the code seen before I start the array. And I need the array later.....unless I can move the steppers without multistepper in such a manner that they end up completing their movement at the same time.

.....add a 4th phantom motor and a 4th value for the positions[] array.....

Brilliant! I'll be right back.

Robin2: One thing I would try if it was my problem is to add a 4th phantom motor and a 4th value for the positions[] array and see what happens to the 3 motors in that case. Maybe the problem will move to the non-existent motor ?

Didn't change anything. Great idea though. I wonder If I can set the setMaxSpeed value from the AccelStepper portion to zero so MultiStepper has to take over. (changing setMaxSpeed didn't change anything other than change the movement speed outside of the array portion.)

This is just thinking out loud so it may be useless...

What happens if you set all the position values in AccelStepper to zero at the end of setup() in the hope that Multistepper starts with no preconceived notions.

Does the problem (of the un-synchronised motor) exist in the 2nd and subsequent Multistepper moves, or only in the first move.

What happens if you create 2 sets of stepper instances with one set for AccelStepper and the other set for Multistepper?

And, of course, the very obvious - what happens if you comment-out all the AccelStepper stuff in setup() ?

...R

What happens if you set all the position values in AccelStepper to zero at the end of setup() in the hope that Multistepper starts with no preconceived notions.

No change.

Does the problem (of the un-synchronised motor) exist in the 2nd and subsequent Multistepper moves, or only in the first move.

The motors run as intended until ‘position[0]’ moves 100 steps. It reaches it distance at a set speed regardless of how many steps the other steppers have (in this case the other steppers have 8000 steps.

void loop(); {
long positions[3]; // Array of desired stepper positions

  positions[0] = -100;  //As rope wraps around bundle this is the target before it jumps back to starting point
  positions[1] =  8000; 
  positions[2] = -8000;

And, of course, the very obvious - what happens if you comment-out all the AccelStepper stuff in setup() ?

No improvement of the issue we are focused on.

I love a good mystery but I think I’ll try another approach.
Your help is greatly appreciated. You are all over this forum and the reason I joined and posted.
Tireless help! I don’t know how you do it…working with so many of us noobs.

I’m going to look for a different solution to my issue.
I think I’ll try running a loop ‘x’ times for Lstepper and Rstepper and hopefully find the code that’s non-blocking so that I can move Gstepper at a custom (variable) speed.

And I think, more importantly, work with either MultiStepper or AccelStepper only.

The code should be simple but the last instructions the three steppers get should start and finish at the same time. Something accomplished all day every day with 3D printers, CNC machines and more.
I think the syntax of the two together in my code is not playing well together.

Any suggestions on a rewrite and I’m all ears…or eyes.
I’m starting my re-write now…and my googling.

I’ll post my solution here to help another, once i get it working.

It just occurred to me that the problem might be because you are trying to do too many steps per second. Try a very much slower speed - say 100 rather than 10,000. The AccelStepper library is not able to do high step rates because it uses floating point maths which is very slow on an Arduino.

As you are using stepper drivers that take step and direction signals AND as you seem not to need acceleration (Multistepper does not do acceleration) there is no real need to use either AccelStepper or Multistepper.

Have a look at the examples in this Simple Stepper Code - especially the second example which uses millis() and micros() for non-blocking timing. That idea can easily be extended to do interleaved movements of several steppers. And, from what other Forum members have said, it is possible to get much higher step rates with these programs.

...R

Have a look at the examples in this Simple Stepper Code

Thats great thanks! Ill head over there now.

I messed around with other code and found a problem with MultiStepper (could be something) when reading the serial...or at least with the below code. I like being able to use the serial monitor to start the system. Might be a better way.

char rx_byte;
  int i;
  if (Serial.available() >1) {
   rx_byte = Serial.read();
    if (rx_byte == 'D')

It just occurred to me that the problem might be because you are trying to do too many steps per second. Try a very much slower speed

[u]Brilliant![/u] That worked!!! :o I adjusted my TB6600 driver switches to use fewer steps which moves the motor faster, rather than using code. Lowering the steps in the syntax made the clouds part and the birds sing.

Thank you very much!

jbc

Glad to see you have a solution. The symptoms were very strange.

...R