Completing a task in a loop before breaking out.

First post, but have read countless forum topics for my Arduino projects and appreciate all contributors...amazing people.

My project is trying to have a stepper motor reach a certain angle in the y-axis if a certain benchmark in the x-axis is reached. I have tried for, if, whiles, do...whiles, and they all do something different. Some just loop inside the loop, or two if's just cycle once through. Below is my latest effort and figure I can start from here:

#include <Stepper.h>

const int stepsPerRevolution = 2050; // designating # of steps per revolution
Stepper myStepper(stepsPerRevolution, 5,4,6,8); // pin designation for Stepper Motor
int stepCount = 0; // number of steps the motor has taken
const int ypin = A2; // y-axis
const int xpin = A1; // x-axis

void setup()
{
// initialize the serial communications:
Serial.begin(9600);
}

void loop(){
// read the sensor value:
int xsensorReading = analogRead(A1);
int ysensorReading = analogRead(A2);
int angle = map(ysensorReading, 315, 345, 30, 0);

if (xsensorReading > 333) //Setting the benchmark in x-axis
{
if (angle > 13) // I would like this "if" statement to loop until the stepper reaches 13 I have used "while" and it freezes up
{ // Several of the above control structures discussed haven't worked nor does this one
myStepper.setSpeed(13);
myStepper.step(-stepsPerRevolution/50);
}

if (angle < 13)
{
myStepper.setSpeed(13);
myStepper.step(stepsPerRevolution/50);}
}

else (xsensorReading < 333);
{
myStepper.setSpeed(0);
}

// print the sensor values:

Serial.print(analogRead(ypin));
Serial.print("\t");
Serial.print(angle);

Serial.print("\t");
Serial.print(analogRead(xpin));
Serial.println();

// delay before next reading:

delay(10 );}

-----So while the y-axis is rotating, I would like it to be completed before seeing the x-axis again. Is there a better control structure? I have replaced those subsequent if's with while's, but it freezes up. Are two "while" loops to much?

Thanks for any insight!

mishap:
trying to have a stepper motor reach a certain angle in the y-axis if a certain benchmark in the x-axis is reached.

I know you know what you mean, but your choice of words is confusing. I guess you might mean:

You have two stepper motors (x-axis and y-axis). When the x-axis stepper motor reaches a certain position, you want to the y-axis stepper to move to a corresponding position.

Is that anywhere close? Do you want the x-axis stepper to stop and wait while the y-axis stepper moves?

Post your while loop version, with code tags please. Without seeing it though, I'm guessing that you don't redo the analog read and map in the while loops, so angle never changes and hence you see the apparent freeze.

Its just one stepper motor responding to the y-axis, but wont do anything until a condition in the x-axis is met.

My code for the while's is:

