Sie sind auf Seite 1von 15

FINAL PROJECT: WALL FOLLOWING ROBOT

EG 6380G Microcomputer Interfacing

Submitted by,
Ashutosh Jaiswal

Introduction
The primary aim of the project is to learn about interfacing external peripherals such as sensors and motors, to a microcontroller and program it to behave in an expected manner, based on the information collected. This is done by designing a wall following robot which collects information from its IR sensors and outputs information to the motors which drive the robot. The main task of the robot is to move parallel to a wall and at the same time avoid any kind of collision with the wall. It is however necessary to design some interfacing circuits to drive the motors and to receive data from the sensors in a way that the microcontroller would understand.

Project Description
The project may be divided into three main parts. Each of these parts will then be explained in detail. 1. Robot Hardware (Body) 2. Interface Circuitry 3. Algorithm/Program

1. Robot Hardware: The robots body was constructed using two hard plastic sheets which were cut into circular plates. The two plates where then mounted on top of each other using stand-offs, creating gap in between them, which was used to mount the battery. Two motors with gear box were used to drive the robot using a differential wheel arrangement. The wheels were mounted on the gear box and then entire assembly was fixed on the lower plate. The HCS12 evaluation board was mounted circuits were designed on the prototype board evaluation board. Three sensors were mounted on top plate, which would help in following the right mounted in the front to detect a wall in the front. A picture of the robot is shown in Fig 1. on the top plate and all provided along with the the right hand side of the wall and one sensor was

2. Interface Circuitry: The interface circuitry was required in order to control high current hardware (such as motor) using the microcontroller and to understand the signals given out by the IR sensor. The two main circuits used are, a. Motor Driver Circuit
b. IR Sensor Circuit Interface

Evaluation Upper Lower Motor with gear box Front

Right

Battery

Fig 1: Hardware Description of the robot

A variable power supply circuit was also used in order to supply sufficient voltage and current to the driving motors. The power supply circuit made use of the variable voltage regulator LM1086. The circuit used for this is shown in Fig 2,

Fig 2: Variable power supply circuit for the motors

Motor Driver Circuit: The motor driver circuit was used to act as a buffer between the microcontroller port and the high current motors. The IC used as a motor driver is L293D. The pin diagram of the IC along with the connections is shown in Fig 3. The digital control signal provided by HCS12 does not deliver sufficient current to drive the motor. Hence, a driver circuit, which is capable of changing the direction of motor using the logic signals and is capable of being driven at high current, is used. The IC is capable of driving motor with voltage up to 36V.

Fig 3: Schematic of the motor driver circuit using L293D

In the above circuit, Vin is the supply voltage for the IC as well as for the motor. D1 and D2 are the inputs which are used to control the direction of the motor. Both D1 and D2 are TTL logic level inputs. The table below (Table 1) shows the different combinations of D1 and D2, with its effect on motors operation,
Table 1: Combinations of D1 and D2 for controlling motor direction

D1 1 0 1 0

D2 0 1 1 0

Motor Direction Clockwise Direction An-Clockwise Direction BRAKE (STOP) BRAKE (STOP)

This is implemented in the microcontroller program in order to change the motor direction or in order to stop the motor, based on the action required to be taken. The same connections are made for the other motor of the robot. IR sensor circuit: The IR sensor circuit made use of the TCRT5000 sensor module as the sensing device, along with some external circuitry for sensitivity control. The circuit is shown in Fig 4. The TCRT5000 sensor module consists of an IR LED which emits IR rays and a IR photo transistor which is mounted next to it is the IR receiver. As the distance between the module and the wall decreases the amount of light being reflected off the wall increases, thereby increasing the IR light on the IR receiver. This promoted more conduction and thereby varies the output voltage. In an essence, the output voltage is a function of the distance and is directly proportional to it. However, the circuit here is designed such that; as the distance is decreased the output voltage decreases and with more distance the output voltage is higher. Based on this the HCS12 was programmed to detect when the robot was too close to the wall or too far from the wall, or at the right distance from the wall.

