element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum Arduino Obstacle Avoidance and Cliff Avoidance Robot
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • Replies 13 replies
  • Subscribers 393 subscribers
  • Views 1168 views
  • Users 0 members are here
  • environment
  • robot
  • development
  • programing
  • arduino
Related

Arduino Obstacle Avoidance and Cliff Avoidance Robot

Former Member
Former Member over 12 years ago

Hello everyone in the Arduino community. Im asking for some help with programing a 3 wheel robot with 2 ultrasonic sensors. The 1st ultrasonic sensor (Parallax)  is used as an obstacle avoidance sensor. The second ultrasonic sensor (SR04) is used to check the ground distance so the robot won't fall into a hole in the ground. The problem I'm having is that the Center Distance Reading from the ultrasonic sensor is always reading zero (0) even if there's nothing in front of the ultrasonic sensors. I have used both of these ultrasonic sensors in another project and they both work perfectly so I now there's nothing wrong with the ultrasonic sensors. I will attach the code I'm using for this project. Thank you in advance for your help.

 

#include <AFMotor.h> // Enables the Motor library

#include <Servo.h> // Enables the Servo library

 

 

Servo PingServo;

AF_DCMotor motor1(1); // Motor 1 is connected to the port 1 on the motor shield

AF_DCMotor motor2(2); // Motor 2 is connected to the port 2 on the motor shield

int minSafeObstacleDist = 11 ; // Minimum distance for ping sensor to know when to turn

int pingPin = A0; // Parallax Ping sensor is connected to port A5

int minSafeGroundDist = 2 ; // Minimum distance for ping sensor to know when to turn

int TrigPin = A5; // SR04 Ping sensor TrigPin is connected to port A5

int EchoPin = A4; // SR04 Ping sensor EchoPin is connected to port A4

int centerDist, leftDist, rightDist, backDist; // Define variables center, left, right and back distance

long duration, inches, cm; // Define variables for Ping sensor

 

void setup() {

PingServo.attach(10); // Servo is attached to pin 10 in the motor shield

PingServo.write(90); // Center the Ping sensor (puts it at 90 degrees)

motor1.setSpeed(250); // Sets the speed of the first motor.

motor2.setSpeed(250); // Sets the speed of the second motor.

 

Serial.begin(9600); // Enables Serial monitor for debugging purposes

Serial.println("Serial test!"); // Test the Serial communication

 

}

 

void AllStop() {

motor1.run(RELEASE); // Turns off motor 1

motor2.run(RELEASE); // Turns off motor 2

}

void AllForward() { // Makes the robot go forward

motor1.run(FORWARD); // Motor 1 goes forward

motor2.run(FORWARD); // Motor 2 goes forward

Serial.println("Going forward"); // Prints a line in the serial monitor

}

void turnRight() { // Makes the robot go right

motor2.run(BACKWARD); // Turns off motor 2

motor1.run(FORWARD); // Motor 1 goes forward

delay(1600); // Time required to turn right (1.6 seconds)

Serial.println("Motors going Right"); // Prints a line in the serial monitor

}

void GoBack(){ // Makes the robot go back

motor2.run(BACKWARD); // Motor 2 goes back

motor1.run(BACKWARD); // Motor 1 goes back

delay(1600); // Time Required to go back (1.6 seconds)

Serial.println("Backward"); // Prints a line in the serial monitor

}

void turnLeft() { // Makes the robot go Left

motor2.run(FORWARD); // Motor 2 goes forward

motor1.run(BACKWARD); // turns off motor 1

delay(1600); //Time Required to turn left (1.6)Seconds

Serial.println("Motors going Left");// Prints a line in the serial monitor

}

// Starts the loop to decide what to do

void loop()

