Project 3: Detecting Obstacles

Introduction

Have you ever wondered how a robot can see? There are many different methods but the method discussed here is sonar. Sonar, which is short for SOund Navigation And Ranging, has many real life applications. Submarines use sonar to see under water, modern cars use sonar sensors to help you park, bats and dolphins and many other animals have there own natural sonar to navigate and hunt in the dark.

IdeaBot's sonar attachment will enable you to program IdeaBot to avoid obstacles, track and chase moving objects, solve mazes and many many other things.

Search and Follow algorithm, simple approach using ideaBot and we challenge you to do it at the end. IdeaBot with sonar holder extension

Theory

A sonar or ultrasonic sensor works by sending out a sound pulse and listening for an echo. The frequency of the sounds used is much higher than a human can hear, which is why sonar sensors are sometimes called ultrasonic sensors. The speed of sound is known, so if one knows the time from the sound pulse being emitted until an echo is detected the distance can be easily calculated Theory of operation of ultrasonic sensors

As you can see, in the above picture, the sound is emitted then reflected back. The timer counts the total time of travel of both ways so we need to divide by 2 to calculate the distance between the object and the sonar. The following distance formula is used:

Distance = Time * speed of sound / 2

the speed of sound equals 340 m/s or 0.034 cm/us , for arduino programming we need it to be in centimeters per microsecond.

IdeaBot has an HC-SR04 ultrasonic sensor included with it, which is a 4 pin sensor, for more details on this sensor and sonar sensors in general, check out our dedicated sonar sensor tutorial here. Sonar Sensor HC-SR04

The pins of the sensor, from left to right from the above picture, are the following:

•  Vcc is the 5V power pin.
• Trig pin, short for trigger, is used to send a sound pulse by setting the trig pin high, generally for a very short period of time, on the order of 10 microseconds.
• The Echo pin is used to listen for the sound wave that bounces back.
• GND is the ground pin and should be connected to the common ground.

Assembly

Before you can unlock any of the things benefits of sonar, you must first assembly the sonar attachment, watch the assembly video or follow the detailed step by step instructions below.

IdeaBot sonar attachment assembly video. 1: Locate the front panel on the robot.

Connection to Shield StartUP shield sonar and servo connections

Sonar sensor connections are quite easy and straight forward. Using the 4 wire female-female jumper provided, connect the sensor directly to the shield and make sure you connect the Vcc to the +5v pin and Gnd to Gnd, not the opposite.

Code

In this code there are two main functions to be introduced which are the following:

delayMicroseconds(number);

this function is a normal delay function but it is in microseconds instead of milliseconds, because we need the delay to be fast between each read and write command of the sonar sensor to be fast enough to catch the reflected sound wave.

Float name;

A Float is a new variable type that reserve a place in memory for a number called "name". A Float number has decimal values and does not have to be a whole number; so you can store a number like 3.141.

The code to read distance in cm and display it on the serial monitor is shown below, and explained through out the comments.

 int echo = 13;    // define pin 13 as the echo pinint trig = 12;      // define pin 12 as the trigger pinfloat dis;           // define variable for distance int t;void setup() {  Serial.begin(9600);      // to display data  pinMode(echo,INPUT);     // echo is set to input so it can listen  pinMode(trig,OUTPUT);    // trig set to ouput to send pulses }void loop() { // put your main code here, to run repeatedly:  // send pulse for 10 microseconds  digitalWrite(trig,HIGH);      //send pulse by setting trig pin to +5v  delayMicroseconds(10);   //wait for that pulse 10 microseconds  digitalWrite(trig,LOW);     //stop sending   // listens for response  t = pulseIn(echo,HIGH);    // time from pulse sent to echo heard in microseconds   t = t/2;                   // time to reach object (half the total time)  dis = .034*t;         // distance = speed of sound ( centimeters/microseconds) * time  Serial.println(dis,2);   // display distance on serial monitor   }

