Difference between revisions of "Tutorials/Arduino Projects/Mobile Robotics/BoeBot/Use Ultrasonic Sensor To Measure Distance"

From ROBOTC API Guide
Jump to: navigation, search
(Wiring the LEDs)
(Overview)
Line 4: Line 4:
 
{{tut-video||BoeBot measuring distance to an object using a PING sensor}}
 
{{tut-video||BoeBot measuring distance to an object using a PING sensor}}
 
== Overview ==
 
== Overview ==
For sensors that return a range of values, we usually just want to check if the returned value is more than, equal to, or less than a predetermined value (called a 'threshold'). For example let's assume we want to keep a robot with a PING sensor at least 5 inches away from any objects. In a situation such as this we would only want to change the behavior of the robot when it senses something that is less that or equal to 7 in (the 5 in minimum plus a 2 in factor of safety).
+
For sensors that return a range of values, we usually just want to check if the returned value is greater than, equal to, or less than a predetermined value (called a 'threshold'). For example let's assume we want to keep a robot with a PING sensor at least 5 inches away from any objects. In a situation such as this we would only want to change the behavior of the robot when it senses something that is less that or equal to 7 in (the 5 in minimum plus a 2 in factor of safety).
  
 
To help demonstrate this principal, we are going to program the robot to display the 3 possible states through two LEDs.
 
To help demonstrate this principal, we are going to program the robot to display the 3 possible states through two LEDs.

Revision as of 21:04, 15 October 2012

ArduinoArduino Tutorials and Guided ProjectsParallax BoeBot + Arduino Shield, Mobile Robotics Platform → How to measure distance with the Parallax PING sensor

Notepad.gif NOTE: This is a place holder for a video.
Please add the id for the YouTube video with description "BoeBot measuring distance to an object using a PING sensor"

Overview

For sensors that return a range of values, we usually just want to check if the returned value is greater than, equal to, or less than a predetermined value (called a 'threshold'). For example let's assume we want to keep a robot with a PING sensor at least 5 inches away from any objects. In a situation such as this we would only want to change the behavior of the robot when it senses something that is less that or equal to 7 in (the 5 in minimum plus a 2 in factor of safety).

To help demonstrate this principal, we are going to program the robot to display the 3 possible states through two LEDs.

Measurement LED 1 LED 2
> threshold ON OFF
= threshold ON ON
< threshold OFF ON

Wiring the LEDs

To wire up an LED we need a 470Ω resistor and the LED. Since we need want to wire 2 LEDs, we will need 2 LEDs and 2 470Ω resistors. We will plug LED 1 into pin 5, and LED 2 into pin 6.

virtual breadboard
breadboard photo

Programming

Configuring the pins

First we need to tell ROBOTC that we have a Parallax Boe Shield connected. Then wee need to tell ROBOTC about the following connections

  • LED to Vcc on digital pin 5, named "led1"
  • LED to Vcc on digital pin 6, named "led2"
  • SONAR [Ping] (inch) on digital pin 3, named "ping"

Once that has been done you should have the following in your source code file

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl3,  ping,           sensorSONAR_Ping_inch)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
#pragma config(Sensor, dgtl6,  led2,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

Reading the Sensor

Before we can move on we need to know how to read the value of the sensor. Just like with the switch sensors and the LEDs before, you use SensorValue[] to read the value. In this case it will be used as shown bellow.

SensorValue[ping];

Greater Than? Less Than?

So we know how to get the reading from the sensor, but how do we check if it is greater or less than the threshold? If we go back to the section about dimming the LEDs, you will find that we used "<" to run the loop 10 times. This operator (the less than operator) can be used on any value. this operator is part of a larger set of operators called comparators, which can all be used to compare values.

Operator name description syntax example
"==" Equal to returns true if the value to the left of the operator is equal to the value to the right of the operator. 1 == 1
">" Greater Than returns true if the value to the left of the operator is greater than the value to the right of the operator. 5 > 4
">=" Greater Than or Equal to returns true if the value to the left of the operator is greater than or equal to the value to the right of the operator. 5 >= 5
"<" Less Than returns true if the value to the left of the operator is less than the value to the right of the operator. 3 < 4
"<=" or "=<" Less Than or Equal to returns true if the value to the left of the operator is greater than the value to the right of the operator. 4 <= 4

Writing the code

So now that we know how to read the sensor value and compare it to our threshold, we can finally start to write the code. First lets look at how we will tell the LEDs to light up depending on the measured value.

Since we have more than 2 possible conditions, we would need to nest multiple if-else statements inside of each other. Fortunately, It ispossible to use something called an else-if statement to stay in one level. The else-if statements function the same as if you were to put the condition inside of an if statement that is nessted in the else code block of an if-else statement.

if (5 == 10) {
  //the 10 must be of a different base
} else {
  if (1 == 1) {
    //everything is good
  } else {
    //something strange is happening
  }
}
is equal to
if (5 == 10) {
  //the 10 must be of a different base
} else if (1 == 1) {
  //everything is good
} else {
  //something strange is happening
}

First let's create the code to decide what to run. Since we have 3 solid states, we need 3 if statements (can be of the else-if form). Using else-if statements to make the code a little cleaner, we end up with the following.

if (SensorValue[ping] > threshold) {
  //led1 on and led2 off
} else if (SensorValue[ping] == threshold) {
  //both leds on
} else if (SensorValue[ping] < threshold) {
  //led1 off and led2 on
} else {
  //something happened
  //we don't know what to do so
  //let's just turn off the leds
}

Now that we have the decision code done, we need to add the action code. So now we just need to add the code to turn on and off the leds.

if (SensorValue[ping] > threshold) {
  //led1 on and led2 off
  SensorValue[led1] = 1;
  SensorValue[led2] = 0;
} else if (SensorValue[ping] == threshold) {
  //both leds on
  SensorValue[led1] = 1;
  SensorValue[led2] = 1;
} else if (SensorValue[ping] < 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;
}

If we place this as is, in to a task main and run it, it would only last for a fraction of a second. Since we want to be able to see the changes, we need to place it in a endless while loop.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl3,  ping,           sensorSONAR_Ping_inch)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
#pragma config(Sensor, dgtl6,  led2,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
 
task main()
{
  while (true)
  {
    if (SensorValue[ping] > threshold) {
      //led1 on and led2 off
      SensorValue[led1] = 1;
      SensorValue[led2] = 0;
    } else if (SensorValue[ping] == threshold) {
      //both leds on
      SensorValue[led1] = 1;
      SensorValue[led2] = 1;
    } else if (SensorValue[ping] < 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 know that the threshold that we are looking for is 7 inches, and the sensor is configured for inches, we can just replace "threshold" with 7.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl3,  ping,           sensorSONAR_Ping_inch)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
#pragma config(Sensor, dgtl6,  led2,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
 
task main()
{
  while (true)
  {
    if (SensorValue[ping] > 7) {
      //led1 on and led2 off
      SensorValue[led1] = 1;
      SensorValue[led2] = 0;
    } else if (SensorValue[ping] == 7) {
      //both leds on
      SensorValue[led1] = 1;
      SensorValue[led2] = 1;
    } else if (SensorValue[ping] < 7) {
      //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;
    }
  }
}