|

|

Sonar &
Infrared Obstacle Avoidance
 |
 |
|

Back To Index
|
|
This project combines infrared & sonar navigation
together. The hardware.inc include file used in previous code examples &
experiments has been changed & saved with the new name XFILES.INC.
Several modifications have been made to the new include file specifically
for this application.
The SRF04 is a relatively power hungry
device, and consumes [30-50mA]. Since we're running on batteries, we'll use PortB.6
to control a 2N3904 NPN transistor configured as a low-side driver to
turn power on or off to the sonar range-finder. When the SRF04 isn't being
used we can extend battery life significantly by turning it off. |

Figure #1: SRF04 Connections
Trigger VAR PortA.2 ' PortA.2 = SRF04 trigger pin
Echo VAR PortA.3 ' PortA.3 = SRF04 echo pin
As shown above,
two lines in the new include file are used to set up an alias for pins that
will control the SRF04. PortA.2 is the Trigger pin, and PortA.3 is the Echo pin. Make these connections between the
SRF04 & PIC PortA I/O-pins.
PortB.6 will be
used to control a 2N3904 NPN transistor. A logic 1 on the base of the NPN
turns the transistor on. This connects ground from the NPN emitter to the
collector providing ground to the SRF04. A logic 0 on the base of the NPN
turns the transistor off, and removes the ground connection from the SRF04.
Without the ground connection the SRF04 is turned off.
The new include
file defines an alias for PortB.6 called SonaControl. When SonaControl
= 1 the SRF04 will be turned on. When SonaControl = 0 the SRF04 is turned
off to conserve battery power.
We setup constants
to use for both on & off logic states making everything much easier to read.
Active = on, InActive=off. When we call the Ping sub-routine the SRF04 is
activated on entry, and deactivated on exit.
Active CON 1 ' Logic to turn on sonar drive transistor
InActive CON 0 ' Logic to turn off sonar drive transistor
SonaControl VAR PortB.6 ' PortB.6 = Sonar power control pin Ping:
SonaControl=Active
Trigger=0 ' Pulsout = compliment of initial value
PULSOUT Trigger, 6 ' Output >10 uS trigger pulse
PULSIN Echo, 1, Width ' Measure distance to target
Distance = Width / 74 ' Convert to inches
SonaControl=InActive
RETURN
|
|

Figure #2: Infrared LED Drive Circuit |
|