{

LookAhead();

Serial.print(inches);

Serial.println(" inches"); // Prints a line in the serial monitor

if((inches >= minSafeObstacleDist) && (inches <= minSafeGroundDist))/* If the inches in front of an object is greater than or equal to the minimum safe distance A (11 inches) and

floor distance is less than or equal to the minimum safe distance B, react*/

{

AllForward(); // All wheels forward

delay(110); // Wait 0.11 seconds

}else // If not:

 

{

AllStop(); // Stop all motors

LookAround(); // Check your surroundings for best route

if(rightDist > leftDist) // If the right distance is greater than the left distance , turn right

{

turnRight();

}else if (leftDist > rightDist) // If the left distance is greater than the right distance , turn left

{

turnLeft();

}else if (leftDist&&rightDist<minSafeObstacleDist) // If the left and right distance is smaller than the min safe distance (11 inch) go back

{

GoBack();

}

}

}

 

unsigned long ping() {

pinMode(pingPin, OUTPUT); // Make the Pingpin to output

digitalWrite(pingPin, LOW); //Send a low pulse

delayMicroseconds(2); // wait for two microseconds

digitalWrite(pingPin, HIGH); // Send a high pulse

delayMicroseconds(5); // wait for 5 micro seconds

digitalWrite(pingPin, LOW); // send a low pulse

pinMode(pingPin,INPUT); // switch the Pingpin to input

duration = pulseIn(pingPin, HIGH); //listen for echo

unsigned long ping();

pinMode(TrigPin, OUTPUT); // Make the Pingpin to output

digitalWrite(TrigPin, LOW); //Send a low pulse

delayMicroseconds(2); // wait for two microseconds

digitalWrite(TrigPin, HIGH); // Send a high pulse

delayMicroseconds(5); // wait for 5 micro seconds

digitalWrite(TrigPin, LOW); // send a low pulse

pinMode(EchoPin,INPUT); // switch the Pingpin to input

duration = pulseIn(EchoPin, HIGH); //listen for echo

 

/*Convert micro seconds to Inches

-------------------------------------*/

 

inches = microsecondsToInches(duration);

cm = microsecondsToCentimeters(duration);

}

 

long microsecondsToInches(long microseconds) // converts time to a distance

{

return microseconds / 74 / 2;

}

long microsecondsToCentimeters(long microseconds) // converts time to a distance

{

return microseconds / 29 / 2;

}

 

void LookAhead() {

PingServo.write(90);// angle to look forward

delay(175); // wait 0.175 seconds

ping();

}

 

