Using loops to move stepper motors

Hi All,

I am hoping someone might be able to help me, I am having a go at making a pan tilt base and what I want to do is to be able to get it to pan and tilt at increments taking a picture in each area. I have got the maths worked out so I know how far to move everything, however I am a bit lost on how to get the loop working the right way.

At the moment, I have a number of variables which define the number of degrees to travel across the X axis, as well as the number of movements required, and the number of degrees per movement along that axis. This seems to work fine from my serial monitor view and I can see the position changing and updating (as a variable).

What I am stuck on is that I would like to follow a pattern, of going left to right the number of movements, then to move the Y axis next up a movement and then reverse the direction of the X axis movement so it runs right to left, then move the Y axis up again but this time go back to left to right.

So it would eventually get to the highest Y axis point, and move to the final X axis point and finish.

As mentioned I can do the left to right as per the below, however I am a bit confused at how I can get this to best work, my thought was to encase this in another loop for the Y axis, so it does all of the positions X, then moves up, but then I would need to reset the pStepXPos and it would be more like an E pattern.

Is this something that can be achieved, or is it somewhat problematic with Arduino?

Appreciate any tips or suggestions on how I can best achieve this?

Many Thanks,

Travis.

while(pStepXPos < TopX){
Serial.println("Moving to position") & Serial.print(pStepXPos);
  delay(sDelay);
  Serial.println("Focusing & Taking Shot");
  delay(cDelay);
  pStepXPos = pStepXPos + DegStepsX;
 Serial.println("");
}

I did think something like the below may do it, but I hit two problems. The first is that i think my logic for Y axis is wrong, but also and more importantly with my X axis, whilst I can change the counter if I do so (for example subtract instead of add) then the while condition will never exist properly.

Can a while loop be used with two conditions, I am wondering if I can define a window for it to loop in, so for example while(pStepXPos < TopX AND pStepXPos > BottomX )?

My dummy code is below:

int YCounter = 0;

while(pStepYPos < TopY){

  delay(sDelay);
  delay(cDelay);
  pStepYPos = pStepYPos + DegStepsY;
 YCounter = YCounter + 1;
  
while(pStepXPos < TopX){
Serial.print("Moving to X position=") & Serial.print(pStepXPos) & Serial.print(", on Y axis=") & Serial.println(pStepYPos);
  delay(sDelay);
  Serial.println("Focusing & Taking Shot");
  delay(cDelay);

if ( (YCounter % 2) == 0) { 
pStepXPos = pStepXPos - DegStepsX;  
} else {
pStepXPos = pStepXPos + DegStepsX;
}
  
 Serial.println("");
}
}
}

It is generally not much use posting a little piece of a program.

I suggest you think of the problem like this

Create a function to move one step in the X axis
Create a function to move one step in the Y axis

Create a function to move all the way in the X axis by a series of calls to the X step function

Create code to move up the Y axis step by step, calling the X movement function between each Y step.

The Thread planning and implementing a program may provide some ideas

...R

What you need is s couple of nested for loops. Something like this

void setup() 
{
  Serial.begin(115200);

  for (int y = 0; y < 10; y++)
  {
    for (int x = 0; x < 5; x++)
    {
      Serial.print(x);  //in your program move one step in the X axis and take a picture
      Serial.print("\t");
    }
    Serial.println();  //in your program move one step in the Y axis
  }
}
void loop() 
{
}

Thanks for the tips, I think i might look at doing some functions as well as the nested loops.
In terms of the nested looks UKHeliBob, with the example you posted am I right in thinking that it will for loop on the Y axis, incrementing vertically and within each loop run across the X axis incrementing.

Is the easiest way to get it to run back (e.g. decrement) along the X axis after each Y axis move to just add another counter and an if statement, so that it runs forward and backwards along the X axis?

Many thanks

am I right in thinking that it will for loop on the Y axis, incrementing vertically and within each loop run across the X axis incrementing.

That's right, as you can see in the Serial monitor.

Is the easiest way to get it to run back (e.g. decrement) along the X axis after each Y axis move to just add another counter and an if statement, so that it runs forward and backwards along the X axis?

I am not familiar with the control of stepper motors so others can give you more help but having moved along the X axis a known number of steps from zero it must be possible to move back to zero at each change of Y value.

If we call the Y axis zero position an even number then you want the X axis on even steps of the Y axis counter to go left to right and on the odd steps of the Y axis counter, to go right to left.

for (y = 0;y <10;y++){
  //move up 1 level of the Y axis here
  if (y %2 ==0){  // y is even
   xDirection = 1; //left to right
  }
  else{  //y is odd
  xDirection = -1;  //right to left
  }
  for (z = 0;z<100; z++){
  xStepperPosition += xDirection;
  }
}

Thanks for all the useful replies, I did something similar to Henry_Best's suggested, I defined another counter which counted the number of moves up the Y axis, and if it was even it was an increment loop which would move left to right and if it was odd it was a decreasing loop which would move from right to left,

Thanks for all the useful suggestions!

Serial.println("Moving to position") & Serial.print(pStepXPos);

I'm curious about this statement. The Serial.println() function returns the number of bytes written to the serial port. You are bitwise anding those values. Why? You discard the result of the (useless) operation anyway, so what is the purpose?

what is the purpose?

Presumably an attempt to print the text and the value.

I've just realized you are running another Thread on the same subject - duplicating (or more) the effort needed to keep track. Don't Double Post.

Perhaps you can ask the moderator to lock one of them and carry on the discussion on the other?

...R

Instead of trying to re-invent the wheel, have a look into G code. I have a suspicion this is the way you're going.