Sonar Car Trouble

I am working on a project using the Arduino Duemilanove, make/mshield(motor shield), 2 continuous parallax servos, 1 T pro 9gram 180 degree servo, and a HC-SR04 sonar sensor. The 2 parallax continuous servos are used to make the car move left, right, backward, and forward. The HC-SR04 sonar sensor is mounted on top of the rotating(right to left) T pro 9gram 180 degree servo. I want the car to avoid objects. When detecting an object I would like the car to go backward and then make a left to switch its path. So far I can get the car to move forward until it senses an object on its right hand side(within 25cm), it then moves back and moves to its left. I can’t get the sensor to measure values while the T pro 9gram 180 degree servo is rotating, only while it’s at degree 0. Another problem is that when it does detect an object on its right hand side, it makes a left for more than the time allotted(In the first code). In the second code I can get the car to do the same task except that now it does return measurements, except that they are all identical to the first measurement. I’ve tried the first code with many adjustments along the way leading to the second code posted and so far I think that maybe whoever reads this post can work with these codes. I would like for someone to please tell me how to also get the T pro 9gram 180 degree servo to rotate while the HC-SR04 sensor gives readings throughout its rotation, therefore alerting the program that there may be on object at some angle other than 0,90, or 180 all while always moving forward until an object is detected.

//Arduino sonar car code 1
#include <Ultrasonic.h>
#define TRIGGER_PIN  12
#define ECHO_PIN     13
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
#include <Servo.h>
Servo myservo1;        
Servo myservo2;
Servo myservo3;
int pos = 0;

void setup()
{
  Serial.begin(9600);
  myservo1.attach(10,544,2400); 
  myservo2.attach(9,544,2400); 
  myservo3.attach(11);  
}  

void loop()
{ float cmMsec, inMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  Serial.print(", CM: ");
  Serial.print(cmMsec);  
delay(200);
 
  for(pos = 0; pos < 180; pos += 1) 
    {                                 
      myservo3.write(pos);               
      delay(5);                      
    }
    for(pos = 180; pos>=1; pos-=1)     
    {                                
      myservo3.write(pos);              
      delay(5);                       
    }
        if(cmMsec<15)
          {
             myservo1.writeMicroseconds(1600); //BACKWARD
             myservo2.writeMicroseconds(1400);
                      delay(2000);       
             myservo1.writeMicroseconds(1400); //LEFT     
             myservo2.writeMicroseconds(1400);
                      delay(2000);
           }   

        else   
          {
             myservo1.writeMicroseconds(1400); //FORWARD
             myservo2.writeMicroseconds(1600);
                      delay(50);
           }
              
}

and

//Arduino sonar car
#include <Ultrasonic.h>
#define TRIGGER_PIN  12
#define ECHO_PIN     13
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
#include <Servo.h>
Servo myservo1;        
Servo myservo2;
Servo myservo3;
int pos = 0;

void setup()
{
  Serial.begin(9600);
  myservo1.attach(10,544,2400); 
  myservo2.attach(9,544,2400); 
  myservo3.attach(11,250,1200);  
}  

void loop()
{ 
  for(pos = 0; pos < 90; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  }
  float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  Serial.print(", CM: ");
  Serial.print(cmMsec);  
  delay(200);


  if(cmMsec>25)
  { 
    //FORWARD
    myservo1.writeMicroseconds(1400); 
    myservo2.writeMicroseconds(1600);
    delay(500);   
  }
  if(cmMsec<25) 
  { //BACKWARD
    myservo1.writeMicroseconds(1600);
    myservo2.writeMicroseconds(1400);
    delay(4000);       
    myservo1.writeMicroseconds(1400); //LEFT     
    myservo2.writeMicroseconds(1400);
    delay(200);
  }
  
  delay(2000);
for(pos = 90; pos < 180; pos += 1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);
  }
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  Serial.print(", CM: ");
  Serial.print(cmMsec);  
  delay(200);
  if(cmMsec>25)   
  { //FORWARD
    myservo1.writeMicroseconds(1400); 
    myservo2.writeMicroseconds(1600);
    delay(500); 
  }
  if(cmMsec<25) 
  { //BACKWARD
    myservo1.writeMicroseconds(1600); 
    myservo2.writeMicroseconds(1400);
    delay(4000);       
    myservo1.writeMicroseconds(1400); //LEFT     
    myservo2.writeMicroseconds(1400);
    delay(200);
  }
 
  delay(2000);