void LookAround(){

PingServo.write(180); // 180° angle

delay(320); // wait 0.32 seconds

ping();

rightDist = inches; //get the right distance

PingServo.write(0); // look to the other side

delay(620); // wait 0.62 seconds

ping();

leftDist = inches; // get the left distance

PingServo.write(90); // 90° angle

delay(275); // wait 0.275 seconds

 

// Prints a line in the serial monitor

Serial.print("RightDist: ");

Serial.println(rightDist);

Serial.print("LeftDist: ");

Serial.println(leftDist);

Serial.print("CenterDist: ");

Serial.println(centerDist);

}

  • Sign in to reply
  • Cancel
  • Former Member
    0 Former Member over 12 years ago

    This is a really cool idea! I've always wanted to create one of these but have never really had the time or resources. Keep the community posted on your progress!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • billabott
    0 billabott over 12 years ago

    If memory serves, Ardiono needs to create a Input Trigger Pulse "tOUT" between 2 µs (minimum) and 5 µs (typical) on a digital pin connected to the data line of the PING))).   A 1000 ohm resister is often used in series on that connection.  Measure the width of the return pulse, and finally calculate a distance to the nearest object that reflected the ultrasonic 'chirp'.  The effective range for measurements is 2 cm to 3 m (0.8 in to 3.3 yd).  PING))) clones may have  other operational parameters.    Source.


    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • billabott
    0 billabott over 12 years ago

    You have placed a redundant

    unsigned long ping();

    in the middle of that same subprogram.

     

    Now would be a good time to remove it.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 12 years ago in reply to billabott

    Thank you so much for the reply. I really appreciate it. I will recheck the code.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 12 years ago in reply to Former Member

    Yes I will. Thank you.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 12 years ago in reply to billabott

    I have revised the code and it has greatly improved. Only 1 small glitch that I hope we can fix soon. The ultrasonic sensor (SR04) for the Cliff Avoidance only reads when Ultrasonic Sensor (Parallax)  for the Obstacle Avoidance senses a distance below the set parameter (15 inches). The code works great as an Obstacle Avoidance code but is not simultaneously reading the sensor for the Cliff Avoidance so if there is a hole in front of the robot, the robot will just roll into the hole.

     

    I will attache the code. The code needs to read the 2 sensors simultaneously so if an obstacle or a hole is in the path of the robot, Arduino can react. I'm thinking of using the "else if" command so Arduino will read the sensors simultaneously. If anyone has any suggestions on how to revise the code so Arduino is reading both sensors simultaneously, feel free to post a reply. Thank you again in advance for the assistance.  

     

    #include <AFMotor.h> // Enables the Motor library

    #include <Servo.h> // Enables the Servo library

     

     

    Servo PingServo;

    AF_DCMotor motor1(1); // Motor 1 is connected to the port 1 on the motor shield

    AF_DCMotor motor2(2); // Motor 2 is connected to the port 2 on the motor shield

    int pingPin = A5; // Parallax Ping sensor is connected to port A5

    int TrigPinA = A1; // SR04 Trig Sensor connected to A1

    int EchoPinA = A3; // SR04 Echo Sensoe connected to A3

    int centerDist, leftDist, rightDist, backDist; // Define variables center, left, right and back distance

    long durationA, durationB, inchesA, inchesB, cm; // Define variables for Ping sensor

     

     

    void setup() {

    PingServo.attach(10); // Servo is attached to pin 10 in the motor shield

    PingServo.write(90); // Center the Ping sensor (puts it at 90 degrees)

    motor1.setSpeed(250); // Sets the speed of the first motor

    motor2.setSpeed(250); // Sets the speed of the second motor

     

    Serial.begin(9600); // Enables Serial monitor for debugging purposes

    Serial.println("Serial test!"); // Test the Serial communication

    }

    unsigned long ping() {

    pinMode(pingPin, OUTPUT); // Make the Pingpin to output

    digitalWrite(pingPin, LOW); //Send a low pulse

    delayMicroseconds(2); // wait for two microseconds

    digitalWrite(pingPin, HIGH); // Send a high pulse

    delayMicroseconds(5); // wait for 5 micro seconds

    digitalWrite(pingPin, LOW); // send a low pulse

    pinMode(pingPin,INPUT); // switch the Pingpin to input

    durationB = pulseIn(pingPin, HIGH); //listen for echo

    inchesB= microsecondsToInches (durationB);

     

    pinMode(TrigPinA, OUTPUT); // Make the Pingpin to output

    digitalWrite(TrigPinA, LOW); //Send a low pulse

    delayMicroseconds(2); // wait for two microseconds

    digitalWrite(TrigPinA, HIGH); // Send a high pulse

    delayMicroseconds(5); // wait for 5 micro seconds

    digitalWrite(TrigPinA, LOW); // send a low pulse

    pinMode(EchoPinA,INPUT); // switch the Pingpin to input

    durationA = pulseIn(EchoPinA, HIGH); //listen for echo

    inchesA= microsecondsToInches (durationA);

     

    /*Convert micro seconds to Inches

    -------------------------------------*/

    inchesB = microsecondsToInches(durationB);

    cm = microsecondsToCentimeters(durationB);

    inchesA = microsecondsToInches(durationA);

    cm = microsecondsToCentimeters(durationA);

    }

     

    long microsecondsToInches(long microseconds) // converts time to a distance

    {

    return microseconds / 74 / 2;

    }

    long microsecondsToCentimeters(long microseconds) // converts time to a distance

    {

    return microseconds / 29 / 2;

    }

     

    void LookAhead() {

    PingServo.write(90);// angle to look forward

    delay(175); // wait 0.175 seconds

    ping();

    }

     

    void LookAround(){

    PingServo.write(180); // 180° angle

    delay(320); // wait 0.32 seconds

    ping();

    rightDist = inchesB; //get the right distance

    PingServo.write(0); // look to the other side

    delay(620); // wait 0.62 seconds

    ping();

    leftDist = inchesB; // get the left distance

    PingServo.write(90); // 90° angle

    delay(275); // wait 0.275 seconds

    }

    void AllStop() {

    motor1.run(RELEASE); // Turns off motor 1

    motor2.run(RELEASE); // Turns off motor 2

    }

    void AllForward() { // Makes the robot go forward

    motor1.run(FORWARD); // Motor 1 goes forward

    motor2.run(FORWARD); // Motor 2 goes forward

    Serial.println("Going forward"); // Prints a line in the serial monitor

    }

    void turnRight() { // Makes the robot go right

    motor2.run(BACKWARD); // Turns off motor 2

    motor1.run(FORWARD); // Motor 1 goes forward

    delay(800); // Time required to turn right (0.8 seconds)

    Serial.println("Motors going Right"); // Prints a line in the serial monitor

    }

    void GoBack(){ // Makes the robot go back

    motor2.run(BACKWARD); // Motor 2 goes back

    motor1.run(BACKWARD); // Motor 1 goes back

    delay(1600); // Time Required to go back (1.6 seconds)

    Serial.println("Backward"); // Prints a line in the serial monitor

    }

    void turnLeft() { // Makes the robot go Left

    motor2.run(FORWARD); // Motor 2 goes forward

    motor1.run(BACKWARD); // turns off motor 1

    delay(800); //Time Required to turn left (0.8)Seconds

    Serial.println("Motors going Left");// Prints a line in the serial monitor

    }

     

    // Starts the loop to decide what to do

    void loop()

    {

    LookAhead();

    Serial.print(inchesB);

    Serial.println(" inchesB"); // Prints a line in the serial monitor

    if(inchesB >= 15) /* If the inches in front of an object is

    greater than or equal to the minimum safe distance (15 inches), react*/

    {

    AllForward(); // All wheels forward

    delay(110); // Wait 0.11 seconds

    }else // If not:

     

    {

    AllStop(); // Stop all motors

    LookAround(); // Check your surroundings for best route

    if(rightDist > leftDist) // If the right distance is greater than the left distance , turn right

    {

    turnRight();

    }else if (leftDist > rightDist) // If the left distance is greater than the right distance , turn left

    {

    turnLeft();

    }else if (leftDist&&rightDist<inchesB) // If the left and right distance is smaller than the min

    //safe obstacle distance (15 inch) go back

    {

    GoBack();

    }

    if(inchesA <= 3) /* If the inches below the ground distance sensor  is less than or equal (3 inches), so the robot can detect if its about to roll into a hole, react*/

    {

    AllForward(); // All wheels forward

    delay(110); // Wait 0.11 seconds

    }

    else // If not:

    {

    AllStop(); // Stop all motors

    delay(1000);

    GoBack();

    delay(1000);

    turnRight();

    }

    {

    // Prints a line in the serial monitor

    Serial.print("RightDist: ");

    Serial.println(rightDist);

    Serial.print("LeftDist: ");

    Serial.println(leftDist);

    Serial.print("CenterDist: ");

    Serial.println(centerDist);

    Serial.print(inchesA);

    Serial.println(" inchesA"); // Prints a line in the serial monitor

    }

    }

    }

     

    Just a note: Im using a L293D Motor Drive Expansion Shield for this project.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • billabott
    0 billabott over 12 years ago in reply to Former Member

    One solution you might like is to read both sensors, then process the inputs, and select proper response mode.  It should be possible to read the two sensors many 10s of time per second.  

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 12 years ago in reply to billabott

    Thank you much . I will look into it.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 9 years ago

    Kindly help me i am using just sr04 sensor. can you please upload the code for onlor can y 1 sensor? and kindly shear your circuit picture.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • clem57
    0 clem57 over 9 years ago in reply to Former Member

    Here it is Let me google that for you

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube