Using an ultrasonic sensor to detect and avoid walls

From ROBOTC API Guide
Jump to: navigation, search
ArduinoArduino Tutorials and Guided ProjectsVEX + Arduino, Mobile Robotics Platform → Using an ultrasonic sensor to detect and avoid walls

How it Works

We have already done wall and obstacle detection using switches (the whiskers). However, this can be problematic if you need to detect the obstacle at a distance. Also, it's annoying (and rather ironic) for the robot to have to bump into the wall it is trying to avoid. This is where the ultrasonic sensor comes into play.

We already know that the ultrasonic Sensor can be used to detect objects and measure the distance to them. So, by using an ultrasonic sensor and looking for objects that are less than some set distance, we can program the robot to avoid them at just about any distance.

The ultrasonic sensor can detect obstacles at a distance, without needing to contact them.

Configuration

The robot will need to have:

  • A VEX motor on pin 10, named "rightServo" (reversed)
  • A VEX motor on pin 11, named "leftServo"
  • A VEX Ultrasonic rangefinder on pins 7 and 8, named "ultrasonic"

Once configured, you should have the following code at the top of your program file.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl7,  ultrasonic,     sensorSONAR_TwoPins_inch)
#pragma config(Motor,  servo_10,        rightServo,    tmotorServoContinuousRotation, openLoop, reversed, IOPins, dgtl10, None)
#pragma config(Motor,  motor_11,        leftServo,     tmotorServoContinuousRotation, openLoop, IOPins, dgtl11, None)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

Programming

We already have some code that monitors the distance to an object using the ultrasonic sensor, so let's modify that code to control how the robot drives.

task main()
{
  while (true)
  {
    //Make sure the value is not an error.
    if (SensorValue[ultrasonic] > 0)
    {
      if (SensorValue[ultrasonic] > threshold) {
        //led1 on and led2 off
        SensorValue[led1] = 1;
        SensorValue[led2] = 0;
      } else if (SensorValue[ultrasonic] == threshold) {
        //both leds on
        SensorValue[led1] = 1;
        SensorValue[led2] = 1;
      } else if (SensorValue[ultrasonic] < threshold) {
        //led1 off and led2 on
        SensorValue[led1] = 0;
        SensorValue[led2] = 1;
      } else {
        //something happened
        //we don't know what to do so
        //let's just turn off the leds
        SensorValue[led1] = 0;
        SensorValue[led2] = 0;
      }
    }
  }
}

Since we only care about when there is an object that is less than or equal to the distance threshold, we can change the first if statement to be <= instead of >. We can also remove the else-if statements.

task main()
{
  while (true)
  {
   //Make sure the value is not an error.
    if(SensorValue[ultrasonic] > 0)
    {
      if (SensorValue[ultrasonic] <= 7) {
        //there is something within the threshold range
      } else {
        //nothing in the threshold range
      }
    }
  }
}

Now that we have the logic done, we need to add the actions. When there is no object detected, we want to just drive forward at power level 50. When we detect an obstacle, we need to turn some amount, then resume driving and looking for obstacles.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl7,  ultrasonic,     sensorSONAR_TwoPins_inch)
#pragma config(Motor,  servo_10,        rightServo,    tmotorServoContinuousRotation, openLoop, reversed, IOPins, dgtl10, None)
#pragma config(Motor,  motor_11,        leftServo,     tmotorServoContinuousRotation, openLoop, IOPins, dgtl11, None)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
  while (true)
  {
    //Make sure the value is not an error
    if(SensorValue[ultrasonic] > 0)
    {
      if (SensorValue[ultrasonic] <= 7) {
        //there is something within the threshold range
        motor[leftServo] = -50;
        motor[rightServo] = 50;
        wait1Msec(800);
        } else {
        //nothing in the threshold range
        motor[leftServo] = 50;
        motor[rightServo] = 50;
      }
    }
  }
}