Servo judder.

Hi,

I'm experiencing a problem keeping a servo steady. I'm working with an arduino pro mini and a home made shield with a servo on it. With a very, very basic sketch that just generates servos pulses at the correct interval the servo remains in position and is absolutely rock-steady - it doesn't move a jot.
As soon as I write to the serial port (just a single line writing the current millis()) then the servo starts to judder, not by much, maybe half a degree, and not very often, on average one judder every 3 seconds. Although it's not enough to cause a problem, it is enough to be annoying!

unsigned long period = 22 ;        // period (in milliseconds) between pulses
unsigned long prevPulse = 0 ;        // moment last pulse was generated.
unsigned long halfPeriod = period / 2;         // half period.
bool elevatorPulse = false;

Servo _elevator;
Servo _rudder;

void setup() 
{
  Serial.begin(115200); // start serial communication at 115200 
  Serial.println("####################     START     ###############################");

  _elevator.attach(6);
  _rudder.attach(5);
}

void loop() 
{
   
  // NOTE - to try to 'smooth out' any battery drain, this code deliberately attempts to seperate
  // the pulses for elevator and rudder by a time equal to half the period - ie about 11 milliseconds
  
  // Decide if it's time for a servo pulse, EITHER for the elevator, OR for the rudder
  if ( millis() > (prevPulse + halfPeriod) )
  {
    
    if (elevatorPulse == false)
    {
      // RUDDER
      // Generate a PWM signal of the appropriate duration to set the servos in the required position.
      _rudder.writeMicroseconds(1490);
      elevatorPulse = true;
      Serial.print("time=<");Serial.print(millis());Serial.println(">"); // The addition of this line causes the judder.
    }
    else
    {
      // ELEVATOR
      _elevator.writeMicroseconds(1490);
      elevatorPulse = false;
    }
    
    // Record the moment this pulse has been applied
    prevPulse = millis();
  } 
}

The above sketch is written just to illustrate the problem, the fact that it works without the print() statement suggests there's nothing wrong with the servo itself, or the power supply to it. I get similar results with different servo positions, and different servos. As far as I can make out somehow the width of the pulse being generated by writeMicroseconds() is being effected by the presence of the print() statement.

My servo libraries are more complex than that shown above, but the still suffer from the same problem - the addition of one of more print() statements causes servo judder. The problem for me is that I need to print() statements because I want to transmit the servo position to a 2nd arduino down the serial port.

Any ideas?

thanks

Ok, I've done a bit more work on this and have found a crude solution.

If I deliberately time my print() statements to leave a few milliseconds gap between them and the writeMicroseconds() statement then the problem seems to go away.

Having said that, if anyone has any idea why a print() statement will 'interfere' with a writeMicroseconds() statement, I'd still like to know.

thanks

There is no point trying to separate the rudder and elevator pulses - the amount of power used by the pulses is trivial. The power is used by the servo motor and that depends on the load on the servo arm, not on the pulses.

Also when you use Servo.writeMicroseconds() that starts the Arduino continually sending a signal for the servo until you give it a different instruction. Servos expect to receive a signal at least every 20 millisecs.

I presume your servos are NOT powered from the Arduino?

...R

the amount of power used by the pulses is trivial.

True, but if I attempt to alter the position of both servos at the same time then they will both attempt to move simultaneously, and will both want to draw current at the same time.

Servo.writeMicroseconds() that starts the Arduino continually sending a signal for the servo until you give it a different instruction

Thanks - I didn't realize this! I had thought it generated a single pulse, not a stream of pulses. The description for this function just says....

Writes a value in microseconds (uS) to the servo

I presume your servos are NOT powered from the Arduino?

No - I'm aware that servos require quite a bit of power so I'm driving from a battery backed 3 amp 6volt regulator.

I'm not clear from your most recent post if you realize that the servos will consume power even if you don't change their position if there is a load on the servo arm.

If there is no load on the servo arms (i.e. they will stay in whatever position they are at when the battery is disconnected) then you could save power by arranging for the Arduino to switch off the power to the servos - perhaps using a relay.

I'm not sure if you MUST simultaneously switch off the stream of pulses with servo.detach() - in other words I don't know if it will damage a servo to send a stream of pulses on the signal wire when the servo is unpowered.

...R

I'm not clear from your most recent post if you realize that the servos will consume power even if you don't change their position if there is a load on the servo arm.

thanks, I'm also aware from doing some experiments that a servo will consume more power when it has to move under load compared to just holding that load.

Thanks