Using the Sharp IR Sensor to Detect the Distance to Objects and Avoid Them

From ROBOTC API Guide
Jump to: navigation, search
ArduinoArduino Tutorials and Guided ProjectsLego + Arduino, Mobile Robotics Platform → Using the Sharp IR Sensor to detect objects and their distance

Contents

Using the IR sensor to detect and avoid walls


Configuration

Now that we know how the sensor works and have it wired, it is time to program it in ROBOTC. But first we need to tell ROBOTC how the robot is configured:

  • DFRobot Motor Shield
  • Motor_5 as a reversed Internal H.Bridge named "rightServo"
  • Motor_6 as a reversed Internal H.Bridge named "leftServo"
  • Analog pin 2 as an analog input named "sharpIR"


#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldDFRobotMotor)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, anlg2,  sharpIR,        sensorAnalog)
#pragma config(Motor,  motor_5,         rightServo,    tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4)
#pragma config(Motor,  motor_6,         leftServo,     tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

Reading the Sensors

To get the reading from the detector you use SensorValue[] just like with any other sensor.

The readings tend to be higher as the sensor approaches an object, and lower as it moves farther away. Note however that there is a value drop off right as the sensor gets close to contact with the object. This is an important flaw in the sensor that should be kept in mind during programming.

The pickup pattern of the Sharp IR sensor (graph courtesy of Sparkfun.com)

As you can see here, the values max out between 2-3" and then rapidly drop as the sensor comes into contact with the object.

Here is a sample of recorded values (approximate) for the sensor at various distances

Distance (in mm) Distance (in In.) Value
0 0" 172
25 1" 245
50 2" 376
75 3" 520
100 4" 500
150 6" 333
200 8" 265
250 10" 217
300 12" 179
>400 >12" 172

It's also very important to note that if the Sharp IR sensor is at an angle to an obstacle, it will read a value that is farther away than it actually is, since the laser is going farther than the shortest distance from the sensor to the object's side.

Making the Program

We will be modifying an existing program to use the Sharp IR sensor, starting with the code for avoiding obstacles using the Lego Ultrasonic sensor.

task main()
{
  while (true)
  {
    if (SensorValue[ping] <= threshold)
    {
      //there is something within the threshold range
      motor[leftServo] = -90
      motor[rightServo] = 90;
      wait1Msec(400);
    } 
    else 
    {
      //nothing in the threshold range
      motor[leftServo] = 90;
      motor[rightServo] = 90;
    }
  }
}

Since the Sharp IR sensor also returns a range of values, all we really need to do is change any reference to the ultrasonic sensor to reference the Sharp IR sensor instead. We will also need to adjust the threshold.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldDFRobotMotor)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, anlg2,  sharpIR,        sensorAnalog)
#pragma config(Motor,  motor_5,         rightServo,    tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4)
#pragma config(Motor,  motor_6,         leftServo,     tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
 
  int threshold=300;//The value for the distance you want to keep from the wall. Values under 200 are not advised.
 
  while (true)
  {
    if (SensorValue[sharpIR] >= threshold) 
    {
      //there is something closer than the threshold value
      motor[leftServo] = -90;
      motor[rightServo] = 90;
      wait1Msec(400);
    } else {
      //nothing in the threshold range
      motor[leftServo] = 90;
      motor[rightServo] = 90;
    }
  }
}

As you see in the video, however, this program runs into problems sometimes because unlike the ultrasonic sensor which sends out sound in all directions, the IR sensor only shoots its IR beam straight ahead. So, when it gets at a very shallow angle to an object, the object interferes with its turning because the robot is practically touching it before the IR sensor picks it up. An easy fix for this is to add in a "back up" segment into the part of the if() statement that turns the robot. This way, the robot gets clear of the object and can turn freely.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldDFRobotMotor)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, anlg2,  sharpIR,        sensorAnalog)
#pragma config(Motor,  motor_5,         rightServo,    tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4)
#pragma config(Motor,  motor_6,         leftServo,     tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
 
  int threshold=300;
 
  while (true)
  {
    if (SensorValue[sharpIR] >= threshold) //The value for the distance you want to keep from the wall. Values under 200 are not advised.
    {
      //there is something closer than the threshold value
      //Back up
      motor[leftServo] = -100;
      motor[rightServo] = -100;
      wait1Msec(500);
      //turn out of the way
      motor[leftServo] = -100;
      motor[rightServo] = 100;
      wait1Msec(500);
    } else {
      //nothing in the threshold range
      // move forward
      motor[leftServo] = 100;
      motor[rightServo] = 100;
    }
  }
}

This second program works even better than the first, and has the robot quickly and easily turning to avoid obstacles.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox