Obstacle Detection Using INFRARED
The variables are set up next, using the “var” directive.
The first two LSENS and RSENS don’t actually reserve RAM
space — similar to typical variables. These two are more
descriptive setups for inputs. If the program wants to test the
state of an input pin, the P# format won’t work because it is
used for outputs.
The compiler wants to see an IN# format to describe an
input pin number. Since I wanted my program to be more
descriptive than “If IN0 = 1 then,” I had to create a substitute
name for IN0. This requires using a “var” directive rather than
the “con” directive.
After the inputs are set up, the program creates a word
variable for storing the 10-bit A/D value reading from the
GP2D12 sensor. The program calls this “val.” Then, a general
purpose byte variable “x” is defined.
‘ Left IRD sensor
‘ Right IRD sensor
‘ Table conversion result
‘ General purpose variable
The RoboBoard needs some initialization before jumping
into the main loop.
The next section does this. First the “setpullups pu_on”
command is issued, as described earlier. Following the pull-up
setup is the initialization of the LEDs to off. A simple “low”
command to each LED label (defined in the constants
section) initializes the LEDs to off.
This is due to the fact that one side of the LEDs is
grounded and the other side is tied to the RoboBoard’s I/O
through a resistor. After this, we can jump to the main
‘ Initialization ]
‘ PortB pull-up resistors on
‘ All LEDs off to start
The main loop is where all the fun stuff occurs. The
first step is to read the analog detector with the “adin”
adin ax0,3,AD_RON, val
22882 Orchard Lake Rd.
Farmington Hills, MI 48336
Commerce, MI 48382
56 SERVO 07.2004
This command handles the A/D register setup and stores
the result in the variable at the end of the command, in this
case “val.” The Atom command handles all the internal PIC
stuff, so all your program has to do is create the “word” size
variable to store the result. Easy, huh?
The next section of code in the main loop makes a series
of decisions using the “if-then-elseif-endif” command:
if val < 450 and lsens = 0 and rsens = 0 then
First, all the detectors are checked for obstacles. The A/D
value of 450 was experimentally found to represent an object
close enough in front of the robot to cause a reaction, but
not so close as to cause it to react too quickly. A smaller
number makes the robot react to objects further away, but
the sensor accuracy is not guaranteed beyond an A/D value
of about 550.
If an A/D reading of less than 450 is detected, then
the program ignores it and considers it not to be an
obstacle. The digital detectors only require the “if-then”
command to look for a 0 (no obstacle detected). If no
obstacle is detected, the program jumps to the “move” label
to move forward.
The program doesn’t really use all possible information
from the analog sensor. It could, for example, react
differently, depending on how close the object is. You can
see how the analog sensor does offer more sensitivity
control in your program than the digital versions do. I’ll
leave that to your adaptation of this program on your
elseif val > 450
elseif lsens = 1
elseif rsens = 1
If an obstacle was detected, then the program has to
determine where the obstacle is. The remaining “elseif“
statements test each detector individually to find that out.
If the obstacle is in front, the program jumps to the “rev”
label. If the obstacle is to the left, then the “lft” label is
If the obstacle is to the right, the label “rht” is jumped
to. If more than one sensor detects the obstacle, only the
first one is reacted to. The way these are listed, front has
priority, followed by left, then right.
The remaining routines are all the robotic drive control.
Each labeled group of commands drives the robot in a
First, they set the LEDs to a specific state so you can
debug the robot if it is not reacting correctly to what it
thought it detected. You can actually leave off the LEDs, but