Un concours classique pour tester des petits robots consiste a leur faire suivre un parcours figuré par une ligne noire sinueuse tracée sur un sol blanc.
Pour commencer on utilise des parcours sans dénivellées et sans croisements ; avec des virages d'au moins 15,5 centimétres de rayon (c'est ce que nous ferons) ; puis on complique avec croissements, sol irrégulier, ponts et tunnels.
Pour tracer le parcours nous utiliserons des dalles de Gerflex blanc en y collant une bande de ruban adhésif noir de 3 cm de large (on peut acheter un revétement décoratif auto collant noir au rayon déco et papiers peints d'une grande surface de bricolage. Une fois le tracé dessiné numéroter les dalles dessous pour s'y retrouver pour remonter ce circuit.
Pour suivre ces parcours il est classique d'utiliser des détecteurs optiques soit dans le visible soit plutot dans l'infra rouge. Comme le PEKIT contient des émeteurs Irfra rouges (LEDs) et des détecteurs correspondants (des ptotodiodes) nous décrirons cette solution.
Ce montage demande plus de réglages que les précédents et nécessitera plus de temps de mise au point.
Le montage comporte :
Les phtotodiodes de détection sont du type de celles utilisées par les téléviseurs pour recevoir les messages du boitier de télé commande. Elles ont la particularité de reconnaitre les infrarouges émis de façon discontinue avec des fréquences voisines de 38500 hertz. Cela les met a l'abri des interférences d'une partie des souces IR de l'environnement , mais pas toutes.
On doit donc faire émettre les LED infrarouges dans des fréquences entre 38 5000 et 42 500 et en fait on totalisera trente lectures faites rapidement de 100 en 100 hertz . Seuls les objets assez proches réfléchissent assez pour alerter le détecteur et les fréquences les plus élevées détectent les objets les plus éloignés . La détection dépend aussi de la couleur des objets : les surfaces blanches réfléchissent beaucoup mieux que les surfaces noires. On peut chercher la sensibilité optimale pour notre parcours en modifiant la valeur des résistances associées aux diodes éméttrices en la diminuant on augmente la sensibilité en augmentant la résistance on diminue la sensibilité (la diode qui recoit moins de courant émet moins).
Pour les suivis de ligne noire sur fond blanc on met une forte résistance ( vers 4,7 kilo Ohms) en série avec la diode émettrice pour diminuer sa portée et sa sensibilité si elle est bien réglée les détecteurs donneront des "1" sur fond noir et des "0" sur fond blanc. Donc en démarrant avec le robot a cheval sur la ligne et un groupe émetteur /récepteur de chaque coté du robot on pourra corriger la trajectoire vers la gauche ou la droite en fonction des réponses des 2 détecteurs. La correction est proportionnelle a l'écart par rapport a une réponse de référence inférieure a 10 . Mais comme les conditions peuvent varier on la multiplie par un facteur variable de sensibité (normalement égal a 2 ou 3).
Au démarrage on régle les durées (lduree et rduree) des impulsions envoyées aux servos droit et gauche pour avoir un robot qui roule a environ la moitié de sa vitesse maximum: pour pouvoir accélérer ou ralentir facilement l'une des deux roues sans aller en butée. _Linit = 1550 et _Rinit = 1372 '
Le programme:
Nous avons volontairement laissé dans ce programme des méthodes pour tester : la présence d'émissions IR parasites dans l'environnement, de test de sensibilité des détecteurs droits ou gauches.En effet ces systémes de détection infra rouges sont sujets a différentes interférences ou variations de sensibilité selon la surface du sol (plus ou moins brillant, plus ou moins éclairé, plus ou moins contrasté entre la couler du fonf et celle de la ligne noire) et nécessitent des moyens de surveillance (il suffit d'enlever les apostrophes qui masquent l'appel a ces programmes de test pour pouvoir les utiliser immédiatement).
Pour signaler un erreur ou un test positif on peut utiliser soit un bip émis par le buzzer soit l'allumage d'une des 2 LEDs témoin verte ou rouge.
Vous noterez la méthode <tester irdeteteurs avec débuggage> elle montre une méthode précieuse pour tester les robots , auusi nous allons un peu détailler son emploi :
{{
MinibotsuiveurligneIR.spin
'' * Marche avec MINIBOT
'' * servo droit en p14 et gauche en pin 15
'' * détecteurs en P4 et P5
'' * LED émétrices en P6 et P7
'' * attention le détecteur PNA4602M utilisé renvoie 0 si il recoit la lumiére réfléchie par une surface blanche
'' * et renvoie 1 (39 si cumulé) si il n'y a pas de lumiére réfléchie , cas d'une surface noire
'' * radio en pin 20 et 21
}}
CON
_xinfreq = 5_000_000 ' External crystal frequency
_clkmode = xtal1 | pll16x ' Set feedback for 4 to 16 MHz ' crystal, and multiply signal up to 80 MHz for system clock.
_Linit = 1550 'pour démarrer en marche avant
_Rinit = 1372 ' a demi vitesse _Linit = 1550 et _Rinit= 1372
VAR
long stack1[9] 'espace pour new cog
long stack2[9]
byte cog1 'espace pour ID du cog
byte pin1, pin2
long Time,Lduree,Rduree
OBJ ' on fait appel a des objets externes
irG : "Ir Detector"
irD :"Ir Detector"
'debug : "FullDuplexSerial" 'utiliser pour tester les détecteur en envoyant leurs résultats vers l'hyperterminal du PC
PUB init
Time:=cnt
Lduree:=_Linit 'sinon pas de valeur pour démarrer
Rduree:= _Rinit 'IMPORTANT INITIALISER ces VARIABLES
irG.init(6,4) 'détecteur G
irD.init(7,5) 'détecteur D
'P6 et P7 LED EMETRICES P4 et P5 détecteurs photodiodes
'Irinterferencesniffer 'recherche des sources infra rouges de parasites
'waitcnt(clkfreq*10 + cnt)
'testedetectionblanc 'mettre sur fond blanc
'waitcnt(clkfreq*10 +cnt)
'testedetectionnoir 'dés le bip du blanc mettre un fond noir
'Noter si détecteurs pas alimentés = comme si revoient toujours zéro
' donc sonne pour fond blanc en premier meme si papier noir et ne sonne jamais sur testenoir
cognew(runmotors, @stack2) 'METTRE COGNEW HORS de la BOUCLE REPEAT !!!
'testeIRdetectorsavecLEDS
'debug.start(31, 30, 0, 9600)
'testeIRdetectorsavecdebug 'nécessite debug
readirdetectors
PUB PulsePiezoSpeaker (Nfois ,frequence,duty) | dureecyclemicrosec, dureeON, dureeOFF ' utilisé au cours de tests de controle
dira[16]~~ ' on ouvre le pin 16 en emission
dureecyclemicrosec:=(clkfreq/frequence)
dureeON:= (dureecyclemicrosec * duty)/100
dureeOFF:= dureecyclemicrosec-dureeON
repeat Nfois
!outa[16]
waitcnt(dureeON + cnt) '
!outa[16]
waitcnt (dureeOFF + cnt) '
waitcnt (clkfreq/4 + cnt)
PUB IrInterferenceSniffer |distD,distG 'A GARDER pour controles
distD := irD.Distance ' Get IR distance (0 to 40)
distG := irG.Distance ' 39 = pas d'obstacle proche ou ligne noire
' 0 a 10 surface blanche détectée
repeat 1
if (distD<10) OR (distG<10)
bipbip
waitcnt (clkfreq +cnt)
PUB testedetectionblanc |distD,DistG 'A GARDER
distD := irD.Distance ' Get IR distance (0 to 40)
distG := irG.Distance ' 39 = pas d'obstacle proche ou ligne noire
' 0 a 10 surface blanche détectée
if (distD<10) AND (distG<10)
bipbip
PUB testedetectionnoir |distG, distD 'A GARDER
distD := irD.Distance ' Get IR distance (0 to 40)
distG := irG.Distance ' 39 = pas d'obstacle proche ou ligne noire
' 0 a 10 surface blanche détectée
if (distD>30) AND (distG>30)
bipbip
PUB bipbip
repeat 5
PulsePiezoSpeaker(1000, 4400,60) 'pas mal vers 4400 et 60%
waitcnt(clkfreq/10 +cnt)
PUB runmotors
dira[14]~~ 'servo droit
dira[15]~~ 'servo gauche
outa[15]~
outa[14]~
Time:=cnt
repeat
pulseleft
pulseright
PUB readIRdetectors | distD, distG , offset ,sensibilite
dira[26]~~
dira[27]~~
repeat
offset:=0
sensibilite:=4 '3 va (mais 2 ou 6 ne vont pas)
distD := irD.Distance ' Get IR distance (0 to 40)
distG := irG.Distance ' 39 = pas d'obstacle proche ou ligne noire
' entre 0 et 10 = obstacle blanc entre 0 et 18 cm
'faire viser les détecteurs sur la table a 12 cm de leur face avant
'si ligne noire au milieu = 2 détecteurs dans le blanc et <15
'si va a droite = détecteur gauche > 10 donc accélérer moteur droit
'si va a gauche = détecteur droit > 10 donc accélérer moteur gauche
if (distG >10) 'sur 6-4
outa[26]:= 1 'LED rouge ON et ligne noire détectée par détecteur gauche BABORD
else
outa[26]:= 0
if (distD>10) 'sur 7-5
outa[27]:= 1 'LED vert ON et ligne noire détectée par détecteur droit TRIBORD
else
outa[27]:= 0
'au départ Rinit=1372 Linit=1550
'pour ralentir se raprocher de 1450 pour accélerer s'en éloigner
'pourquoi la roue droite accélére mieux quand il y a une ligne noire visible sur la gauche
'que la roue gauche quand il y a une ligne noire visible sur la droite ?
if (distD <10)and ( distG <10)
Lduree:=_Linit '1550
Rduree:=_Rinit '1372
elseif (distG >10) 'sur 6-4 et led ROUGE GAUCHE ON trop a droite > accélérer D ralentir G
offset:= (distG -10)* sensibilite
Lduree:= (_Linit - offset) #> 1450 'on rapproche gauche de 1450
Rduree:= (_Rinit - offset) #> 1250 'on éloigne droit de 1450
elseif ( distD>10)'sur 7-5 et led VERTE DROIT ON trop a gauche > accélerer G ralentir D
offset:= (distD -10)* sensibilite
Lduree:= (_Linit + offset) <# 1650
Rduree:= (_Rinit + offset) <# 1450
waitcnt (clkfreq/20 +cnt) 'un delai est indispensable ICI
'A QUOI CORRESPOND CE DELAI ???? est ce un temps de remise a zéro du détecteur
'clkfreq1/10 a 1/20 possible
' si on met 1/100 les diodes témoin indiquent une détection droite et gauche en même temps
PUB testeirdetectorsavecdebug |distD,DistG
dira[27]~~
dira[26]~~
repeat
distD := irD.Distance ' Get IR distance (0 to 40)
distG := irG.Distance ' 10 a 39 = pas d'obstacle proche ou ligne noire
' entre 0 et 10 = obstacle blanc entre 0 et 18 cm
'faire viser les détecteurs sur la table a 12 cm de leur face avant
'si ligne noire au milieu = 2 détecteurs dans le blanc et <15
'si va a droite = détecteur gauche > 10 donc accélérer moteur droit
'si va a gauche = détecteur droit > 10 donc accélérer moteur gauche
debug.dec(distD)
debug.tx(32)
debug.dec(distG) ' Display distance for HyperTerminal
debug.str(String(10,13)) ' Start of next line
if (distD >10)
outa[27]:= 1 'VERT ON
else
outa[27]:= 0
if (distG>10)
outa[26]:= 1 'ROUGE ON
else
outa[26]:= 0
waitcnt (clkfreq +cnt)
PUB testeirdetectorsavecLEDS |distD,DistG
dira[27]~~
dira[26]~~
repeat
distD := irD.Distance ' Get IR distance (0 to 40)
distG := irG.Distance ' 10 a 39 = pas d'obstacle proche ou ligne noire
' entre 0 et 10 = obstacle blanc entre 0 et 18 cm
'faire viser les détecteurs sur la table a 12 cm de leur face avant
'si ligne noire au milieu = 2 détecteurs dans le blanc et <15
'si va a droite = détecteur gauche > 10 donc accélérer moteur droit
'si va a gauche = détecteur droit > 10 donc accélérer moteur gauche
if (distD >10)
outa[27]:= 1
else
outa[27]:= 0
if (distG>10)
outa[26]:= 1
else
outa[26]:= 0
waitcnt (clkfreq +cnt)
PUB pulseleft | duree
duree:=Lduree
!outa[15]
waitcnt(((clkfreq/1_000_000) * duree) +cnt) 'clkfreq= 1seconde
!outa[15]
waitcnt ( Time+= clkfreq/50 )
PUB pulseright | duree
duree:=Rduree
!outa[14]
waitcnt(((clkfreq/1_000_000)* duree) +cnt)
!outa[14]
waitcnt ( Time+= clkfreq/50 )