Using an IR sensor to detect objects

From ROBOTC API Guide
< Tutorials‎ | Arduino Projects/Mobile Robotics/BoeBot
Revision as of 17:11, 16 October 2012 by Jwatson (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Configuration

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

  • Parallax Boe Shield
  • servo_10 as a continuous rotation servo named "leftServo"
  • servo_11 as a reversed continuous rotation servo named "rightServo"
  • sound (under the motor tab) as an audio speaker named "irLeds"
  • digital pin 7 as a digital input named "rightIR"
  • digital pin 8 as a digital input named "leftIR"
#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(Sensor, dgtl7,  rightIR,        sensorDigitalIn)
#pragma config(Sensor, dgtl8,  leftIR,         sensorDigitalIn)
#pragma config(Motor,  servo_9,          ,             tmotorAudio, openLoop, IOPins, None, None)
#pragma config(Motor,  servo_10,        leftServo,     tmotorServoContinuousRotation, openLoop, IOPins, dgtl10, None)
#pragma config(Motor,  motor_11,        rightServo,    tmotorServoContinuousRotation, openLoop, reversed, IOPins, dgtl11, None)

Reading the Sensors

First off, the IR detectors only respond to IR light that is flashing at 38kHz. For this reason we have the IR LEDs connected to the sound pin so that we can turn them on and off at 38kHz. To flash them at this speed we tell ROBOTC to use the hardware on that pin to turn the pin on and off, without user intervention, at what ever speed we want, which in this case is 38kHz. To do this we use the insert command here to set the "tone" out for the IR LEDs

Notepad.gif NOTE: ROBOTC is currently unable to make the IR LEDs flash at 38kHz. As such this section is on hold.

Notepad.gif TODO: insert link to the page that defines the above function.

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

  • returns 0 when it detects IR light
  • returns 1 when it does not detect IR light

Make Sensor Readings easier

To make the sensor readings easier, we can create a function that starts the IR LEDs flashing and then reads the IR detector and returns the result.

int getIrReading(tSensors irReceiverPin)
{
  // IRLED 38 kHz for at least 2 ms
  wait1Msec(1);                              // Wait 1 ms
  int ir = SensorValue[irReceiverPin];      // IR receiver -> ir variable
  wait1Msec(1);                              // Down time before recheck
  return ir; 
}

You will notice that we are passing a variable of type "tSensors" to the function. This is the variable type used to refer to a sensor pin. This allows us to specify what pin to read for the IR detector.

Making the Program

To demonstrate how to use the sensor, we are going to make the robot drive forward and look for obstacles. If it finds on, it will turn then continue driving forward. If you are thinking that this sound familiar, that is because we made a similar program using the Parallax PING sensor. So like any good programmer, we are going to copy the program using the PING sensor and modify it to use the IR sensors.

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

First lets add the function for reading the IR Sesnors. Then we can replace the ping sensor value calls with calls to the function for both the left and the right sensors. Once we do that we should end up with something like the following.

insert config code.
 
int getIrReading(tSensors irReceiverPin)
{
  // IRLED 38 kHz for at least 2 ms
  wait1Msec(1);                              // Wait 1 ms
  int ir = SensorValue[irReceiverPin];      // IR receiver -> ir variable
  wait1Msec(1);                              // Down time before recheck
  return ir; 
}
 
task main()
{
  while (true)
  {
    if (getIrReading(leftIR) == 0 || getIrReading(rightIR) == 0) {
      //there is something within the threshold range
      motor[leftServo] = -15;
      motor[rightServo] = 15;
      wait1Msec(400);
    } else {
      //nothing in the threshold range
      motor[leftServo] = 15;
      motor[rightServo] = 15;
    }
  }
}