Figure #3: Infrared Detector
Circuit |
|
Figures #2 & #3 above show the
connections for the infrared LED drive & detector circuits. These are the
same as previous experiments.
Notice how we've set up a loop
counter. After 6 complete loops moving forward and checking for obstacles in
our path with infrared, we check for objects with the SRF04 sonar
range-finder. During the time we're using the infrared components for
obstacle detection we keep the SRF04 powered down to conserve batteries.
Once Micro-Bot has detected an
obstacle with infrared or the sonar range-finder, program execution will
jump to several sub-routines to determine where the obstacle was, and which
sensor type [IR or Sonar] found it.
Once we reach one of the obstacle
avoidance sub-routines BackUp, TurnRight or TurnLeft, we'll keep checking
for the obstacle that caused us to get into the obstacle avoidance
sub-routine before exiting. This will cause continuous right turns, left
turns or backing up until Micro-Bot has cleared the obstacle. |
'****************************************************************
'* Name : IR_Sonar.BAS *
'* Author : Bruce Reynolds *
'* Notes : Micro-Bot Infrared + Sonar Navigation Example *
'****************************************************************
INCLUDE "XFILES.INC"
Begin:
FOR X=1 TO 4
PULSOUT Left_Servo,ForwardLeft
PULSOUT Right_Servo,ForwardRight
PAUSE 20
NEXT
Loops=Loops+1
IF Loops >=6 THEN SonarCheck
GOSUB Check_Left ' Check left for obstacles
GOSUB Check_Right ' Check right for obstacles
' Check IR results
IF (Left_IR=No) AND (Right_IR=No) THEN Begin ' If no contact skip further checking
IF (Left_IR=Yes) AND (Right_IR=Yes) THEN GoBack ' If contact on both sides then reverse
IF (Left_IR=Yes) AND (Right_IR=No) THEN TurnRight ' If contact on left then turn right
IF (Left_IR=No) AND (Right_IR=Yes) THEN TurnLeft ' If contact on right then turn left
GOTO Begin
SonarCheck: ' Check sonar
Loops=0 ' Reset loop counter
GOSUB Ping ' Take sonar reading
IF (Distance > 9) THEN Begin ' Exit if no object within 9"
BackUp:
FOR X=1 TO 20
PULSOUT Left_Servo,ReverseLeft ' Back up first
PULSOUT Right_Servo,ReverseRight
PAUSE 20
NEXT
FOR X=1 TO 10
PULSOUT Left_Servo,ReverseLeft ' Now turn left
PULSOUT Right_Servo,ForwardRight
PAUSE 20
NEXT
GOSUB Ping ' Take another sonar reading to see if we're clear after the turn
IF Distance <= 9 THEN BackUp ' Check again before exiting right BackUp sub
GOTO Begin
GoBack: ' Go backwards
FOR X=1 TO 4
PULSOUT Left_Servo,ReverseLeft
PULSOUT Right_Servo,ReverseRight
PAUSE 20
NEXT
GOTO Begin
TurnRight: ' Turn right until object is no longer in our path
FOR X=1 TO 4
PULSOUT Left_Servo,ForwardLeft
PULSOUT Right_Servo,ReverseRight
PAUSE 20
NEXT
GOSUB Check_Right ' Check for obstacle again before exiting right turn sub
IF Right_IR=Yes THEN TurnRight
GOTO Begin
TurnLeft: ' Turn left until object is no longer in our path
FOR X=1 TO 4
PULSOUT Left_Servo,ReverseLeft
PULSOUT Right_Servo,ForwardRight
PAUSE 20
NEXT
GOSUB Check_Left ' Check for obstacle again before exiting left turn sub
IF Left_IR=Yes THEN TurnLeft
GOTO Begin
END
|
|
The Include File: |
'****************************************************************
'* Name : XFILES.INC *
'* Notes : Hardware Setup For IR_SONAR.BAS *
'****************************************************************
@ DEVICE HS_OSC,MCLR_OFF,LVP_OFF,WDT_OFF,PROTECT_OFF
DEFINE OSC 20 ' We're using a 20MHz crystal
DEFINE NO_CLRWDT 1 ' Do not auto insert watchdog timer reset code
'** Turn 16F62x Comparators OFF **'
CMCON = 7 ' Comparators = OFF, PortA = digital I/O
VRCON = 0 ' Internal A/D Vref disabled
'** Define Constants **'
Led_On CON 0 ' Led_On = logic 0 which turns IR LED on
Led_Off CON 1 ' Led_Off = logic 1 which turns IR LED off
No CON 1 ' If IR Detector Output = 1, then No object detected
Yes CON 0 ' If IR Detector Output = 0, then Yes object detected
ForwardLeft CON 800 ' Make adjustments to these motor constants
ReverseLeft CON 600 ' if Micro-Bot tends to veer left or right when
ForwardRight CON 600 ' moving in a straight line to compensate for
ReverseRight CON 800 ' different batteries or servo motors
Active CON 1 ' Logic to turn on sonar drive transistor
InActive CON 0 ' Logic to turn off sonar drive transistor
TRUE CON 12 ' CCP1CON value for PWM ON
FALSE CON 0 ' CCP1CON value for PWM OFF
'** Setup PortB **'
' PortB.3 = PWM output
TRISB = %00000100 ' Set PortB TRIS register
PORTB = %00000011 ' LEDs off, Servo pins=0, Sonar off, PWM pin=0
Left_Led VAR PortB.0 ' PortB.0 = left IRLED output
Right_Led VAR PortB.1 ' PortB.1 = right IRLED output
IR_Detector VAR PortB.2 ' PortB.2 = IR detector input
Left_Servo VAR PortB.4 ' PortB.4 = left servo output
Right_Servo VAR PortB.5 ' PortB.5 = right servo output
SonaControl VAR PortB.6 ' PortB.6 = Sonar power control pin
'** Setup PortA **'
TRISA = %00001000 ' Set PortA TRIS register
PORTA = %00000000 ' Initialize PortA
Trigger VAR PortA.2 ' PortA.2 = Output for SRF04 trigger pin
Echo VAR PortA.3 ' PortA.3 = Input for SRF04 echo pin
Width VAR WORD ' Pulse width from SRF04
Distance VAR WORD ' Converted distance value
'** IR Flag Bit Variables **'
Left_IR VAR BIT ' Flag bit for left IR object detection
Left_IR = No ' Initialize to 1 [no object detected] on power-up
Right_IR VAR BIT ' Flag bit for right IR object detection
Right_IR = No ' Initialize to 1 [no object detected] on power-up
'** G.P. Working Variables **'
X VAR BYTE ' GP working variable
Loops VAR BYTE ' GP working variable
Loops = 0 ' Start with Loops variable clear
'** Setup For 40KHz PWM IRLED Drive **'
CCPR1L = 25 ' 63=50%, 25=20%, 94=75% PWM Duty-Cycle
PR2 = 124 ' Set PWM for approximately 40KHz
T2CON = 4 ' Timer2 ON + 1:1 prescale
CCP1CON = FALSE ' Start with hardware PWM = OFF
GOTO Begin ' Jump to beginning routine
Check_Left: ' Call here to check left for obstacle
CCP1CON = TRUE ' ON 40KHz PWM
Right_Led=Led_Off : PAUSE 5 ' OFF right LED / pause
Left_Led=Led_On : PAUSE 5 ' ON left LED / pause
Left_IR = IR_Detector ' Read IR detector output
Left_Led=Led_Off ' OFF Left LED
CCP1CON = FALSE ' OFF 40KHz PWM
RETURN ' Return to calling routine
Check_Right: ' Call here to check for right obstacle
CCP1CON = TRUE ' ON 40KHz PWM
Left_Led=Led_Off : PAUSE 5 ' OFF left LED / pause
Right_Led=Led_On : PAUSE 5 ' ON right LED / pause
Right_IR = IR_Detector ' Read IR detector output
Right_Led=Led_Off' OFF Right LED
CCP1CON = FALSE ' OFF 40KHz PWM
RETURN ' Return to calling routine
Ping:
SonaControl=Active
Trigger=0 ' Pulsout = compliment of initial value
PULSOUT Trigger, 6 ' Output >10 uS trigger pulse
PULSIN Echo, 1, Width ' Measure distance to target
Distance = Width / 74 ' Convert to inches
SonaControl=InActive
RETURN
|
|

Back To Index
Copyright © 2007
Reynolds Electronics
http://www.rentron.com

|