for(pos = 180; pos > 90; pos -= 1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);
  }
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  Serial.print(", CM: ");
  Serial.print(cmMsec);  
  delay(200);
        // waits 15ms for the servo to reach the position 
  
  if(cmMsec>25)
  {//FORWARD
    myservo1.writeMicroseconds(1400); 
    myservo2.writeMicroseconds(1600);
    delay(500);
  }
  if(cmMsec<25) 
  {
    myservo1.writeMicroseconds(1600); //BACKWARD
    myservo2.writeMicroseconds(1400);
    delay(4000);       
    myservo1.writeMicroseconds(1400); //LEFT     
    myservo2.writeMicroseconds(1400);
    delay(200);
  }
  delay(2000);
for(pos = 90; pos > 0; pos -= 1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);      // waits 15ms for the servo to reach the position 
  }
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  Serial.print(", CM: ");
  Serial.print(cmMsec);  
  delay(200);
   
  if(cmMsec>25)
  {
    //FORWARD
    myservo1.writeMicroseconds(1400); 
    myservo2.writeMicroseconds(1600);
    delay(500);
  }
  if(cmMsec<25) 
  {
    myservo1.writeMicroseconds(1600); //BACKWARD
    myservo2.writeMicroseconds(1400);
    delay(4000);       
    myservo1.writeMicroseconds(1400); //LEFT     
    myservo2.writeMicroseconds(1400);
    delay(200);
  }
  delay(1000);
 


}

Some quick (preliminary) comments:

  • Please shrink photos to somwhere around 640x480. Hi-res photos are fun to look at, but are a real PIA to download.
  • The delays in your program are a more serious problem. I'm planning to download and look over your code, but already I'm thinking that you're crippling your processing with delay() calls. However convenient it may seem, delay() is [u]not[/u] your friend.

I look forward to your reply.

Ok. I pulled the code and took a look. I'm pretty sure where your difficulties are coming from, but need answers to a few questions in order to give good answers.

  1. what does ultrasonic.timing() return?

  2. What does ultrasonic.convert(x,Ultrasonic::CM) do/return?

  3. Please explain (brief please) what myservo1.writeMicroseconds(n) does.

  4. What is the range of the ultrasonic device?

  5. I'm not sure what the proper vocabulary is, but what is the aperture angle of the ultrasonic device?

This looks as if it could be a really fun project! :)

(I will answer your questions to my best ability. I’m quite new to programming and only know the basics. I have been getting ideas from the samples I see around the net and use them to add them to my projects.)
1.Used to manipulate the frequency (in micro seconds) as which I would like to see measurements.
2. Makes it so that the HC-SR04 sends the pulse and measure the amount of time taken to return to get the distance.
3. Tells the servo to rotate with a certain speed in one direction. 1500 being no movement. One is 1400 and the other is 1600 because the servos are opposite in the way they have been positioned.
4. Approximately 2cm-500cm
5. Effectual angle is <15°

I am extremely appreciative of the time you are taking to view my project. You really don’t know how much this means to me. Thought you should know.

Thanks - more/better info almost always means better help. If you were looking for somebody who knows a little about servos and rangefinders, then you've had incredibly good luck because I know about as little as can be known. :)

Here's a short function to think about. It still has the awful delay(), but it accepts an angle and returns a range:

float range(int angle)
{  static int old = 0;
   if (angle != old)
   {  myservo3.write(angle);
      delay(15 * ((angle>old)?angle-old:old-angle));
      old = angle;
   }
   return ultrasonic.convert(ultrasonic.timing(),Ultrasonic::CM);
}

Note that at 15 msec/deg, a full scan will take about 2.7 seconds. I'm not sure what the forward speed is, but I suspect that it might be more productive to do 180° scans only selectively - and keep the bot's attention on where it's going.

You might consider dividing the 180° field of view into twelve 15° segments and maintaining an array of twelve elements containing the distance to the nearest obstacle (if any) in each direction.

