Servo2Timer and Parallax ultrasonic sensors

Hello. I am trying to drive a servo from Adafruit 180 deg. in increments back and forth. Between moves of the servo I am pinging a parallax ultrasonic sensor to determine distance. I am using Servo2Timer because ultimately I will use the wav shield from Lady Ada which has an interrupt conflict with the standard servo library. The ping sensor does not give a valid distance all the time. The whole sketch is so small I will post it.

//   sketch to move servo and ping a distance
        //   two different ways with different results

#include <ServoTimer2.h>  
const int pin6 = 6;   //attaches servo to pin 6 
const int ping1 = 7;  //attaches ping sensor to pin 7 

long duration1;      // used in ping function
long cm1;             // distance value
int num1;             // direction value out of servo1
int dir;                 // var for switch to sweep servo back & forth in move

ServoTimer2 servo1;    // declare object for servo

void setup() {
  Serial.begin(9600);      // initialize serial communication:
  servo1.attach(pin6);    // attach pin to the servo 
  dir = 0;                      // set direction of servo to zero
  int num1 = 0;             // initialize direction of servo movement
  duration1 = 0;            // used in the ping function
}  

long ping()   //function to drive the Parallax ultrasonic sensors
{
  pinMode(ping1, OUTPUT);    
  digitalWrite(ping1, LOW);
  delayMicroseconds(2);  
  digitalWrite(ping1, HIGH);
  delayMicroseconds(5);   
  digitalWrite(ping1, LOW);
  pinMode(ping1, INPUT);
  duration1 = pulseIn(ping1, HIGH);
  cm1 = microsecondsToCentimeters(duration1);
  return cm1;
}  

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}  // end of ping

long out()           //function to print distances
{
  Serial.print(cm1);
  Serial.println("  cm1  ");
}

int move_another(){     // this code gets good distance values from i = 45 down to i = 12 
                                  // then bad distance- always ~ 15 cm
  int count = 0;
  int i;
  for ( i = 1; i != 60; i++){     // servo starts in the middle so for the first loop it
                                         // hangs from i = 15 until i = 60...doesn't matter...
    if ( i <= 30 ){                   // then it sweeps ~180 deg correctly
      num1 = (servo1.read() - 50);
      delay(5);      
      servo1.write(num1);
      delay(400);
      ping();
      out();
      count = count + 1;
      Serial.print(i);
      Serial.println("  i < 15  ");
    }
    else {
      num1 = (servo1.read() + 50);
      delay(5);
      servo1.write(num1);
      delay(400); 
      ping();
      out();
      count = count + 1;
      Serial.print(i);
      Serial.println("  i > 15  ");
    }
  }
}

int move(){        // This one gets 29 good distances  then 29 bad ones ( always 15 cm)
  switch (dir) {    // ad infinitum
  case 0:
    ping();
    out();
    num1 = (servo1.read() + 50);
    delay(5);      
    servo1.write(num1);
    delay(250);     
    if (num1 >= 2250){ 
      dir = 1;
    }
    break;
  case 1:
    ping();
    out();
    num1 = (servo1.read() - 50);
    delay(5);
    servo1.write(num1);
    delay(250); 
    if (num1 <= 800){
      dir = 0;
    }
    break;  
  }
}

void loop()
{
  move();
//  move_another();  
}

I have tried delays in a variety of values and places in the code because I determined the ping sensors are sensitive to timing. I would appreciate any help anyone can give me. Thanking you in advance.

You've got a mixture of functions that return values that happen to already be global, and functions that don't return anything that are specified as returning values.

That needs to be sorted out.

Hello again. I rewrote my sketch using the servo and ping librarys that come with the IDE. I am still getting low distance values in the middle of the sweep. I can take the servo out of the sketch and the same thing happens. For 9 readings in the middle of the sweep, the distance is 15 cm instead of maximum. I can hold my hand in front of the sensor and it will read shorter distances so the sensor is working properly. I moved the sensor around to eliminate the effect of what I am pinging and can turn the servo by hand but still get low readings in the middle of the sweep. I have 2 servos and 2 ping sensors from Parallax and it happens to both of them. I am attaching the ping sensors to pins 6 & 8 and the servos to pins 7 & 9.

// Sweep
// by BARRAGAN <http://barraganstudio.com> 
// This example code is in the public domain.
#include <Servo.h> 
const int ping1 = 7;
const int ping2 = 9;
int cm;
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() {
  // initialize serial communication:
  Serial.begin(115200);
  myservo.attach(8);  // attaches the servo on pin 9 to the servo object 
  }

int ping(int pingPin){
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  long duration;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);

  return cm;
}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

void loop() 
{
  for(pos = 0; pos < 180; pos += 10)  // 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(50);
    ping(ping1);
    Serial.print(cm);
    Serial.println("  cm up");
    delay(50);
    ping(ping2);
  } 
  for(pos = 180; pos>=1; pos-=10)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(50);    // waits 15ms for the servo to reach the position  
    ping(ping1);
    Serial.print(cm);
    Serial.println("  cm down");
    delay(50);
    ping(ping2);
  }
}

I have put 470mf capacitors across the servos and 33 mf caps across the ping sensors. I drive the servos with a separate 5vDC power supply. These measures had no effect. Does anyone have a suggestion for me? Thanks!

–Cappy Jack

for(pos = 0; pos < 180; pos += 10)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree

It clearly does none of the things described in the comment.
Either match the comment to the code, or simply don’t bother.

You’ve still got a function that returns a global -that’s pointless.

int ping(int pingPin){

  cm = microsecondsToCentimeters(duration);

  return cm;
}

long microsecondsToInches(long microseconds)
{

I'm at a bit of a loss to understand why you have microsecondsToInches return a long that you then return as an int.

In addition to what AWOL says, why, if ping returns something, do you not do anything with the returned value?