Linbot Advanced Line Following Robo1
Linbot Advanced Line Following Robo1
by : activerobot
Linbot is an advanced line tracer robot. It has one pair of infrared emitters and sensors directed forward, as well as
three pairs of infrared emitters and sensors directed downward. Linbot can follow a black line placed on a white floor
as well as a white line on a black floor.
When it meets with an obstacle while following the line, it makes a U-turn and continues on. It comes in kit form,
allowing the user to acquire hands on experience in robotic principles.
Features
PIC16F876(Microchip).
Two modes: Simple line-tracer mode.
Line-tracer with obstacle avoidance.
Four speed settings.
Trace a black line or a white line.(Selectable)
Pulse Width Modulation(PWM) motor control.
Intelligent line tracing.
-Continual Adjustment.
-If goes off the line, can find way back.
-Can handle intersecting lines.
-In-System Programming(ISP) port.
-Source program is available on the web.
-Downloadable free development tools(MPLAB : Assembler, Linker, Debugger).
Specifications
Item Description
SIZE 125.5 x 87 x 41(H) mm
CPU PIC16C876
SENSOR Bottom: Infrared emitter x 3, Infrared sensor x 3
Front: Infrared emitter x 1, Infrared sensor x 1
MOTOR MRM-GM03 Gearbox(DC Motor x 2)
SPEED 4 speed modes : 20 - 60 cm/s
BUZZER Piezo Buzzer(ALP1205S)
LED Sensor data indicator LED x 4
KEY Jumper switch x1, Push switch x 1
PORT ISP port for MPLAB-ICD
BATTERY AA x 4(not included)
;==================================================
;
; This file is a basic code for Linbot.
; Linbot is a intelegent line tracer.
; Linbot's CPU is a PIC16F876.
;
;==================================================
;
; Filename: LINBOT.ASM
; Date: Sept,2001
; File Version: 1.0
;
; Author: James Jeong
; Company: Microrobot(www.microrobot.com)
;
;===============================================
LIST P=16F876
#INCLUDE <P16F876.INC>
;; Macros.
BANK0 MACRO
BCF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK1 MACRO
BCF STATUS,RP1
BSF STATUS,RP0
ENDM
BANK2 MACRO
BSF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK3 MACRO
BSF STATUS,RP1
BSF STATUS,RP0
ENDM
#DEFINE RM_IN2_OUT PORTC,0 ; RIGHT MOTOR IN2 (RIGHT MOTOR CONTROLS LEFT WHEEL.)
#DEFINE RM_IN1_OUT PORTC,1 ; RIGHT MOTOR IN1
#DEFINE LM_IN1_OUT PORTC,2 ; LEFT MOTOR IN1 (LEFT MOTOR CONTROLS RIGHT WHEEL.)
#DEFINE LM_IN2_OUT PORTC,3 ; LEFT MOTOR IN2
#DEFINE FRONT_LED_OUT PORTC,4 ; LED
#DEFINE RIGHT_LED_OUT PORTC,5 ; LED
#DEFINE CENTER_LED_OUT PORTC,6 ; LED
#DEFINE LEFT_LED_OUT PORTC,7 ; LED
;=============================================
;=============================================
ISR
RETFIE
;=============================================
START
CALL INIT_PORT
CALL INIT_ADC
CALL INIT_PWM
CALL START_SIGN
MOVLW .50
MOVWF FRONT_REF_REG
;;
MAIN
CALL READ_LEFT
CALL DELAY_1MS
CALL READ_CENTER
CALL DELAY_1MS
CALL READ_RIGHT
CALL DELAY_1MS
CALL READ_VR
CALL READ_FRONT
MOVF L_AD_REG,W
SUBWF VR_AD_REG,W ; VR - L_AD_REG
BTFSC STATUS,C
BSF LEFT_FLAG ; IF L_AD_REG > VR_AD_REG THEN SET FLAG.
MOVF C_AD_REG,W
SUBWF VR_AD_REG,W
BTFSC STATUS,C
BSF CENTER_FLAG ; IF C_AD_REG > VR_AD_REG THEN SET FLAG.
MOVF R_AD_REG,W
SUBWF VR_AD_REG,W
BTFSC STATUS,C
BSF RIGHT_FLAG ; IF R_AD_REG > VR_AD_REG THEN SET FLAG.
MOVF F_AD_REG,W
SUBWF FRONT_REF_REG,W
BTFSS STATUS,C
BSF FRONT_FLAG ; IF F_AD_REG > VR_AD_REG THEN SET FLAG.
TURN_OFF LEFT_LED_OUT
TURN_OFF CENTER_LED_OUT
TURN_OFF RIGHT_LED_OUT
TURN_OFF FRONT_LED_OUT
BTFSC LEFT_FLAG
TURN_ON LEFT_LED_OUT
BTFSC CENTER_FLAG
TURN_ON CENTER_LED_OUT
BTFSC RIGHT_FLAG
TURN_ON RIGHT_LED_OUT
BTFSC FRONT_FLAG
TURN_ON FRONT_LED_OUT
CALL DELAY_1MS
MOVLW B'00000111' ;
ANDWF SENSOR_REG,W ;
ADDWF PCL ; JUMP WITH TABLE.
GOTO NO_LINE ;0
GOTO LEFT_LINE ;1
GOTO CENTER_LINE ;2
GOTO LEFT_CENTER_LINE ;3
GOTO RIGHT_LINE ;4
GOTO NUL_LINE ;5
GOTO RIGHT_CENTER_LINE ;6
GOTO CENTER_LINE ;7
GOTO MAIN
LEFT_LINE CALL LEFT_SMALL
BSF PRE_OP_FLAG ; PRE_OP_FLAG=1
GOTO MAIN
CENTER_LINE CALL GO1
GOTO MAIN
LEFT_CENTER_LINE CALL LEFT_VSMALL
GOTO MAIN
RIGHT_LINE CALL RIGHT_SMALL
BCF PRE_OP_FLAG ; PRE_OP_FLAG=0
GOTO MAIN
NUL_LINE CALL GO1
GOTO MAIN
RIGHT_CENTER_LINE CALL RIGHT_VSMALL
GOTO MAIN
;==========================================
DELAY_10US
GOTO $+1
GOTO $+1
RETURN
;===========================================
DELAY_50US
MOVWF DELAY_STACK1
MOVLW .15
MOVWF DELAY_CNT1
D_50US_1
DECFSZ DELAY_CNT1
GOTO D_50US_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_100US
MOVWF DELAY_STACK1
MOVLW .30
MOVWF DELAY_CNT1
D_100US_1
DECFSZ DELAY_CNT1
GOTO D_100US_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_500US
MOVWF DELAY_STACK1
MOVLW .164
MOVWF DELAY_CNT1
D_500US_1
DECFSZ DELAY_CNT1
GOTO D_500US_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_1MS
MOVWF DELAY_STACK1
MOVLW .198
MOVWF DELAY_CNT1
D_1MS_1
GOTO $+1
DECFSZ DELAY_CNT1
GOTO D_1MS_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_5MS
CALL DELAY_1MS
CALL DELAY_1MS
CALL DELAY_1MS
CALL DELAY_1MS
CALL DELAY_1MS
RETURN
;===========================================
DELAY_50MS
MOVWF DELAY_STACK2
MOVLW .50
MOVWF DELAY_CNT2
D_50MS_1
CALL DELAY_1MS
DECFSZ DELAY_CNT2
GOTO D_50MS_1
MOVF DELAY_STACK2,W
RETURN
;===========================================
DELAY_100MS
MOVWF DELAY_STACK2
MOVLW .100
MOVWF DELAY_CNT2
D_100MS_1
CALL DELAY_1MS
DECFSZ DELAY_CNT2
GOTO D_100MS_1
MOVF DELAY_STACK2,W
RETURN
;===========================================
DELAY_500MS
CALL DELAY_100MS
CALL DELAY_100MS
CALL DELAY_100MS
CALL DELAY_100MS
CALL DELAY_100MS
RETURN
;===========================================
DELAY
MOVWF DELAY_CNT2
DELAY_LOOP1
CALL DELAY_1MS
DECFSZ DELAY_CNT2
GOTO DELAY_LOOP1
RETURN
;=======================================
INIT_PORT
BANKSEL PORTA
BANKSEL TRISC
MOVLW B'00000000'
MOVWF TRISC
MOVLW B'11000011'
MOVWF TRISB
BCF OPTION_REG,NOT_RBPU ; PULL UP PORTB
; FOR PUSH AND JUMPER SWs INPUT.
MOVLW B'00101111'
MOVWF TRISA
BANK0
RETURN
;===========================
;===========================
INIT_ADC
BANKSEL ADCON0
MOVLW B'01000001' ; FOSC/8, AN0, A/D IS TURNED ON.
MOVWF ADCON0
BANKSEL ADCON1
MOVLW B'00000010' ; LEFT JUSTIFIED. AD=AN0~AN5. REF=VDD,VSS.
MOVWF ADCON1
BANK0
RETURN
;=============================================
INIT_PWM
BANKSEL T2CON
MOVLW B'00000101'
MOVWF T2CON ; PRESCALER =4, POSTSCALER =1:1
; TIMER2 ON
; TIMER2 CLOCK = 0.25MHz
MOVLW B'00001111'
MOVWF CCP1CON ; 2 LSBS=0, PWM MODE
MOVWF CCP2CON ; 2 LSBS=0, PWM MODE
BANKSEL PR2
MOVLW 0XFF
MOVWF PR2 ; PERIOD = 980HZ = 250000/255
BANKSEL CCPR1L
MOVLW 0X00 ; STOP RIGHT WHEEL(LEFT MOTOR)
MOVWF CCPR1L ; PWM DUTY CYCLE REGISTER
MOVLW 0X00 ; STOP LEFT WHEEL(RIGHT MOTOR)
MOVWF CCPR2L ; PWM DUTY CYCLE REGISTER
RETURN
;========================================
;========================================
START_SIGN
BANK0
TURN_ON BUZZER_OUT
TURN_ON LEFT_LED_OUT
CALL DELAY_100MS
TURN_OFF BUZZER_OUT
CALL DELAY_100MS
TURN_OFF LEFT_LED_OUT
TURN_ON CENTER_LED_OUT
CALL DELAY_100MS
CALL DELAY_100MS
TURN_OFF CENTER_LED_OUT
TURN_ON RIGHT_LED_OUT
CALL DELAY_100MS
CALL DELAY_100MS
TURN_OFF RIGHT_LED_OUT
RETURN
;=====================================
READ_FRONT
BANKSEL ADCON0
MOVLW B'01011001' ; FOSC/8, AN3, A/D IS TURNED ON.
MOVWF ADCON0
TURN_ON FRONT_IR_OUT
CALL DELAY_50US
TURN_OFF FRONT_IR_OUT
BSF ADCON0,GO_DONE
R_F_1
BTFSC ADCON0,GO_DONE
GOTO R_F_1
MOVF ADRESH,W
MOVWF F_AD_REG
BANK0
RETURN
;=====================================
READ_LEFT
BANKSEL ADCON0
MOVLW B'01000001' ; FOSC/8, AN0, A/D IS TURNED ON.
MOVWF ADCON0
TURN_ON LEFT_IR_OUT
CALL DELAY_10US
CALL DELAY_10US
TURN_OFF LEFT_IR_OUT
BSF ADCON0,GO_DONE
R_L_1
BTFSC ADCON0,GO_DONE
GOTO R_L_1
MOVF ADRESH,W
MOVWF L_AD_REG
BANK0
RETURN
;======================================
READ_CENTER
BANKSEL ADCON0
MOVLW B'01001001' ; FOSC/8, AN1, A/D IS TURNED ON
MOVWF ADCON0
TURN_ON CENTER_IR_OUT
CALL DELAY_10US
CALL DELAY_10US
TURN_OFF CENTER_IR_OUT
BSF ADCON0,GO_DONE
R_C_1
BTFSC ADCON0,GO_DONE
GOTO R_C_1
MOVF ADRESH,W
MOVWF C_AD_REG
BANK0
RETURN
;====================================
READ_RIGHT
BANKSEL ADCON0
MOVLW B'01010001' ; FOSC/8, AN2, A/D IS TURNED ON
MOVWF ADCON0
TURN_ON RIGHT_IR_OUT
CALL DELAY_10US
CALL DELAY_10US
TURN_OFF RIGHT_IR_OUT
BSF ADCON0,GO_DONE
R_R_1
BTFSC ADCON0,GO_DONE
GOTO R_R_1
MOVF ADRESH,W
MOVWF R_AD_REG
BANK0
RETURN
;======================================
READ_VR
BANKSEL ADCON0
MOVLW B'01100001' ; FOSC/8, AN0, A/D IS TURNED ON
MOVWF ADCON0
CALL DELAY_10US
CALL DELAY_10US
BSF ADCON0,GO_DONE
R_V_1
BTFSC ADCON0,GO_DONE
GOTO R_V_1
MOVF ADRESH,W
MOVWF VR_AD_REG
BANK0
RETURN
;=======================================
SET_STOP
BANKSEL CCPR1L
MOVLW 0X00 ; PWM = 0
MOVWF CCPR1L ;
RETURN
;=======================================
GO1
BANKSEL CCPR1L
MOVLW PWM_HIGH ;
MOVWF CCPR1L ;
MOVLW PWM_HIGH ;
MOVWF CCPR2L ;
BANK0
RETURN
;====================================
LEFT_SMALL
BANKSEL CCPR1L
MOVLW PWM_HIGH ;
MOVWF CCPR1L ;
MOVLW PWM_LOW ;
MOVWF CCPR2L ;
BANK0
RETURN
;====================================
LEFT_VSMALL
BANKSEL CCPR1L
MOVLW PWM_HIGH ;
MOVWF CCPR1L ;
MOVLW PWM_VLOW ;
MOVWF CCPR2L ;
BANK0
RETURN
;===================================
RIGHT_SMALL
BANKSEL CCPR1L
MOVLW PWM_LOW
MOVWF CCPR1L ;
MOVLW PWM_HIGH ;
MOVWF CCPR2L ;
BANK0
RETURN
;======================================
RIGHT_VSMALL
BANKSEL CCPR1L
MOVLW PWM_VLOW
MOVWF CCPR1L ;
MOVLW PWM_HIGH ;
MOVWF CCPR2L ;
BANK0
RETURN
;=====================================
;=====================================