ping + servo... I'm missing something....

Hi, I’m playing with ping sensor and a servo… I have no problem moving the servo, and no problem pinging with the sensor… but when I mix things then the servo moves to slow… Is there a better way to to this??..

#include <Servo.h> 

Servo pingServo;  
const int pingServoPin = 9;
const int pingPin = 8;
 
void setup() 
{ 
  pingServo.attach(pingServoPin); 
  pingServo.write(90);  
  Serial.begin(9600);
} 
 
 
void loop() 
{
  int dir = pingScan();
  pingServo.write(dir);
  Serial.println(dir);
  delay(5000);
 } 
//-----------------------------------------------------------------------------
int pingScan()
{
  long maxDist = 0;
  int dir = -1;
  
  for(int pos = 0; pos < 180; pos += 1) 
  {                                 
    pingServo.write(pos);       
    long dist = readPing();
    if (dist > maxDist)
    {
      maxDist = dist;
      dir = pos;
    }
    //Serial.println(dist);
    //delay(15);                   
  }
  return dir; 
}
//-----------------------------------------------------------------------------
long readPing()
{
  long duration;
  
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  
  return duration / 29 / 2;
}

Maybe if you removed that 5 second delay?
Don't forget that you now have the round-trip time of the sonar pulse between servo increments.
If you want the sweep to complete faster, make the angular increments larger.

The 5s delay is just between sweeps. Incremeting the angular step works, but I think there is something else wrong...

If I comment the pulseIn function then the servo speed is good, also, if I comment the servo write funcion then the ping works at full speed....

Don't forget that you now have the round-trip time of the sonar pulse between servo increments

Sound travels at around 330m/s, so a two metre round-trip will take 6ms.
If everything that the sensor "sees" is 1 metre away, a full sweep will take 180 * 6ms - over a second

That is!!
With the above code each sweep take 50s,... and everything arround is much less than 1m away.

A sweep, replacing the readPing function with a delay(15) takes 3s!!!!

I'm having the same problem, did you solve it motote?

Hi phokur,
I make some little advances... The problem is the call to pulseIn, sometimes it takes so much time, up to 1000ms, so I supposed it doesn't detect anything and just timeout.

So, I think the problem is the servo refresh call that runs on background that take the processor after the pulse launch and release it to late for the pulseIn call to detect anything.

One solution is to use a custom timeout.. pulseIn(pingPin, HIGH, 10000).. this make the call take at most 10ms and the return is 0, so we can detect bad pings.

But, I resist to consider this as a solution!!!! This is just a workaround not a solution.

I have a similar problem moving a servo and reading a GPS

Stepping a servo by single degree increments when the beam width of the sensor is probably in excess of 20 degrees seems a little pointless.

That's not a bad idea, I'll try sweeping in larger increments.

You don't need larger increments. I have it sweep 180 degrees one degree at a time, calculate the coordinates and show them on the display and it doesn't take more than 2 seconds to do a full 180 sweep. Take a look at my code and video here:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1256716463/6#6

Thanks Ro-Bot-X… I will try this afternoon…

Nope, It doesn't work, I was using arduino 0017 with the servo library and I switch to softwareServo, the result is even worst :(.. the pulseIn call always timeout at 1068ms

Ro-Bot-X... I see you use pin 16 for the servo... which microcontroller are you using, maybe a speed issue... I'm with an Atmega328

Thanks!

Got mine working with a combination of only scanning in 20 degree increments and increasing the delay to let the servo arrive before pinging. I will get an occasional 0 or timeout but I just test for that in my loops.