void loop(){
// read the sensor value:
int xsensorReading = analogRead(A1);
int ysensorReading = analogRead(A2);
int angle = map(ysensorReading, 315, 345, 30, 0);

if (xsensorReading > 333) //Setting the benchmark in x-axis
{
while (angle > 13) // While the angle is greater than 13
{ // initiate Stepper
myStepper.setSpeed(13); //Setting Stepper Speed at 13rpms
myStepper.step(-stepsPerRevolution/50); //Telling Stepper to rotate in the counterclockwise direction 2050/50 steps = 41 steps
}

while (angle < 13) //While angle is less than 13
{ //initiate Stepper
myStepper.setSpeed(13); //Set stepper speed to 13 rpms
myStepper.step(stepsPerRevolution/50);} //Step 41 steps
}

else (xsensorReading < 333); //Otherwise if the x-axis is less than 333 than do not run motor at all
{
myStepper.setSpeed(0);
}

---This is the while loops. I just replaced the if's. Wildbill, that makes a really good point. I have it reading the angle outside the while loop when I should have it rereading it until 13 inside the while loop? Thank you, I will try that out and post results.

mishap:
Its just one stepper motor responding to the y-axis, but wont do anything until a condition in the x-axis is met.

My code for the while's is:

void loop(){
... while (angle > 13) // While the angle is greater than 13
{ // initiate Stepper
myStepper.setSpeed(13); //Setting Stepper Speed at 13rpms
myStepper.step(-stepsPerRevolution/50); //Telling Stepper to rotate in the counterclockwise direction 2050/50 steps = 41 steps
}

while (angle < 13) //While angle is less than 13
{ //initiate Stepper
myStepper.setSpeed(13); //Set stepper speed to 13 rpms
myStepper.step(stepsPerRevolution/50);} //Step 41 steps
}
...

What happens if the start angle is 12 degrees?
Will one motor movement (41 steps) change the angle to more than 13 degrees?
In other words, will your program make the motor 'hunt', never reaching exactly 13 degrees?

Also, you don't need either an if or a while statement if your 41 steps represent exactly one degree.

{     // initiate Stepper
   myStepper.setSpeed(13);     //Setting Stepper Speed at 13rpms
   myStepper.step((-stepsPerRevolution/50)*(angle - 13));   
//Tell Stepper to rotate until angle = 13
//if angle is less than 13, (angle - 13) will be a negative number
//so the step direction will be anticlockwise. (- * - = +)
//If angle is = 13, (angle - 13) will be zero, so the stepper will 
//rotate 0 steps!!
}
while (angle > 13)                     // While the angle is greater than 13
{                                         // initiate Stepper
   myStepper.setSpeed(13);     //Setting Stepper Speed at 13rpms
   myStepper.step(-stepsPerRevolution/50);   //Telling Stepper to rotate in the counterclockwise direction 2050/50 steps = 41 steps
}

Suppose the angle value starts at 15. You move the stepper motor. Then, the angle is still 15, so you move it again. Then, the angle is still 15, so you move it again. Then, the angle is still 15, so you move it again.

Can you see what the problem is? Is the solution obvious yet?

Thanks for the ideas Henry_Best. I like that approach a lot, but my system is dynamic and the angle isn't a one time shot. The angle in the y_axis is always changing. While the motor is moving the amount of angles calculated in your code, by the time it stops it, it will be at completely different angle.

So I do want it to always move the stepper motor. Then, when the angle is still 15, I move it again. Then, when the angle is still 15, I move it again. Then, when the angle is still 15, I move it again. I can definitely use your logic for some other stuff.

I should have explained the project a little more. Imagine a water trough that needs to stay level when its going around a water mill.

I can definitely use your logic for some other stuff.

The point was that inside the while loop, you have to keep updating the condition, so that there is a point at which the while loop can end. If you start at 15 degrees, and rotate to 13, and don't check, then next time around, you'll rotate to 11, then 9, then 7, and pretty soon, you're upside down.

else (xsensorReading < 333);

Should probably read ...

else if ( xsensorReading < 333)

mishap:
Thanks for the ideas Henry_Best. I like that approach a lot, but my system is dynamic and the angle isn't a one time shot. The angle in the y_axis is always changing. While the motor is moving the amount of angles calculated in your code, by the time it stops it, it will be at completely different angle.

Try this:

 Void loop(){
   myStepper.setSpeed(13);     //Setting Stepper Speed at 13rpms
// You only need do this once (unless you're  changing the 
// speed of the motor), not every time you move the stepper.
   int xsensorReading = analogRead(A1);
    //get initial reading of xsensor
   while (xsensorReading > 333) {
     int xsensorReading = analogRead(A1);
     int ysensorReading = analogRead(A2);
     int angle = map(ysensorReading, 315, 345, 30, 0);
               //calculate angle each time through the loop
     myStepper.step((-stepsPerRevolution/50)*(angle - 13)); 
   }
//when it gets here, xsensor reading will be <=333. No need to check it.
   myStepper.setSpeed(0); //Stop motor
}

If your motor is turning at 13 rpm and you turn 1/50th of revolution, it will take
(60/13)/50 seconds = less than 0.1 seconds (not allowing for the miniscule amount of time it takes for the program to run the loop). The angle should never be more than 2 or 3 degrees away from your 13 degrees between one reading and the next. 3 degrees will take the motor 0.3 seconds.
How much faster do you want it?

Thanks for helping me resolve this. I mixed everyone's input and this is what worked (Without notes...sorry):

void loop(){
// read the x sensor value:

int xsensorReading = analogRead(A1);

if (xsensorReading > 333) {

int sensorReading = analogRead(A2);
int angle = map(sensorReading, 315, 345, 30, 0);
if (angle > 14)
{
myStepper.setSpeed(13);
myStepper.step(-stepsPerRevolution/125);
}
if (angle < 12)
{
myStepper.setSpeed(13);
myStepper.step(stepsPerRevolution/125);
}
else (xsensorReading < 333);
{
myStepper.setSpeed(0);

Henry_Best, I did a similar one as your code, but for some reason it wasn't performing as well. I also wanted the x to initiate something, and didn't want the y-axis to correct itself while the x- axis was greater than 333.

lloyddean, with your input I realized I want it to prevent from bouncing outside of 13 to much so I opened up the range to be between 12 and 14 and the amount of steps to be a little over 1 degree.

Like I said thanks for the input options and ideas, it worked out money. If there are other ideas I would be willing to try it out and let you know how the project performs.

I think I'd order of the 'if' ladder differently. What holds me back from commenting is that I can't see your full set of code (a round-about way of saying please post your complete code instead of fragments).

What is this line of code supposed to do?

mishap:
else (xsensorReading < 333);       

That looks familiar; reply 8!

lloyddean:
That looks familiar; reply 8!

Yep, but if/when it gets to that line the xsensorReading will be <=333. No test needed, just else{...}