Fig 4: IR sensor circuit used for detecting wall

3. Algorithm and Program: The algorithm described below is based on the labeling shown in Fig 5,

Fig 5: Figure shows labeling used in the algorithm

In Fig 5, A corresponds to the value given by the front sensor depending on its distance from the wall. In a similar fashion B, C and D correspond to the values given out by the sensors on the right side of the robot. Algorithm:
START: { if A<x then Turn left 90 degrees else go to CHECK1

} CHECK1: { if C=B

if C=D { Move front } else go to CHECK2 }

CHECK2:

if C>B

Tilt Left else if C>D { Tilt Right } else go to CHECK_U CHECK_U: if A>y { if B>y { { if D>y { }

if

C>y

Perform U turn operation

} } else go to START }

x= optimal value derived by trial and error to define least distance of the sensor from wall y= optimal value derived by trial and error to define farthest distance of the sensor from wall

Based on the algorithm defined above, the program has been written in ALP for controlling the robot and is given in the next section, Program:
#include reg9s12.h ; include register equates ORG $1000 JSR openAD0 ; initialize and configure ATD0 JSR openlcd ; initialize and configure LCD MOVB #$0F, DDRA ; Set Port A as output port ; ************************************************************************************************* ** ;Check if button is pushed ; ************************************************************************************************* ** LDAA JSR LDX JSR LDAA STAA BRCLR reset then start countdown JMP Push_Button #$80 ; set DDRAM address to 0000000 cmd2lcd #Push_Button_msg ; point to 1st message character puts2lcd ; output it to LCD screen PORTA ;Load input value in port A Push ;Store the input value in memory Push,PSH,Countdown ;Check for Bit 4 --- if it is Push_Button ;If not reset then stay in loop

; ************************************************************************************************* **** ;Start Countdown before starting algorithm ; ************************************************************************************************* **** Countdown JSR JSR JSR JMP LDAA JSR LDX JSR LDX JSR RTS LDAA JSR LDX JSR LDX JSR RTS LDAA JSR LDX JSR LDX JSR RTS three two one forever #$80 cmd2lcd #Count3_msg puts2lcd #100 hlfsec #$80 cmd2lcd #Count2_msg puts2lcd #100 hlfsec #$80 cmd2lcd #Count1_msg puts2lcd #100 hlfsec ; set DDRAM address to 0000000 ;

three

two

; set DDRAM address to 0000000

one

; set DDRAM address to 0000000

Forever MOVB conversion for multi-channels MOVB MOVB MOVB cclp BRCLR JSR LDAA JSR LDX JSR LDAA JSR JMP

#$97,ATD0CTL5 #$96,ATD0CTL5 #$95,ATD0CTL5 #$93,ATD0CTL5

start

conversion

at

PAD7

and

set

ATD0STAT,SCF,cclp sens_ad #$C0 cmd2lcd #lcdmsg puts2lcd #46 START Forever ; wait till conversion is complete ; convert A/D value to voltage ; set DDRAM address to 0000000 ; ; point to 1st message character ; output it to LCD screen ; create 460 ms delay

; ************************************************************************************************* * ;Algorithm Starts .... ; F -Sens1 (Front sensor) ; A -Sens2 (1st on right) ; B -Sens3 (Middle) ; C -Sens4 (Last) ; ************************************************************************************************* * START LDD #900 ; Check if Front wall is present

CPD BHI degree operation JSR JMP JSR JSR JSR JSR RTS LDD CPD BLO JMP LDD CPD BLO RTS LDD CPD BHI JMP

Adr00h Front_Detect Front Check1 Brake Back Lefta Front Adr01h Adr02h Check1a Check2 Adr02h Adr03h Tilt_Left

; If present then perform left by 90 ; If not present go Front

Front_Detect

Check1

