Trying to "Sweep" servo for 45 seconds

Hello everyone,

First of all, my apologies if I put this in the wrong message board.

I am trying to run the “Sweep” code for the examples with my servo. I want it to go back and forth for 45 seconds, and than stop for 15 seconds and then sweep again, but it doesn’t work.

#include <Servo.h>
unsigned long time;

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}

void loop()
{
time = millis();
while (time <= 45000){
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}
if (time <= 60000){
int time = 0;
}
Serial.println(time);
// wait a second so as not to send massive amounts of data
delay(1000);
}

Does anyone see what I am doing wrong?

if ( time < 60000 ) is always true.
Please use “60000UL”, the “UL” indicates that it is an unsigned long.

So

#include <Servo.h>
unsigned long time;

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}

void loop()
{
time = millis();
while (time <= 45000){
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}
if (time = 60000UL){
int time = 0;
}
Serial.println(time);
// wait a second so as not to send massive amounts of data
delay(1000);
}

45000 is larger than a normal integer, please use also for that : 45000UL.

To capture the millis() exactly at 60000UL is very dangerous, it can be missed easily.
I prefer this: if ( time >= 60000UL ) {

Please use code tags, it is explained at number 7 here : http://forum.arduino.cc/index.php/topic,148850.0.html

The while ( time < 45000UL ) is not okay. Since time is not updated inside the while-loop, it will run forever.
You can use : if ( time < 45000UL )

Thanks for your help. Sorry I haven't read the forum rules yet, I will soon :slight_smile:

The problem now is that the servo stops after every sweep instead of after 45 seconds

So now the code stops after 45 seconds, but doesn’t start up again after 60…

#include <Servo.h> 
unsigned long time;


Servo myservo;  // create servo object to control a servo 
               // a maximum of eight servo objects can be created 

int pos = 0;    // variable to store the servo position 

void setup() 
{ 
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
 Serial.begin(9600);
} 


void loop() 
{ 
 time = millis();
 if ( time < 45000UL ){
   for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
   {                                  // in steps of 1 degree 
     myservo.write(pos);              // tell servo to go to position in variable 'pos' 
     delay(15);                       // waits 15ms for the servo to reach the position 
   } 
   for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
   {                                
     myservo.write(pos);              // tell servo to go to position in variable 'pos' 
     delay(15);                       // waits 15ms for the servo to reach the position 
   } 
 }
  if ( time >= 60000UL ) {
  int time = 0;
   delay(15000);
 }

}

I’m sorry, I didn’t understand what you wanted to do. You want to sweep again as you wrote in your first post. That is why you had the while-loop.

It is also possible to do the sweep 10 times in a for-loop. But I don’t know if that is what you want.

With your new sketch, time is set to zero, but after that filled with millis().
The millis() itself can not be set to zero.

The sketch could be done with delays, and with millis().

This is the “delay” version. Could you run it, just for fun ?

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
               // a maximum of eight servo objects can be created

void setup()
{
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 Serial.begin(9600);
}


void loop()
{
  for(int i=0; i<10; i++)
  {
   for(int pos = 0; pos < 180; pos++)  // goes from 0 degrees to 180 degrees
   {                                  // in steps of 1 degree
     myservo.write(pos);              // tell servo to go to position in variable 'pos'
     delay(15);                       // waits 15ms for the servo to reach the position
   }
   for(pos = 180; pos>=1; pos--)     // goes from 180 degrees to 0 degrees
   {                               
     myservo.write(pos);              // tell servo to go to position in variable 'pos'
     delay(15);                       // waits 15ms for the servo to reach the position
   }
 }
 delay(15000);
}

With millis() the sketch has to be rewritten completely. Because there are only a few options to avoid the rollover problem. What about a software timer of 1 second ? During the first 45 seconds the sweep is executed.

This is the “millis()” version. I’m not sure if it will work. I’m pretty sure it will not work. It has to be done in different way if you want to use millis().

#include <Servo.h>
unsigned long previousMillis;

Servo myservo;  // create servo object to control a servo
               // a maximum of eight servo objects can be created

void setup()
{
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 Serial.begin(9600);

 previousMillis = millis();
}


void loop()
{
  unsigned long currentMillis = millis();
  if( currentMillis - previousMillis >= 1000UL)    // interval for 1 second
  {
    previousMillis = currentMillis;              // advance for next interval

    // This part is the software timer at 1Hz (1 second interval).
    // By counting up to 60 the counter can be used to do things at certain seconds.

    static int counter;
    counter++;
    if (counter >= 60)
      counter = 0;

    if( counter < 45) {
      // The seconds are between 0 and 45, do a sweep.
     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
    {                                  // in steps of 1 degree
     myservo.write(pos);              // tell servo to go to position in variable 'pos'
     delay(15);                       // waits 15ms for the servo to reach the position
    }
    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
   {                               
     myservo.write(pos);              // tell servo to go to position in variable 'pos'
     delay(15);                       // waits 15ms for the servo to reach the position
   }
 }
 }
}

It worked! Thank you so much! I owe you a beer :slight_smile: