Arduino Servo Library- Help ;)

First- For my Thesis Project I'm working with 6 mechanical flowers- that open and close with the servo when the maxsonar range finder detects someone close (0 to 110= OPENS -STAY OPEN until/ 110 to 200 = Close-Stay Close). I'm also getting analog info from the maxsonar to Max Jitter (for video/audio).

QUESTION:

I need to change the servos delay when moving from 10 to 170 and back. But since I'm using the Servo library it doesn't work when changing it in the code and if I change it directly in the servo library code:

#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microsecond

It only changes for 100000- but starts to jump.

My code is really simple:

#include <Servo.h>
Servo myservo;
int pos = 0;
int pos2 = 0;
void setup() {
Serial.begin(9600);
myservo.attach(9);
}

void loop() {

if (analogRead(1)< 110){
Serial.print (analogRead(1));
Serial.println();
myservo.write(170);
// delay(100);
}
else
{
Serial.print (analogRead(1));
Serial.println();
myservo.write(10);
// delay(100);
}
}

---I contacted Michael Margolis-- but he is traveling and can test anything--
He send me a code, and the delay is working nicely but when it gets to 170 the servo starts vibrating (the same when it gets to 10).


#include <Servo.h>

Servo myservo;

int pos = 0;
int pos2 = 0;

void setup() {
Serial.begin(9600);
myservo.attach(9);
}

void loop() {
if (analogRead(1)< 110){
Serial.print (analogRead(1));
Serial.println();
moveTo(170);
}
else{
Serial.print (analogRead(1));
Serial.println();
moveTo(10);
}
}

// move to the given position
// degreesPerStep of 4 moves 160 degrees in a little under a second
// degreesPerStep of 1 moves 160 degrees in around 3.2 seconds
void moveTo(int newPosition){
int degreesPerStep = 4; // decrease this to slow movement

int currentPos = myservo.read();
int movement = newPosition - currentPos; // the number of degrees to move
if(movement < 0){
while(currentPos > newPosition){
currentPos = currentPos - degreesPerStep;
myservo.write( currentPos);
delay(20);
}
}
else{ // movement is >0 )
while(currentPos < newPosition){
currentPos = currentPos + degreesPerStep;
myservo.write( currentPos);
delay(20);
}
}
}

I will greatly appreciate any help.

THANKS ANYA

Changing the refresh interval (the first example) won't work.

The second way is the better way to go about it.

but when it gets to 170 the servo starts vibrating (the same when it gets to 10).

What if you go from 20 to 160?

when it gets to 170 the servo starts vibrating (the same when it gets to 10)

One possibility is that myservo.read doesn't return clean / consistent values. Print movement...

 int currentPos = myservo.read();
 int movement = newPosition - currentPos; // the  number of degrees to move
[glow]// Print movement here[/glow]
 if(movement < 0){

It should be consistently zero when the servo reaches 10 or 170.

Hi Larissa,

I wonder if the problem is overshoot,perhaps it is hunting when it gets to the end points.

If you add some serial print statments in the moveTo function you can see what is actually happening

edit: CodingBadly beat me by two seconds :wink:

Hi AWOL,

I tried that already and it didn't work. I change the

int degreesPerStep = 4; // decrease this to slow movement

From 4 to 1- and is not vibrating! :wink:

Thanks,
Anya

Anya, good to hear you have it working.

If you do want to get the servo moving a little faster, this version of the moveTo function should prevent overshoot.

// move to the given position
// degreesPerStep of 4 moves 160 degrees in a little under a second 
// degreesPerStep of 1 moves 160 degrees in around 3.2 seconds 
void moveTo(int newPosition){
 int degreesPerStep =  4;  // decrease this to slow movement

 int currentPos = myservo.read();
 int movement = newPosition - currentPos; // the  number of degrees to move
 if(movement < 0){
   while(currentPos > newPosition){
     currentPos = currentPos - degreesPerStep; 
     if(currentPos < newPosition)
       currentPos = newPosition; 
     myservo.write( currentPos);
     delay(20);
   }
 }
 else{ // movement is >0 )
   while(currentPos < newPosition){
     currentPos = currentPos + degreesPerStep; 
     if(currentPos > newPosition)
       currentPos = newPosition;  
     myservo.write( currentPos);
     delay(20);
   }
 }
}