return to start position - how to code?

I’ve written the stepper motor code below to move a carriage in 5 equal steps in one direction. I’d like to move it back to it’s starting position in one step and start over again. I’ve tried to add a function to do so but haven’t had any luck and not for lack of trying. I’ll need to call that function several times so a simple loop wouldn’t work. Thanks for any suggestions you may have.

#include <AFMotor.h>
  int i = 0;
  int yCount = 4;
  int xCount = 5;
  
AF_Stepper motor(200, 1);


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps

  motor.setSpeed(100);  // 100 rpm

}

void loop() {
while(i < yCount){
  motor.step(500, FORWARD, SINGLE); 
  motor.release();
  delay(2000);
  i++;

}
}
while(i < yCount){
  motor.step(500, FORWARD, SINGLE); 
  motor.release();
  delay(2000);
  i++;

This would make a lot more sense expressed as a for loop.

Then, you could create another for loop to step the other way, 5 times as many times.

I chose a while loop so I could have it count up to a predefined variable number, which is user configurable before launch. Would you still use a for loop in this case? Also, I would like to be able to call this function to return to 'home' position.

while(i < yCount)
{
  // do something
  i++;
}

is exactly the same as:

for(i =0; i<yCount; i++)
{
   // do something
}

But, because the latter is far more common, it is much quicker for most people to see what it is doing. And, it is clear that all the variable are initialized at the proper time.

If you don’t want to reset i each time, the initialization portion can be omitted. Though, I don’t encourage you to do that.

Also, I would like to be able to call this function to return to ‘home’ position.

void returnHome()
{
   for(int i=yCount; i>=0; i--)
   {
      motor.step(500, FORWARD, SINGLE); 
      motor.release();
      delay(2000);
   }
}

For loops can count down, too.

I guess I was hoping I could employ a function which takes the factor of the Ycount and stepper steps to quickly move back rather than doing it in intervals which would take unnecessary time.

In a ‘for’ loop, am I free to use my own variable in place of the ‘i’? It’s unclear to me and I’ve broken enough for loops in learning that it’s still unclear.

I plugged in your for loop and the motor sits there at the end of my successive steps.

I’ll keep working at it but I’d learn more at this point seeing how my code above would look than continue guessing at it’s implementation.

In a 'for' loop, am I free to use my own variable in place of the 'i'?

Yes, but in this case 'i' is just the loop variable. But certainly you can use whatever you want.

Here’s where I’m at:

#include <AFMotor.h>
  int i = 0;
  int yCount = 4;
  int xCount = 5;
  
AF_Stepper motor(200, 1);


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps

  motor.setSpeed(100);  // 100 rpm

}
void returnHome()
{
   for(int q=yCount; q>=0; q--)
   {
      motor.step((200 * yCount), BACKWARD, SINGLE); 
      motor.release();
   }
}


void loop() {
while(i < yCount){
  motor.step(500, FORWARD, SINGLE); 
  motor.release();
  delay(2000);
  i++;
  returnHome;
} 
}

I suspect the returnHome; should not be inside that loop but placing it elsewhere also fails. Ideas?

@Paul S

void returnHome()
{
   for(int i=yCount; i>=0; i--)
   {
      motor.step(500, FORWARD, SINGLE); 
      motor.release();
      delay(2000);
   }
}

Hi Paul, :)

I do not use AFMotor.h at all but I noticed this: shouln't direction be "BACKWARD" in the returnHome() function?

I suspect the returnHome; should not be inside that loop but placing it elsewhere also fails. Ideas?

Yes but, have you tried writing returnHome(), not returnHome, out of the loop? Maybe that's what you need?

I do not use AFMotor.h at all but I noticed this: shouln't direction be "BACKWARD" in the returnHome() function?

Yes.

Yes but, have you tried writing returnHome(), not returnHome, out of the loop? Maybe that's what you need?

It is.

Bibre, I took a lot of pot shots at that and similar arrangements and still no joy as yet. Not giving up, I’m sure it’s something simple for which I’ll feel foolish once resolved : )

Here’s my latest version, which compiles fine and advances through the first forward steps and stops, ignoring the returnHome function…

#include <AFMotor.h>
int i = 0;
int yCount = 4;
int xCount = 5;


AF_Stepper motor(200, 1);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  motor.setSpeed(100);  // 100 rpm
}

void loop() {
  while(i < yCount){
    motor.step(500, FORWARD, SINGLE); 
    motor.release();
    delay(2000);
    i++;

  } 
}
void returnHome() {
  motor.step((500 * yCount), BACKWARD, SINGLE); 
  motor.release();
}

@nSomnius

You defined the returnHome function but you are not calling it. Try:

#include <AFMotor.h>
int i = 0;
int yCount = 4;
int xCount = 5;


AF_Stepper motor(200, 1);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  motor.setSpeed(100);  // 100 rpm
}

void loop() {
  while(i < yCount){
    motor.step(500, FORWARD, SINGLE); 
    motor.release();
    delay(2000);
    i++;

  } 
  returnHome();                                              <== add this line
}
void returnHome() {
  motor.step((500 * yCount), BACKWARD, SINGLE); 
  motor.release();
}