; Load D with sensor A's value ; Compare it with sensor B ; If A<B then robot is tilted right ; Check if B<C ; If true then robot is tilted right

Check1a so tilt left Check2 is tilted left

Adr01h Adr02h Check2a Check_uturn Adr02h Adr03h Tilt_Right

; Check if A > B, if true then robot

; Finally check for U-turn ; Check if B>C ; If true then robot is definitely

LDD CPD BHI tilted left, so tilt right RTS Check_uturn

Check2a

LDD Adr01h ; Load sensor A's value in D CPD #995 ; Compare D with a little less than the highest possible sensor value BHI CompB ; Branch to CompB is D is higher (NO WALL DETECTED) JMP Forever CompB LDD Adr02h ; Load sensor B's value in D CPD #995 ; Compare D with a little less than the highest possible sensor value BHI CompC ; Branch to CompB if D is higher (NO WALL DETECTED) JMP Forever CompC LDD Adr02h ; Load sensor C's value in D CPD #995 ; Compare D with a little less than the highest possible sensor value BHI CompF ; Branch to CompB if D is higher (NO WALL DETECTED) CompF LDD Adr02h ; Load sensor F's value in D CPD #995 ; Compare D with a little less than the highest possible sensor value BHI Uturn ; Branch to Uturn if D is higher (NO WALL DETECTED) JMP Forever ; ************************************************************************************************* *************** ;Commands ; ************************************************************************************************* *************** Tilt_Left JSR JSR JSR RTS Left Front_short Right

Tilt_Right

JSR ;JSR RTS JSR LDAA JSR LDX JSR JSR JSR JSR JSR

Right Front_short Brake #$80 cmd2lcd #Uturn_msg Front_Ustart Right90 Fronta Right90 Front_Ustart2

Uturn

; set DDRAM address to 0000000 ; point to 1st message character ; Go straight ; Turn right by 90 degrees ; Go straight so that the obstacle is ; Turn right by 90 degrees ; Go straight enough to make sure wall is

crossed detected

RTS

; ************************************************************************************************* ** ;MOTOR DIRECTION CONTROL SUBROUTINES ; ************************************************************************************************* ** Front MOVB #$0A,PORTA LDAA #$80 ; set DDRAM address to 0000000 JSR cmd2lcd LDX #Front_msg ; point to 1st message character JSR puts2lcd LDX #85 ; Load X with 5 for counting purposes gives 460ms JSR hlfsec RTS Front_Ustart LDAA JSR LDX JSR LDX JSR RTS Front_Ustart2 LDAA JSR LDX JSR LDX JSR RTS MOVB LDAA JSR LDX JSR LDX JSR RTS MOVB MOVB #$0A,PORTA #$80 ; set DDRAM address to 0000000 cmd2lcd #Uturn_msg ; point to 1st message character puts2lcd #150 hlfsec #$0A,PORTA #$80 ; set DDRAM address to 0000000 cmd2lcd #Uturn_msg ; point to 1st message character puts2lcd #400 ; hlfsec

Front_short

#$0A,PORTA #$80 cmd2lcd #Front_msg puts2lcd #85 ; hlfsec

; set DDRAM address to 0000000 ; point to 1st message character

; Long Front drive after U turn detect Fronta MOVB #$0A,PORTA LDAA #$80 JSR cmd2lcd LDX #Uturn_msg JSR puts2lcd LDX #625 JSR hlfsec

; set DDRAM address to 0000000 ; point to 1st message character

RTS ;Regular Left turn Left MOVB LDAA JSR LDX JSR LDX JSR RTS #$09, PORTA #$80 cmd2lcd #Left_msg puts2lcd #35 hlfsec

; set DDRAM address to 0000000 ; point to 1st message character

