trouble with 'for' loop: programming a servo to perform a specified # of sweeps

Hey there,

I am new to all of this and am trying to get my servo motor to perform a specified number of sweeps based on input from the serial monitor.

My current code is attached below...it waits for me to input something into the monitor, but never slows stops doing sweeps.

If I take out the serial input portion of the code and simple limit i to say 4...the serial.print(i) shows it counting: 0,1,2,3,0,1,2,3,0,1,2,3...etc.

What am I doing wrong??

Thanks in advance!

Cheers :slight_smile:

Olive

#include <Servo.h>
int servoPin = 9;
Servo servo;
int angle = 0; // servo position in degrees
void setup()
{
servo.attach(servoPin);
Serial.begin(9600);
}
void loop(){
int loonum = Serial.read();
for(int i = 0; i < loonum; i++){
Serial.print(i);
// sweep from 0 to 180 degrees
for(angle = 0; angle <= 180; angle++){
servo.write(angle);
delay(15);
}
// sweep back from 180 to 0 degrees
for(angle = 180; angle >= 0; angle--){
servo.write(angle);
delay(15);
}
}
}

Controlling_Speed_of_Continuous_Rotation_Servos.ino (828 Bytes)

/*

Adafruit Arduino - Lesson 14. Sweep

*/
#include <Servo.h>
int servoPin = 9;
Servo servo;
int angle = 0; // servo position in degrees

void setup()
{
  servo.attach(servoPin);
  Serial.begin(9600);
}

void loop()
{
	int loonum = Serial.read();
  for(int i = 0; i < loonum; i++)
  {
  	Serial.print(i);
    // sweep from 0 to 180 degrees
    for(angle = 0; angle <= 180; angle++)
    {
    	servo.write(angle);
      delay(15);
    }
            
    // sweep back from 180 to 0 degrees
    for(angle = 180; angle >= 0; angle--)
    {
    	servo.write(angle);
      delay(15);
    }
  }
}

Most of the time, Serial.read is going to return -1.
That'll make the loops very short

okay gotcha. but then how do I input a number and have the servo do a sweep that number of times...and why doesn't the loop work when I take out the whole loonum thing and the serial.read thing and just put in normal numbers?

Don't forget that the numbers you send (if you're using the serial monitor) are ASCII representations of the numbers, so '0' has the value 48 (0x30), '1' has the value 49 (0x31) and so on.

As it stands, you don't need to wait for a character to become available before reading it (because your loops will not run if you get -1), but you do need to subtract '0' from each character to convert it to the digit it represents, so all in all, it is simpler to wait, by checking "Serial.available ()"

hmmmmm okay I'm pretty new to all this, is there any chance you could show me some example code?

and mainly I just need help not with the serial monitor input, but with making the code work without that (so let's say...just sweeping the servo 3 times and then stopping).

Thanks for your help!

The other thing to remember is that the function "loop()" gets called repeatedly.

so how do I get it to exit the loop?? in order to stop sweeping after the specification i<=2 is met?

You have to decide what you want to do: do you really not want to do anything else until you reset the Arduino, or do you not want to do anything until you send a new command?

well I want it to stop sweeping and then start recording and graphing data (so move onto the next loop I suppose?) basically the sweeping will be used to dispense a certain number of super absorbent polymer beads into a solution, then I will have to program the arduino to start recording and graphing data obtained from a conductivity probe.

well I want it to stop sweeping

So, you sweep only if there is serial data. Stop it from sweeping, then, by keeping your paws off the keyboard.

so how do I get it to exit the loop??

You do not.
You seem to not know that the loop function repeats forever, you do not stop code you just do not call it.
You have to put logic inside the loop that will do what you want and will do it through many iterations of the loop.

This involves using variables and if statements to decide when you want to do certain functions.

Grumpy_Mike:
You do not.
You seem to not know that the loop function repeats forever, you do not stop code you just do not call it.
You have to put logic inside the loop that will do what you want and will do it through many iterations of the loop.

This involves using variables and if statements to decide when you want to do certain functions.

You're right, I didn't know that initially, and that does make things somewhat clearer...but my problem still persists...I'm hoping for help with my for loop as the servo keeps sweeping indefinitely...even when I do this:

#include <Servo.h>

int servoPin = 9;

Servo servo;

int angle = 0; // servo position in degrees

void setup(){
servo.attach(servoPin);
}

void loop(){
for(int i=0; i<=3; i++){
Serial.print(i);
for(angle = 0; angle < 180; angle++){
servo.write(angle);
delay(15);
}
for(angle = 180; angle > 0; angle--){
servo.write(angle);
delay(15);
}
}
}

shouldn't the loop do nothing from i=4 to i=infinity? Thanks for helping me everyone...I'm very very new to this and not so good at coding in general.

Your outer for loop runs four times.
Then "loop()" exits, and gets called again.
Your outer for loop runs four times. . .

aaaaaah okay...so basically, there is no way to do what I'm looking to do?

Yes, see reply #7

okay cool, but how on earth do you set it so that it doesn't do anything until it receives a new command???(again, I'm a really new user...so I'm not quite sure how to go about that)

thanks again :slight_smile:

so basically, there is no way to do what I'm looking to do

You can do what you need to do but you can not do it in the way you have been thinking you can do it.

how on earth do you set it so that it doesn't do anything until it receives a new command?

You put the functions inside a conditional 'if' so it only gets done under specific circumstances.

but how on earth do you set it so that it doesn't do anything until it receives a new command?

void loop()
{
   if(Serial.available() > 0)
   {
      // read the data and do something
   }
   else
   {
      // Do not do anything!
   }
}

aaaaaah okay...so basically, there is no way to do what I'm looking to do?

You should be able to send a command to start the sequence you want. You may need a flag and/or a counter in your looping code. When the start command is received, a flag is checked to see if the servo has been operated. If the servo has not been operated, then the servo sweep loop is entered. If the servo has not made four sweeps as tracked by a counter for each sweep loop, another sweep is made and the the sweep counter is incremented by one. When the four sweeps are completed, the flag is set to indicate all sweeps have been made and the main loop continues to data logging and monitoring for a new command. When a new command is received, the flag and counter is reset and the whole process starts again.