That helped a lot, thank Bibre. Still needs work though. The carriage seems to loop the last returnHome function, so rather than simply go back to starting position, it continues to travel backwards indefinitely. I simplified it by removing the compound step value (500 * yCount) to a basic value (500) to rule that out but no go. Here’s where I’m at now:

#include <AFMotor.h>
int i = 0;
int yCount = 4;
int xCount = 5;


AF_Stepper motor(200, 1);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  motor.setSpeed(100);  // 100 rpm
}

void loop() {
  while(i < yCount){
    motor.step(500, FORWARD, SINGLE); 
    motor.release();
    delay(2000);
    i++;

  } 
  returnHome();                                              
}
void returnHome() {
  motor.step(500, BACKWARD, SINGLE); 
  motor.release();
}

Look at your loop function. It gets called in an endless loop.

void loop() {
  while(i < yCount){
    motor.step(500, FORWARD, SINGLE); 
    motor.release();
    delay(2000);
    i++;

  } 
  returnHome();                                              
}

The variable i starts at 0. So, since i is less than yCount, the while loop runs. The device steps forward 500 times. Then, i is incremented. It’s still less than yCount, so the device steps 500 more times. After a few increments, i is finally equal to or greater than yCount.

So, the while loop ends, and returnHome() is called. Now, returnHome() was just provided as an example of how to write a function, but you’ve adopted it as gospel. What it does is step backwards 500 times, and return.

So, loop ends, and gets called again. Nothing has changed in the values of i and yCount, so i is still equal yCount, so the while loop is skipped. returnHome is unconditionally called, does some stuff unconditionally, and returns.

So, loop ends, and gets called again. Nothing has changed in the values of i and yCount, so i is still equal yCount, so the while loop is skipped. returnHome is unconditionally called, does some stuff unconditionally, and returns.

So, loop ends, and gets called again. Nothing has changed in the values of i and yCount, so i is still equal yCount, so the while loop is skipped. returnHome is unconditionally called, does some stuff unconditionally, and returns.

So, loop ends, and gets called again. Nothing has changed in the values of i and yCount, so i is still equal yCount, so the while loop is skipped. returnHome is unconditionally called, does some stuff unconditionally, and returns.

See where the problem is?

Let me see,

What you want is to step your motor forward 4 times, wait 2 seconds after each step and then move it back to its ‘home’ position, in a single step; and then repeat everything again or ‘halt’ there doing nothing?

If so:

#include <AFMotor.h>
int i = 0;
int yCount = 4;
int xCount = 5;


AF_Stepper motor(200, 1);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  motor.setSpeed(100);  // 100 rpm
}

void loop() {
  while(i < yCount){
    motor.step(500, FORWARD, SINGLE); 
    motor.release();
    delay(2000);
    i++;
  } 
  returnHome();                                              
  delay(10000);     <== (optional) 10 sec delay at end of main loop
}
void returnHome() {
  motor.step(2000, BACKWARD, SINGLE);     <== changed 
  motor.release();
}

BTW: Dou you have a page address where I can study the AFMotor.h library? :slight_smile:

So, loop ends, and gets called again. Nothing has changed in the values of i and yCount, so i is still equal yCount, so the while loop is skipped. returnHome is unconditionally called, does some stuff unconditionally, and returns.

Paul is right, i is never reset back to zero at end, or beginning, of loop(). I didn't see that one.

You need

  i = 0;

right before your while statement.

@ I appreciate your taking the time to write that all out to state the obvious.

Moderator edit: Insulting personal remarks deleted. (Nick Gammon)

@Billy, thanks again for applying yourself to the problem I reluctantly reached out for help with. You have it right. As for the stepper.h library, your wit is above me. Or am I being too careful in not putting my head in the lion's mouth? : )

Hi nSomnius,

As for the stepper.h library, your wit is above me. Or am I being too careful in not putting my head in the lion's mouth? : )

No, really, wit or no wit, I can't find AFMotor.h :roll_eyes: and I've never used it up to now. I did find Stepper but that's not the same, or is it?. If you know where AFMotor.h is, please post the URL to the the page. I'll appreciate it very much. Thanx!

C'mon, no lions here. Actually the only lion in my family is the drugstore that my German great-grandfather founded both in Matamoros, Mexico and Brownsville, TX and whose name was "Droguería del León" (The Lion's Drugstore), but that was circa 1880, hehe. :)

https://github.com/adafruit/Adafruit-Motor-Shield-library

My apologies, I thought it was in the Stepper library myself. I've seen a few variations of stepper motor control, this looks to be super lean by comparison.

Thank you for the URL, nSomnius :)

I will study this library's methods in more depth. There's so much to learn that I haven't been doing much on my train layout.

One thing is to arrive to a good circuit/sketch design, which 'I think' I have done already, and another is to get hands on, on the wiring. My software sketch/FreeBasic is already up'n running.

I like being here at the board, trying to learn some more and also maybe being of help. Anyway, I'm just a Newbie here.

I may use AFMotor and Stepper for my trains in the future, who knows? They're good tools to try to design something newer, and hopefully creative. ;)