;90 degree left turn for front sensor Lefta MOVB #$09, PORTA LDAA #$80 JSR cmd2lcd LDX #Wall_msg JSR puts2lcd LDX #480 JSR hlfsec RTS Back MOVB LDAA JSR LDX JSR LDX JSR RTS Right MOVB LDAA JSR LDX JSR LDX JSR RTS Right90 MOVB LDAA JSR LDX JSR LDX JSR RTS Brake 460ms MOVB LDX JSR RTS #$05, PORTA #$80 cmd2lcd #Back_msg puts2lcd #150 hlfsec #$06, PORTA #$80 cmd2lcd #Right_msg puts2lcd #30 hlfsec #$06, PORTA #$80 cmd2lcd #uturn_msg puts2lcd #500 hlfsec #$00, PORTA #35 hlfsec

; set DDRAM address to 0000000 ; point to 1st message character

; set DDRAM address to 0000000 ; point to 1st message character ; Load X with 5 for counting purposes gives

460ms

; set DDRAM address to 0000000 ; point to 1st message character ; Load X with 5 for counting purposes gives

460ms

; set DDRAM address to 0000000 ; point to 1st message character ; Load X with 5 for counting purposes gives

460ms

; Load X with 5 for counting purposes gives

; ************************************************************************************************* **** ;0.5 sec delay ; ************************************************************************************************* **** hlfsec LDY #60000 ; (60000 X 4)/24 = 10 ms mlsec DEY BNE mlsec DBNE X,hlfsec RTS

; ************************************************************************************************* **** ;Reading Sensor values ; ************************************************************************************************* **** sens_ad LDD Adr00h ; get result of conversion LDY #10 ; multiply result by 10 to be EMUL ; able to divide it by 2046 LDX #2000 ; note! result only sitting in D IDIV ; integer part of the result is in X XGDX ; D has the remainder, swap them ADDB #$30 ; make it ASCII STAB sens1 LDD LDY EMUL LDX IDIV XGDX ADDB STAB LDD LDY EMUL LDX IDIV XGDX ADDB STAB LDD LDY EMUL LDX IDIV XGDX ADDB STAB RTS ; ******************************************************************************************* ;INITIALIZE A to D ; ******************************************************************************************* openAD0 MOVB #$E0,ATD0CTL2 LDY #120 ; 120 X 4 / 24 = 20 us ; ******************************************************************************************* ;LCD SUBROUTINE ; ******************************************************************************************* ad0lp DEY BNE ad0lp cmd2lcd PSHA BCLR BSET ANDA LSRA LSRA ORAA STAA NOP NOP NOP PORTK,RS PORTK,E #$F0 #E PORTK ; ; ; ; ; ; ; ; ; save the command in stack select the instruction register pull the E signal high clear the lower 4 bits match the upper four bits with the LCD data pins Maintain the E signal value send the command along w/ RS & E extend the duration of E pulse Adr01h #10 #2000 #$30 sens2 Adr02h #10 #2000 #$30 sens3 Adr03h #10 #2000 #$30 sens4 ; get result of conversion ; multiply result by 10 to be ; able to divide it by 2046 ; note! result only sitting in D ; get result of conversion ; multiply result by 10 to be ; able to divide it by 2046 ; note! result only sitting in D ; get result of conversion ; multiply result by 10 to be ; able to divide it by 2046 ; note! result only sitting in D ; integer part of the result is in X ; D has the remainder, swap them

sdly

BCLR PULA ANDA LSLA LSLA BSET ORAA STAA NOP NOP NOP BCLR LDY DEY BNE RTS MOVB JSR LDAA JSR LDAA JSR LDAA JSR LDAA JSR LDY DEY BNE RTS LDY DEY BNE RTS PSHA BSET BSET ANDA LSRA LSRA ORAA STAA NOP NOP NOP BCLR PULA ANDA LSLA LSLA BSET ORAA STAA NOP NOP NOP BCLR LDY DEY BNE RTS LDAA BEQ JSR JMP RTS

PORTK,E #$0F PORTK,E #E PORTK

; ; ; ; ; ; ; ; ; ; ; ; ;