The function pulseIn(echo,HIGH) measures "How long is the echo signal on HIGH voltage?" and returns the time. What happens, in the sensor, is that the echo pin stays HIGH after it sends the sonar wave. Once the wave comes back to the sensor, after bouncing of an object, it sets the echo pin to low. So if we measure how long the echo pin has been on HIGH state, we can tell how long the wave took to travel.

Results of the code: After uploading code, open serial monitor then you will see the readings, put an object and check measurements.

Return Function

Now if you want to make things easy you use functions approach, but at the same time to make complex tasks you need to break things down into functions. We have explained functions concept in a previous tutorial. But here we will introduce a new way of using the functions.

It is called a Return Function where it returns the results by the end of executing the function, so you can store the results in any type of variable and use it. For example it might be  sensor readings, the code is explained below:

float dis;    //define the variable to be returned

// your code can be written in the function

return dis;
}

So what we can do now is the following

x = read(); // use this in the main code void loop, and x will have the returned value of the function read();

and x is a float value, instead of writing the total function to read the distance you can use the function approach. a practical example of the code is mentioned below.

The code above can be put in a compact function as follows, and it is explained below:

 int echo = 13;    // define pin 13 as the echo pinint trig = 12;      // define pin 12 as the trigger pinfloat dis;           // define variable for distance void setup() {    Serial.begin(9600);      // to display data  pinMode(echo,INPUT);     // echo is set to input so it can listen  pinMode(trig,OUTPUT);    // trig set to ouput to send pulses }void loop() {dis = read();Serial.println(dis);}float read()    // function to read sonar and return distance {float distance;  int t;// send pulse for 10 microseconds   digitalWrite(trig,HIGH);        delayMicroseconds(10);  digitalWrite(trig,LOW);  // listens for response   t = pulseIn(echo,HIGH);    // time from pulse sent to echo heard in microseconds   t = t/2;                   // time to reach object (half the total time)  distance = .034*t;         // distance = speed of sound ( centimeters/microseconds) * time  return distance;}

Let us now combine these concepts to write a simple code to keep IdeaBot a constant distance away from an object.

keep constant distance

Now to make the robot interact with the environment and the obstacles surrounding it, let us get use of the sonar sensor and let it help ideaBot decide how to move, when to stop and to avoid obstacles.

The following code uses if else statements depending on the readings of the sonar sensor to move the servo motors and you can choose your own way of controlling the motors like turning left or right.
If  the servo motors are not calibrated don't forget to do so, check project 1. The code to do this is shown below:

 #include Servo right;  Servo left;int echo = 13;int trig = 12;float dis;int track = 30;     // follow object at this distance(cm)void setup() {  right.attach(9);        left.attach(11);   pinMode(echo,INPUT);  pinMode(trig,OUTPUT);}void loop() {  // put your main code here, to run repeatedly:  dis = read();   // measure distance     if( dis < 29.5)    // if distance less than 29.5 move forward   {    right.write(0);    left.write(180);  }  else if(dis > 30.5) // if distance greater than 30.5 move backwards  {    right.write(180);    left.write(0);  }  else               // if within range, stop  {    right.write(90);    left.write(90);  }   delay(5);   // delay 5 milliseconds for loop stability}float read()    // function to return distance{ float distance; int t; // send pulse for 10 microseconds   digitalWrite(trig,HIGH);        delayMicroseconds(10);  digitalWrite(trig,LOW);  // listens for response   t = pulseIn(echo,HIGH);    // time from pulse sent to echo heard in microseconds   t = t/2;                   // time to reach object (half the total time)  distance = .034*t;         // distance = speed of sound ( centimeters/microseconds) * time  return distance;}

The Challenge

Program IdeaBot to chase an object like the video you saw at the beginning, send a copy of your code and a video of IdeaBot in action to store@idealink.net and we may publish it on our website.

We ship to the GCC and MENA regions.

Reliable and fast shipping to your door, quality assured.