Let's Make Robots!

Ping ultrasonic sensor, servo and an Arduino

I'm trying to use a servo with my ping ultrasonic sensor to build an autonomous robot like many fellow robot poineers. 

At the moment I'm using an "for" function to rotate my servo in increments of a few degrees, take a measurement with the sonar senor, rotate a few more degrees and then take another measument etc. 

The problem is that the servo does not always correctly rotate to its exact position and judders for a few miliseconds (as if trying to correct itself to the right position). Consequently this prevents my sonar from taking a measurement ( the ACT light does not flash and it returns a "0cm" measurement) and instead the servo will just move to the next position and (may or may not) take another measurement. I'm assuming that the the program is still trying to correct the servo to that exact position unsuccesfully hence preventing the loop from continuing until it eventually "jumps" to the next stage..

Here's the "for" statement i'm using, I've played around a bit with it changing the increments and the servo range however it still sometimes judders and wont take the measurement at that particular angle. Maybe it's just a crappy servo?

 

  for(pos = 0; pos <= 180; pos += 36){         // increments of 36deg so distance is recorded at five different angles

        SonarServo.write(pos);

        Serial.print(pos);

        Serial.print(" Degrees-");

        delay(400);                           //give servo enough time to reach position

        SonarScan();                          //scan for distance measurements

        delay(400);                           //wait long enough for sound to return before moving to next position

        Serial.print(cm);

        Serial.print("cm   ");

 

        }

 

      Serial.println(" ");

 

 

      for(pos = 180; pos >= 1; pos -=36){ //rotates servo in opposite direction whilst taking measurements

        SonarServo.write(pos);

        Serial.print(pos);

        Serial.print(" Degrees-");

        delay(400);

        SonarScan();

        delay(400);

        Serial.print(cm);

        Serial.print("cm   ");

 

        }

 

      Serial.println(" "); 

 

 

any suggestions or ways to circumnavigate this problemo?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I had a similar problem when following one of the examples on the Arduino website. I connected it up exactly as per the schematics (directly to the Arduino) and used the example code. I realised that despite it only being a little 9g servo, it was drawing too much power from the Arduino every time it received an instruction to move. The Arduino seemed to almost reset, while the servo just juddered its way to the next position. The Arduino didn't fully reset, as the example code progressed on to the next stage of a "for loop" and moved the servo on to the next position just like your code, but it did this slowly and in a very juddery manner.

To solve it, I used an external power supply (4xAA batteries) and powered the servo from these. I connected the ground from the batteries to the ground of the Arduino so that the signal wire was correctly grounded. This worked beautifully.

Yes sorry that's a typo, i forgot to change the comment.

When i look closely the ACT light flickers very faintly whilst the servo is juddering as if it's trying to work.

http://www.sparkfun.com/products/9064 

This is the servo that i'm using so i think i've narrowed it down to the fact that it's a cheap servo or what birdmun said about the ADC readings. I do have a short delay, however i'll try experiment with a longer one and see if that helps. I didn't want to slow it down too much because then I'd need to slow my whole robot down to compensate for the time the servo takes complete a full rotation and to take all the measurements 

but, I think you may want to pay attention to some of the other guys here that actually do rather than just the guy that has read about doing. :)

// increments of 36deg so distance is recorded at five different angles - - this will stop at 6 positions not 5.

If you want it to record at 5 positions you need to change the increment to pos+=45

I don't understand why a reading isn't being made. Your board doesn't get feedback from the servo on wheter or not it got to the right position or not, it just tells the servo what to do and reads the sonar after the delay no matter what. I guess it is possible that if the servo is jittering while the sonar is transmitting or receiving there won't be a successful reading...but I'm guessing this isn't what is happening. 

The HXT900 servo is notoriously wacky. The center is not 90 like for any respectable servos, it's around 80. Then if you make it move every degree, sometimes it doesn't move, just jitters and sometimes moves more degrees. I would not use this servo for taking distance readings every degree. I have successfuly used the Turnigy TGY-S3101S from HobbyKing.com for such purposes.

This extra wire, connected to the wiper on the pot, lets them know where the servo is. OddBot did some calculations and came up with 0.6 degrees per 10 bit ADC reading. I mention all this because, it is possible your desired position lands in between one of these ADC readings in your servo and therefore, it can not stop exactly where you want it to.

If your servo does actually stop stuttering after a time maybe you could just add a delay() before you take a reading to ensure the servo has ceased movement before you take your reading.