Ping/distance sensor gets unstable when attaching servo

Hi everyone!

I have a Ping sensor http://www.parallax.com/product/28015 , that is good and precise when it’s the only thing running in arduino; ± 0,3 mm accuracy or so. But when I attach a servo, or several (just in code, not hardware), it suddenly gets unstable and the accuracy drops to about ±1 cm. (adding a real servo does not change anything).

This is whats troubling;
Servo myServo;
myServo.attach(3); <----- makes it unstable.

What is going on? My guess is, that the processor is doing PWM on the servo port, and thats what’s making it shaky. Is there a work around, or another answer to the behavior?

Stable output:
1321 mm
1320 mm
1320 mm
1320 mm
1320 mm
1320 mm
1320 mm
1321 mm
1320 mm
1320 mm
1320 mm
1320 mm
1320 mm
1321 mm

Unstable output when servo is attached:
1300 mm
1302 mm
1307 mm
1309 mm
1311 mm
1314 mm
1318 mm
1318 mm
1318 mm
1319 mm
1313 mm
1311 mm
1309 mm
1307 mm
1302 mm
1303 mm
1301 mm

This is my code:

#include <Servo.h> 

//Servo Servos[4] ; // max servos is 48 for mega, 12 for other boards

const int pingPin = 10;
Servo Servos[8];
void setup() {

  Serial.begin(9600);
  
  Servos[0].attach(2);
  Servos[1].attach(6);
  Servos[2].attach(3);
  Servos[3].attach(7);
  Servos[4].attach(4);
  Servos[5].attach(8);
  Servos[6].attach(5);
  Servos[7].attach(9);
}

void loop()
{
  long temp = readDistance();
  if (temp < 100) {
    Serial.print("");
  }
  Serial.print(temp);
  Serial.println(" mm");

}

long readDistance() {
  long duration, mm;

  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  mm = microsecondsToMillimeters(duration);
  
  delay(10);
  
  return mm;
}

long microsecondsToMillimeters(long microseconds) {
  return microseconds / 2.9 / 2;
}

How are you powering these Servos - 90% of all problems with servos and motors is failure to provide a separate and/or adequate power supply.

The instability happens before I actually wire up a real servo, so the servo is not physically mounted, and therefore not part of the circuit at all.

(When it comes to powering the servos i use a standard PSU 300 Watt.)

Ah, in that case its probably timing accuracy lost because of the timer1 interrupts
used by the Servo library - I think you need to use interrupts to time the ping
sensor to get finer accuracy back (which may give a little jitter on the servos
for the same sorts of reason).

Thanks! you are absolutely right! This did the trick, and the ping sensor became stable:

  noInterrupts();
  duration = pulseIn(pingPin, HIGH);
  interrupts();

However, now the servos jitter as you said, i guess the pwm on the servos returns 0 or 5 vcc shortly. So I tried to Servo.detach() intstead of noInterrupts(), and Servo.attach(SERVO_NUMBER), and that reduces the jitter on the servos, but not enough for my project.. Could I use a capacitor to store the power for the short moment, until the ping has been read?

Be aware that disabling interrupts for any length of time will break millis(), micros() and delay(). They rely on timer0 interrupts every 1.024ms