Bug in the servo library?

Hey everyone!

I am using servos in my project, but I can't get it to work. What I want is to detach and attach a servo in my arduino program (inside the loop function):

#include <Servo.h> 
 
Servo myservo;

void setup() { 
} 
 
void loop(){ 
  myservo.attach(9);
  myservo.write(90);
  delay(200);
  myservo.write(0);
  myservo.detach();
  delay(1000);
}

This is very simple, only for testing, and it doesn't work when I run it. But when I change it to this, it works perfectly:

#include <Servo.h> 
 
Servo myservo;

void setup() {
  myservo.attach(9);
}   
 
void loop(){ 
  myservo.write(90);
  delay(200);
  myservo.write(0);
  delay(1000);
}

Why is that? Do I do something wrong?
Please help me.

The problem is where you detach the servo immediately after the write(0) command. You haven't given it the time to execute the command. So it stays forever at 90 degrees.

Your other sketch doesn't have the detach(), that's what makes the difference...

What I want is to detach and attach a servo in my arduino program (inside the loop function):

Why ?

UKHeliBob:
Why ?

I think that a continuously running servo interferes with the Serial library. Is that possible? And it also consumes less power when it's detached(?)

Perhaps you are confusing Serial with SoftwareSerial (which definitely isn't compatible with Servo).

And it also consumes less power when it's detached(?)

Have you confirmed that by measuring it ?

MarkT:
Perhaps you are confusing Serial with SoftwareSerial (which definitely isn't compatible with Servo).

No, I mean normal Serial. I'm not sure if that is the problem, but I use an arduino in this situation:
My uno gets data via serial and it reads it, and if it's a certain character, it should move a servo to a 30 degrees and after 200ms back to 0. Firstly, it worked ok, but after some time, it started to behave weird: it didn't react to the serial commands.

UKHeliBob:
Have you confirmed that by measuring it ?

No, but I read this somewhere. Power consumption isn't a problem actually, so even if it's not true it doesn't matter.

My uno gets data via serial and it reads it, and if it's a certain character, it should move a servo to a 30 degrees and after 200ms back to 0. Firstly, it worked ok, but after some time, it started to behave weird: it didn't react to the serial commands.

Can you please post the code so that others can test it.

Sure, here is my code:

#include <Servo.h>
#define relayPin 8
Servo myServo;

char oldByte = 0;
unsigned long start = 0;
unsigned long oldMil = 0;

void setup(){
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);
  myServo.attach(9);
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()){
    char incomingByte = Serial.read();
    if(incomingByte == 'd') start = millis();
    switch (incomingByte){
      case 'd':
        if((start - oldMil) > 3000 ) servofunc();
        else if(oldByte != incomingByte) servofunc();
        oldMil = start;
        break;
      case 'n':
        if(oldByte != incomingByte) On();
        break;
      case 'f':
        if(oldByte != incomingByte) Off();
        break;
      default:
        break;
    }
    oldByte = incomingByte;
  }
}

void servofunc(){
  myServo.write(30);
  delay(200);
  myServo.write(0);
}
void On() {  digitalWrite(relayPin, LOW); }
void Off(){ digitalWrite(relayPin, HIGH); }

After some time it stops working, I don't know why. When I reflash the arduino it works again for some time, but then it starts to misbehave. I also have some protection for the servofunc, so it doesn't start a few times in a short time.

Tinkerspy:
The problem is where you detach the servo immediately after the write(0) command. You haven't given it the time to execute the command. So it stays forever at 90 degrees.

Your other sketch doesn't have the detach(), that's what makes the difference...

Thanks a lot, I tried this and it worked perfectly with a 150ms delay. Why does it work this way? Shouldn't it first execute the write(0) function and after that detach? Or does it work with interrupts and it does it 'in the background'?
But anyway, thank you! Now this part of my problem is solved.

tym3k:
Thanks a lot, I tried this and it worked perfectly with a 150ms delay. Why does it work this way? Shouldn't it first execute the write(0) function and after that detach? Or does it work with interrupts and it does it 'in the background'?
But anyway, thank you! Now this part of my problem is solved.

As I understand it a servo is controlled by feeding it a certain PWM signal. To keep the servo moving you must continue to feed it the PWM signal until it reaches the destination position. The PWM signal is created with a timer interrupt which keepd running in the background, it stops when you do a detach. Problem is that most servo's don't give any feedback as to whether the destination has been reached, so the Servo library doesn't know it either and the write() command returns immediately after you call it. What else could it do?

Where does your servo get its power?