The code you posted swings the rangefinder around and then looks for an obstacle only at the final position. I'm unsure about the benefit of only looking straight right, straight ahead, or straight left. Seems to me that it'd make more sense for it to watch where it's going and if it finds itself approaching an obstacle, then slow down and look for an avoidance pathway (but as I say, I don't know much about these things).

I would guess that once the range-finding and motion control are worked out, you'll be ready to tackle the problem of scanning continuously while the bot is in motion - but it'll be easier to work out (and verify) the basics first.

I been going over the code in my head and I thought that this should end up working.

//Arduino sonar car
#include <Ultrasonic.h>
#define TRIGGER_PIN  12
#define ECHO_PIN     13
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
#include <Servo.h>
Servo myservo1;        
Servo myservo2;
Servo myservo3;
int pos = 0;
float cmMsec;

void setup()
{
  
  myservo1.attach(10,400,2400); 
  myservo2.attach(9,400,2400); 
  myservo3.attach(11);  
}  

void loop()
{
  do
  {
  float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  Serial.print(", CM: ");
  Serial.print(cmMsec);  
  delay(200);
  }
  while(cmMsec<15);
  {
    myservo1.writeMicroseconds(1400); //FORWARD
       myservo2.writeMicroseconds(1600);
                delay(1000);
    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
    {                                  // in steps of 1 degree 
      myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(100);                       // waits 15ms for the servo to reach the position 
    }
    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
    {                                
      myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(100);                       // waits 15ms for the servo to reach the position 
    }
   if(cmMsec>=15);
    {
             myservo1.writeMicroseconds(1600); //BACKWARD
             myservo2.writeMicroseconds(1400);
                      delay(2000);       
             myservo1.writeMicroseconds(1400); //LEFT     
             myservo2.writeMicroseconds(1400);
                      delay(2000);
     }}}

My servos aren’t rotating at all now. I have no idea why. This code seems like it should work.

I have no idea why

What are your debug prints telling you?

     }}}

I've given up on trying to help people that post code like this. If you put each { and } on separate lines, and use Tools + Auto Format, you may see what is wrong with the logic of your program. If not, post it again.

Removing useless { and } would be a good idea, too.

Finally, global and local variables of the same name is a sure recipe for disaster. You absolutely need to stop doing that.

Look at your "if" and your "while" and ask yourself about punctuation.

There are no debug prints. I fixed the punctuation on the if and while. My new code is

//Arduino sonar car
#include <Ultrasonic.h>
#define TRIGGER_PIN  12
#define ECHO_PIN     13
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
#include <Servo.h>
Servo myservo1;        
Servo myservo2;
Servo myservo3;
int pos = 0;
float cmMsec;

void setup()
{  
  myservo1.attach(10,400,2400); 
  myservo2.attach(9,400,2400); 
  myservo3.attach(11);  
}  
void loop()
{
do  
  {
    long microsec = ultrasonic.timing();
    cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
    Serial.print(", CM: ");
    Serial.print(cmMsec);  
    delay(200);
  }
  while(cmMsec>15);
  {
    myservo1.writeMicroseconds(1400); //FORWARD
    myservo2.writeMicroseconds(1600);
    delay(1000);
    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
    {                                  // in steps of 1 degree 
      myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(10);                       // waits 15ms for the servo to reach the position 
    }
    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
    {                                
      myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(10);                       // waits 15ms for the servo to reach the position 
    }
    if(cmMsec<=15)
    {
      myservo1.writeMicroseconds(1600); //BACKWARD
      myservo2.writeMicroseconds(1400);
      delay(2000);       
      myservo1.writeMicroseconds(1400); //LEFT     
      myservo2.writeMicroseconds(1400);
      delay(1000);
    }
  }
}

Now the car waits for an object within 15cm to move forward and only reads it at the 0 degree mark(Right most). The car goes to its left if values are greater then 15cm. And there is are no values being printed. Everything that can go wrong is going wrong.

The do statement is improperly indented. Some white space after the while statement would be useful. The { on the next line is unnecessary, as is the matching } later.

    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
    {                                  // in steps of 1 degree 
      myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(10);                       // waits 15ms for the servo to reach the position 
    }
    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
    {                                
      myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(10);                       // waits 15ms for the servo to reach the position 
    }

Why bother waving the servo around? It isn’t accomplishing anything.