Tout petit robot suiveur de lignes

Ce petit robot utilise 2 moteurs à courant continu commandés par un PIC 12F675, via de simples transistors à jonction en technologie CMS. Ces deux transistors ne sont pas protégés contre les surintensités (il y a juste une diode pour les surtensions), et sont calculés au plus juste, mais ça tourne !! (rien de grillé pour l'instant)...

Le but est tout simplement de suivre une ligne réalisée à l'aide d'un ruban adhésif noir, sur une feuille blanche : c'est un classique !!

Pour cela, le robot utilise deux capteurs à réflexion placés à l'avant : si le capteur droit voit du blanc, il fait marcher le moteur droit, et pareil pour le capteur gauche, avec le moteur gauche.

Schéma théorique

Liste des composants


BILL OF MATERIALS (Default)
===========================
Design:   Robot suiveur de lignes
Doc. no.: 
Revision: 
Author:   d.B
Created:  04/10/06
Modified: 23/10/06

Partslist generated OK.

QTY  PART-REFS           VALUE          
---  ---------           -----          
Resistors
---------
5    R1,R2,R10    150            
1    R3                  10k            
2    R5,R7            1,5M           
1    R8                  1500           
1    R4,R6,R9      47

Capacitors
----------
3    C1,C2,C3            100nF          

Transistors
-----------
3    Q1,Q2,Q3            PBSS4120T      

Diodes
------
1    D1                  Del            
2    D2,D3               1N4004         

Miscellaneous
-------------
1    BAT1                2,4 à 3 V      
1    IC1                 12F675         
1    K1                  BP             
1    MOT D               1,5 V          
1    MOT G               1,5V           
2    OPTO D,OPTO G       CNY70          

Détail du châssis

Allure du typon

Vue de dessus

Les copains rappliquent !!

Gros plan du circuit imprimé

Fichier source du PIC

 

;-----------------------------------------------------------------------------------------------
; 				Robot suiveur de ligne
; 					         dB
;				       PIC12F675 CMS
;				   Horloge interne 4 Mhz
;                 Version alu avec roues !!
;				   	      12/09/2006
;					      22/10/2006
;					      10/12/2006
;
;					Nouvelle version
;
;	- arrêt moteurs et attente pendant KOFF (fin des parasites)
;	- mesure éclairement et comparaison à Kseuil
;	- marche moteurs pendant KON
;	- etc jusqu'à l'arrêt défini par Kdodo
;	- BP utilisé en reset
;
;-----------------------------------------------------------------------------------------------
;
; Alimenté sur 2 accumulateurs NiMh en série soit environ Vcc = 2,5 V
;
;		Le robot suit une ligne noire en ruban adhésif de largeur 8 mm environ
;		La ligne est tracée sur une feuille blanche
;		Le capteur droit commande le moteur droit : si blanc marche, si noir arrêt
;		Idem pour le capteur gauche, avec le moteur gauche
;		Un capteur CNY70 délivre entre environ 2,1 V pour du noir et 1,1 V pour du blanc
;		On place donc un seuil à 1,7 V soit 255*1,7/Vcc = 175
;		Le mot du CAN 10 bits est 1023 pour Vcc
;		On utilise uniquement l'octet de gauche (on néglige les LSB) cela donne une division par 4
;		A la mise sous tension (mise en place des piles) le micro démarre et fait son boulot
;		Après 60 s il se met en veille (consommation quasi nulle)
;		Si on presse le BP il se réveille et recommence, etc ..
;
; Micro 12F675	E/S 25 mA
;
;				 Vdd	[ ° ]	Vss
;     Moteur gauche	GP5	[   ]	GP0 capteur gauche
;     Moteur droit	GP4	[   ]	GP1 capteur droit
;     Bouton pouss	GP3	[   ]	GP2 activation des capteurs
;

; Constantes

#define		Kseuil		165	; plus le seuil est élévé, et plus le robot voit du blanc partout
#define		KON			10	; temps de validation des moteurs
#define		KOFF		25	; temps d'arrêt des moteurs
#define		Kdodo		10	; comptage nombre de boucles pour arrêt automatique


; Variables

TensionD	equ	0X20		; mesure tension droite
TensionG	equ	0X21		; mesure tension gauche
ImageES		equ	0X22		; image port sortie moteurs
ONOFF		equ	0X23		; cumul temps (marche ou arrêt)
Dod			equ	0X24		; pour calcul Dodo
Dodo		equ	0X25		; cumul temps fonctionnement robot
Boucle		equ	0X26		; diviseur par 256

		ERRORLEVEL -302		; Turn off bank bits warning

; Preprocessor Directives
; Using 12F675 processor, generating an Intel HEX file, using DECimal radix

		LIST P=12F675, F=INHX8M, R=DEC
		#INCLUDE 
		__CONFIG  _INTRC_OSC_NOCLKOUT & _WDT_OFF& _PWRTE_OFF & _MCLRE_ON & _BODEN_OFF & _CP_OFF & _CPD_OFF


;-----------------------------------------------------------------------------------------------

	ORG		0x0000
	goto	Start

	ORG		0x0004
	goto	Start

	ORG		0x0005
Start

	banksel	OSCCAL	    		; BANK1
	call	3FFh      			; Retrieve Factory Calibration Value
	movwf	OSCCAL      		; Load OSCCAL

	banksel	GPIO
	clrf	GPIO

	banksel	CMCON
	movlw	07h				;Turn Off comparator
	movwf	CMCON

	banksel	ANSEL
	movlw	b'01100011'		; AD clock Fosc/64 et Entrée analogique = GP0 et GP1
	movwf	ANSEL		

	banksel	VRCON
	clrf	VRCON			;Turn Off VREF

	banksel	INTCON
	movlw	b'11001000'
	movwf	INTCON

	banksel	IOC
	movlw	b'00001000'
	movwf	IOC

	banksel	TRISIO
	movlw	b'00001011'		; GPI0 GPI1 GPI3 en entrée GPI2 GPI4 GPI5 en sortie
	movwf	TRISIO		

	banksel	OPTION_REG		;BANK 1	
	movlw	b'11001000'		;Pull Ups Desabled, Rising Edge, Assigned to WDT , Prescaler is 1:1 WDT
	movwf	OPTION_REG	

	banksel	WPU
	clrf	WPU			;Pullup Desabled

	clrf	TensionD
	clrf	TensionG
	clrf	ImageES
	clrf	ONOFF
	clrf	Dod
	clrf	Dodo
	clrf	Boucle
	
;-----------------------------------------------------------------------------------------------

Principal

	call	attente			; on arrête tout pour stopper les parasites
	call	mesureg			; mesure tension gauche
	call	mesured			; mesure tension droite
	call	moteurs			; mise en marche ou non des moteurs
	
	goto	Principal

;----------------------------------- stopper les parasites des moteurs ---------------------

attente

	banksel	ImageES		; on arrête les moteurs et on laisse les capteurs en marche
	movlw	b'00000100'
	movwf	ImageES
	banksel	GPIO
	movwf	GPIO

	banksel	Boucle		; et on attend pendant KOFF
	clrf	Boucle
	clrf	ONOFF

attent1

	incfsz	Boucle,1
	goto	attent1
	incf	ONOFF,1
	movf	ONOFF,W
	sublw	KOFF
	bnz		attent1

	return


;----------------------------------- mesure tension gauche -----------------------------------

mesureg

	banksel	ADCON0
	movlw	b'00000001'	; b7 à 0 : résultat CAN justifié à gauche : octet haut = 8 bits fort conversion, octet bas négligé
						; b6 à 0 : référence = Vcc
						; b5 à 0 : NU
						; b4 à 0 : NU
						; b3 à 0 : sélection entrée AN0 (= GP0 = broche 7)
						; b2 à 0 : idem
						; b1 à 0 : pas de demande de conversion
						; b0 à 1 : validation du CAN
	movwf	ADCON0	

	banksel	ADCON0
	bsf		ADCON0,1	; lance la conversion

adconverg
 	btfss	PIR1,6		; teste si la conversion est finie
   	goto	adconverg	; si pas finie on reteste

	bcf		PIR1,6		; on efface le flag
	bcf		INTCON,2		; on efface le flag TOIF

	movf	ADRESH, W	; on transfère le résultat de l'adc dans W
	movwf	TensionG

finconverg
	return

;----------------------------------- mesure tension droite -----------------------------------

mesured

	banksel	ADCON0
	movlw	b'00000101'	; b7 à 0 : résultat CAN justifié à gauche : octet haut = 8 bits fort conversion, octet bas négligé
						; b6 à 0 : référence = Vcc
						; b5 à 0 : NU
						; b4 à 0 : NU
						; b3 à 0 : sélection entrée AN1 (= GP1 = broche 6)
						; b2 à 1 : idem
						; b1 à 0 : pas de demande de conversion
						; b0 à 1 : validation du CAN
	movwf	ADCON0	

	banksel	ADCON0
	bsf		ADCON0,1	; lance la conversion

adconverd
 	btfss	PIR1,6		; teste si la conversion est finie
    goto	adconverd	; si pas finie on reteste

	bcf		PIR1,6		; on efface le flag
	bcf		INTCON,2		; on efface le flag TOIF

	movf	ADRESH, W	; on transfère le résultat de l'adc dans W
	movwf	TensionD

finconverd
	return

;-------------------------- Commande des moteurs ---------------------------------------------

moteurs

	banksel	ImageES
	movlw	b'00000100'
	movwf	ImageES

	movf	TensionD,W	; on charge W
	sublw	Kseuil		; opération Kseuil - TensionD
	bnc		suita		; si borrow (TensionD > Kseuil) on saute
	bsf		ImageES,4	; Marche moteur D

suita
	movf	TensionG,W	; on charge W
	sublw	Kseuil		; opération Kseuil - TensionG
	bnc		suitb		; si borrow (TensionG > Kseuil) on saute
	bsf		ImageES,5	; Marche moteur G

suitb

	movf	ImageES,W
	banksel	GPIO
	movwf	GPIO

	banksel	Boucle		; attente pendant KON
	clrf	Boucle
	clrf	ONOFF

suitc

	incfsz	Boucle,1
	goto	suitc
	incf	ONOFF,1
	movf	ONOFF,W
	sublw	KON
	bnz		suitc

	incfsz	Dod,1		; on regarde s'il est l'heure de faire dodo
	goto	suitd
	incf	Dodo,1

suitd
	movf	Dodo,W
	sublw	Kdodo
	bnz		suite
	clrf	ImageES		; Si dodo
	movf	ImageES,W	; alors on arrête moteurs et capteurs
	banksel	GPIO
	movwf	GPIO
	bcf		INTCON,0
	sleep				; et on fait dodo (réveil par Reset donc rien à préparer)

suite
	return				; on sort


;--------------------------------------------- fin ---------------------------------------------
        end
;-----------------------------------------------------------------------------------------------