pull the E signal low retrieve the LCD command clear the upper four bits match the lower four bits with the LCD data pins pull the E signal high maintain the E signal value send the lower 4-bit w/RS & E extend the duration of E pulse clear E signal to complete the operation 240 x 4 = 960 cycles = 40 micro_s 1 cycle 3 cycles

PORTK,E #240 sdly #$FF,DDRK d_10ms #$28 cmd2lcd #$0F cmd2lcd #$06 cmd2lcd #$01 cmd2lcd #10000 dly1 #60000 dly

openlcd

; configure port K for output ; wait for LCD to be ready ; set 4-bit data, 2-line display, 5x8 font ; turn on display, cursor, and blinking ; ; ; ; move cursor right (entry mode set instruction) clear the screen and return to home position

dly1

; 10000 x 4 = 40,000 cycles = 1.67ms ; 1 cycle ; 3 cycles ; 60000 x 4 = 240,000 cycles = 10ms ; 1 cycle ; 3 cycles ; ; ; ; ; ; ; ; ; ; ; ; ; save the command in stack select LCD data register pull the E signal high clear the lower 4 bits match the upper four bits with the LCD data pins keep E & RS signals unchanged send the upper 4-bit along w/ RS & E extend the duration of E pulse

d_10ms dly

putc2lcd

PORTK,RS PORTK,E #$F0 #$03 PORTK

PORTK,E #$0F PORTK,E #$03 PORTK

pull the E signal low retrieve the LCD command clear the upper four bits match the lower four bits ; with the LCD data pins ; pull the E signal high ; keep E & RS signals unchanged ; send the lower 4-bit w/RS & E ; extend the duration of E pulse ; clear E signal to complete the operation ; 240 x 4 = 960 cycles = 40 ?s ; 1 cycle ; 3 cycles ; ; ; ; get a character from string reach NULL character? if not, output to screen continue till whole string is outputed

PORTK,E #240 dly2 1,X+ done_puts putc2lcd puts2lcd

dly2

puts2lcd

done_puts

getchar RS E count1 count2 lcdmsg sens1 sens2 sens3 sens4 Front_msg

EQU EQU EQU RMB RMB FCC RMB FCC RMB FCC RMB FCC RMB

$EE84 $01 $02 1 1 'F:' 1 ' A:' 1 ' B:' 1 ' C:' 1 0 'GOING FRONT 0 'GOING BACK 0 'GOING RIGHT 0 'GOING LEFT 0 'U TURN 0 'PUSH TO START' 0 'STARTING IN 3 0 'STARTING IN 2 0 'STARTING IN 1 0 'OOPS!...A WALL!! 0 $80,$C0 $10 1 ' ' ' ' ' ' ' ' '

DB FCC DB Back_msg FCC DB Right_msg FCC DB Left_msg FCC DB Uturn_msg FCC DB Push_Button_msg FCC DB Count3_msg Count2_msg Count1_msg Wall_msg SCF PSH Push FCC DB FCC DB FCC DB FCC DB EQU EQU RMB END

Result and Conclusion


The robot worked as expected. It completed the maze fully and detected U turn and front walls perfectly. However, there were many difficulties that came across during the course of the project. One of them was driving the motors. Whenever the motor dragged more current under higher load, it would reset the evaluation board as the drop out voltage of the regulator was too close to the output voltage. In this case the board would automatically reset itself. In order to overcome this problem, the voltage to the motors was controlled using the adjustable voltage regulator, in such a way that at maximum load, the motor drops out the voltage of the boards supply, just enough to keep it at 5V mark. This would not reset the

evaluation board. Another problem was sensitivity of the IR sensors. The output voltage from the IR sensor circuit was first derived from the emitter of the photo transistor. However, it was found that the voltage range would be from 3 to 5 volts. This was because the impedance of the analog port along with the impedance of the photo-transistor, forced the voltage range to be limited. However, if the voltage was derived from the collector, a full range from 0 to 5 volts was attained.