Vous êtes sur la page 1sur 9

Un suiveur de ligne (encore avec Arduino) - Brico bidules

1 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

Des bricolages en tout genre, comme je veux, comme a vient.


Accueil Billets rcents
Archives
ArduTiger, un robot qui vite les obstacles - L'encodeur du pauvre

Un suiveur de ligne (encore avec Arduino)


Par Professeur Shadoko, mardi 6 mars 2012. Lien permanent Robots Arduino

Aprs mon robot viteur d'obstacles, je me suis fabriqu un robot suiveur de ligne. Ca ne sert rien mais c'est un classique
amusant faire.
Le principe est simple : un chssis motoris suit une ligne noire. Des dtecteurs observent la position de la ligne et donnent les
ordres de correction correspondants au robot.

Version 1 : a eut march...


suiveur_v1_600.JPG
Je me suis d'abord lanc avec ce que j'avais sous la main.
Pour la motorisation, j'ai rcupr deux moteurs courant continu avec moto-rducteurs qui me restaient, toujours suite
l'amlioration d'un char radio-command (http://youtu.be/LyNH567mb_A) . Ce sont des moteurs trs bas de gamme ce qui ne m'a
pas facilit la tche.
Pour les capteurs, j'avais achet des petits rcepteurs-metteurs infrarouges QRD1114 (http://www.alpha-crucis.com
/fr/recherche?orderby=position&orderway=desc&search_query=qrd1114&submit_search=) pour faire de la dtection de sol pour
mon robot viteur d'obstacles mais ils se sont rvls totalement inadapts cet usage. Par contre ils sont idaux pour la dtection
d'une ligne noire sur fond blanc, ce qui est prcisment ce qu'on leur demande.
Pour relier tout a, j'ai fabriqu un chssis en matriau de rcup.
Le chssis porte les moteurs un bout, l'accu pour les alimenter l'autre bout et par-dessus la carte de commande des moteurs et

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

2 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

l'Arduino. Les capteurs peuvent tre fixs aux extrmits. Un patin tflon sert de "troisime roue" l'extrmit de l'ensemble.
Les moteurs sont pilots via une carte de commande base sur un pont en H L298 pilote par l'Arduino. C'est un peu un marteau
pour craser une mouche vu que deux transistors auraient aussi bien fait l'affaire.
Ce projet ne devait me prendre qu'une aprs-midi, mon ide tant de coller deux capteurs devant le robot (un de part et d'autre de
la ligne), crire les 10 lignes de code correspondantes (ligne sur le capteur droit : on tourne gauche et vice-versa) et hop!
Mais a s'est rvl un tantinet plus difficile...
Premier essai
Pour ce premier essai, on a deux capteurs l'avant du robot, assez loin des moteurs, et un code simple : on avance vitesse
constante et si la ligne est dtecte on bloque le moteur situ du ct du capteur. a marche... plus ou moins.
Dj, la dmarche du robot est trs hache puisqu'il zigzague en "butant" sur la ligne en permanence. Ensuite, comme les capteurs
sont loin des moteurs, ils font de grandes embardes et perdent rgulirement la ligne. Enfin, le robot a la curieuse manie de
tourner trs bien gauche, mais trs mal droite... Il fallait donc revoir tout a.
Deuxime essai
Pour le deuxime essai, j'ai tout d'abord modifi les capteurs : au lieu de 2, j'en ai 4 en ligne. J'ai tout ralis la main mais a peut
aussi s'acheter tout fait (http://www.alpha-crucis.com/fr/capteurs/341-qtr-8rc-reflectance-sensor-array-3700386709616.html) . De
plus les capteurs sont placs l'arrire du robot, qui devient donc l'avant, bien plus prs des moteurs, rduisant la vitesse de leur
mouvement latral par rapport l'axe davance.
Le comportement du robot est plus "intelligent" : si la ligne est dtecte par un des capteurs centraux (petite erreur), on tourne
doucement en freinant lgrement une roue et en acclrant l'autre. Les petites corrections sont donc bien plus douces. Par contre
si la ligne est dtecte par un des capteurs latraux (grande erreur) on braque en bloquant une roue et en acclrant l'autre. Ca fait
une embarde mais comme un des capteurs centraux passe trs vite sur la ligne, initiant le comportement "petite erreur",
l'embarde est assez vite lisse.
Le robot marche beaucoup mieux! Les lignes droites sont bien mieux ngocies et les tournants ne gnrent plus de perte de la
ligne intempestive... Dans un sens seulement. En effet, tout comme dans la version prcdente, le robot tourne trs bien droite
mais trs mal gauche (c'est invers puisqu'on a retourn le robot).
Aprs moult recherches dans le code, les branchements, les engrenages, j'ai fini par comprendre qu'un des moteurs tait plus
faiblard que l'autre et tournait moins vite avec la mme valeur de PWM. J'ai donc introduit une variable de trim pour galiser leur
vitesse.
Et enfin, j'ai eu un comportement efficace et cohrent dans les deux sens pendant toute une soire!
Et le lendemain matin, patatras... La ligne tait trs mal dtecte et le robot la perdait au premier tournant.
J'ai fini par me rendre l'vidence : moteurs trop bas de gamme, masse (plus de 800g) et donc inertie trop importante, je n'allais
pas m'en sortir avec ce matriel. J'ai donc recommenc.

Version 2

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

3 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

Le chssis
J'ai tout d'abord chang les moteurs. J'ai opt pour deux servos rotation continue : ce n'est pas cher et a marche trs bien, mme
si a n'atteint pas des vitesses bien grandes.
Exit galement la batterie NiMH, j'alimente dsormais l'ensemble avec un botier contenant 6 piles AA.
Ct chssis, il a bien rduit en taille. J'ai fait au plus simple : les servos sont colls avec du double-face sur une plaque qui
accueille galement le pack de piles sur lequel s'ajoute l'Arduino, le tout fix avec du velcro pour pouvoir tre transport d'un
projet l'autre.
Sur le dos de l'Arduino, un shield maison porte un rgulateur de tension LM317 dlivrant 6 volts pour alimenter les servos ainsi
que leurs deux connecteurs. Le LM317 est connect au pack de piles via une broche. On aurait peut-tre pu utiliser le Vin de
l'Arduino pour l'alimenter mais je n'ai trouv nulle part de renseignement fiable sur l'intensit maximale qui peut y passer, j'ai
donc jou la scurit.
A l'avant, on retrouve le capteur maison inchang avec ses quatre dtecteurs.
Au final la structure est plus simple et surtout plus lgre avec peine 400g, soit la moiti du poids de la version prcdente.
Le comportement
J'ai quelques dtails prs repris le comportement de la premire version.
Si un des capteurs centraux dtecte la ligne, on freine le moteur situ du mme ct pour recentrer. Si un des capteurs latraux voit
la ligne, on bloque compltement la roue pour corriger plus violemment. Petite amlioration, la roue reste bloque jusqu' ce qu'un
des capteurs centraux ait vu la ligne et prenne le relais avec la correction douce. Ainsi on s'assure que la ligne est toujours
recentre.
J'ai galement dot le robot de la capacit ngocier des croisements de ligne. Si les quatre capteurs voient la ligne en mme
temps, c'est qu'on est sur un croisement. Le robot continue alors tout droit jusqu' ce que les deux capteurs extrmes revoient le
blanc, indiquant qu'on est sorti du croisement. Le comportement par dfaut reprend alors son cours.
Comme le montre la vido en tte d'article, a marche merveille. Pour amliorer encore, on pourrait prendre des moteurs plus
rapides et un dtecteur 5 capteurs pour toujours dtecter la position exacte de la ligne.

Le code
La fonction "tourne" accepte deux arguments, la vitesse des moteurs gauche et droite. L'arrt correspond la valeur 90, la vitesse
maximum environ 105 dans un sens (j'ai pris 110 par scurit) et 75 dans l'autre sens. Comme les servos sont tte-bche et pour
simplifier la gestion des valeurs de vitesse dans le reste du code, on "retourne" la valeur envoye au servo droit avec la fonction
map().
#include <Servo.h> // bibliotheque servo
// capteurs
int
int
int
int

capteurDDroite = A2; // analog pin 2


capteurDroite = A3; // analog pin 3
capteurGauche = A4; // analog pin 4
capteurGGauche = A5; // analog pin 5

// valeurs des capteurs


int
int
int
int

droite = 0;
gauche = 0;
ddroite = 0;
ggauche = 0;

int seuil = 450; // seuil de dtection de la bande noire, rgler en fonction de la


luminosit ambiante

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

4 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

// servos
Servo myservo1;
Servo myservo2;

// cration de l'objet servo droit


// cration de l'objet servo gauche

// vitesses
int avance
= 110; // avance normale
int ralenti = 95; // vitesse pour tourner lentement
int stoppe = 90; // arret
void setup(){
// Serial.begin(9600);

// dmarrage port srie

// servo
myservo1.attach(9); // servo droite sur le pin 9
myservo2.attach(10); // servo gauche sur le pin 10
myservo1.write(stoppe); // on arrete les servos
myservo2.write(stoppe);
delay(5000); // petit dlai avant dmarrage
}
void loop(){
lecture();
while ((gauche <=seuil && droite <= seuil && ddroite <= seuil && ggauche <= seuil)){
// si tout est ok on avance
tourne(avance,avance);
lecture();
}
if(gauche >= seuil && droite >= seuil && ddroite >= seuil && ggauche >= seuil){ //
croisement
while (ddroite >= seuil || ggauche >= seuil){ // on attend que les capteurs
extremes soient nouveau dans le blanc
tourne(avance,avance);
lecture();
}
}

if (ggauche > seuil){ // si capteur extreme gauche on tourne a fond jusqu' ce que le
capteur central gauche ait rcupr la ligne
while (gauche < seuil) {
tourne(stoppe,avance);
gauche = analogRead(capteurGauche);
}
}
if (ddroite > seuil){ // // si capteur extreme droit on tourne a fond jusqu' ce que
le capteur central droit ait rcupr la ligne
while (droite < seuil) {
tourne(avance,stoppe);
droite = analogRead(capteurDroite);
}
}
if (gauche > seuil && ggauche <= seuil && ddroite <= seuil){ // si le capteur centre
gauche et lui seul voit la ligne on tourne doucement
tourne(ralenti,avance);

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

5 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

}
if(droite > seuil && ggauche <= seuil && ddroite <= seuil){ // si capteur centre droit
on tourne doucement
tourne(avance,ralenti);
}
}
void tourne(int vitesseGauche, int vitesseDroite) { // on transmet la vitesse de
rotation aux servos
vitesseDroite=map(vitesseDroite,180,0,0,180); // on inverse le sens de rotation du
servo droit
myservo1.write(vitesseDroite);
myservo2.write(vitesseGauche);
// Serial.print(vitesseGauche);
// Serial.print("\t");
// Serial.println(vitesseDroite);
}
void lecture(){ // on lit les capteurs
ggauche = analogRead(capteurGGauche);
droite = analogRead(capteurDroite);
gauche = analogRead(capteurGauche);
ddroite = analogRead(capteurDDroite);
}

8 ractions
1 De alex - 03/04/2012, 09:47
bonjour,
j'aimerais refaire le robot suiveur de ligne avec arduino mais je bloque sur la PWM, pourriez-vous me montrer votre
premier code avec la PWM, s'il vous plait ?
merci
dans l'attente de votre rponse
cordialement
2 De Vincent Becker - 03/04/2012, 20:04
Bonjour,
Voici le code pour la version PWM. Les moteurs sont commands par un module avec un pont en H qui utilise deux pins
par moteur : un en HIGH ou LOW (digitalWrite) pour le sens de rotation, et un en analogique (analogWrite) pour la vitesse
avec une valeur comprise entre 0 (stop) et 255 ( fond).
Comme mes moteurs taient de trs mauvaise qualit, j'ai introduit un trim appliqu aux valeurs envoyes la fonction
tourne() pour en acclrer un par rapport l'autre.
La fonction hardstop met les moteurs en marche arrire pendant 5ms pour arrter net et viter que le robot parte sur son
inertie.
Enfin, la fonction lancement() met brivement les moteurs fond en marche avant pour les faire dcoller aprs un arrt,
sinon il leur arrivait de se bloquer si on leur envoyait une vitesse lente.
Bref tout ceci s'est rsolu avec les servos rotation libre. Mais si vous avez de bons moteurs, le PWM peut tre trs
efficace.
// capteurs
int capteurDDroite = A2; //analog pin 0
int capteurDroite = A3; //analog pin 0
int capteurGauche = A4; //analog pin 1
int capteurGGauche = A5; //analog pin 1

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

int droite = 0; // valeurs des capteurs


int gauche = 0;
int ddroite = 0;
int ggauche = 0;
int seuil = 100; // seuil de dtaection de la bande noire
// moteurs
int moteurDroite = 6; // PWM Pin Motor 1
int PoMD = 7; // Polarity Pin Motor 1
int moteurGauche = 5; // PWM Pin Motor 2
int PoMG = 4; //Polarity Pin Motor 2
// vitesses
int trim = 30; // trim moteur gauche
int avance = 110; // avance normale
int deltaV = 35; // constante de variation de vitesse des moteurs pour chg de direction
int ralenti = avance-deltaV; // ralentissement pour tourner
int accelere = avance+deltaV; // acclration pour tourner
int demarrage = 255; // coup de pouce pour dcoller les moteurs aprs un arret
int stoppe= 1; // variable qui se rappelle si on s'est arret
int hardstopped = 0;
void setup(){
// Serial.begin(9600);
pinMode(moteurDroite, OUTPUT);
pinMode(PoMD, OUTPUT);
pinMode(moteurGauche, OUTPUT);
pinMode(PoMG, OUTPUT);
digitalWrite(PoMD, HIGH) ; // On met les moteurs en marche avant
digitalWrite(PoMG, HIGH) ;
/*
tourne(255,255); // on lance les moteurs
delay(2000);
tourne(0,0);
delay(2000);
*/
}
void loop(){
lecture();
/*
Serial.print(droite);
Serial.print("\t");
Serial.println(gauche);
Serial.print("\t");
Serial.println(gauche);
Serial.print("\t");
Serial.println(gauche);
delay(100);
*/
if (gauche <=seuil && droite <= seuil && ddroite <= seuil && ggauche <= seuil){ // si tout est ok on lance les moteurs si
ils sortent d'un arret et on avance
lancement();
tourne(avance,avance);
// lecture();
}

if (ggauche > seuil){ // si capteur extreme gauche on tourne a fond

6 sur 9

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

7 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

// hardstop(PoMG,moteurGauche);
tourne(0,accelere);
// ggauche = analogRead(capteurGGauche);
stoppe = 1;
}
if (ddroite > seuil){ // si capteur extreme droit on tourne a fond
// hardstop(PoMD,moteurDroite);
tourne((accelere+trim),0);
// ddroite = analogRead(capteurDDroite);
stoppe = 1;
}
if (gauche > seuil && ggauche <= seuil && ddroite <= seuil){ // si capteur centre gauche on tourne doucement pondr
par rapport aux capteurs extremes
lancement();
tourne((ralenti+trim),accelere);
// gauche = analogRead(capteurGauche);
// Serial.println("Droite");
// droite = analogRead(capteurDroite);
}
if(droite > seuil && ggauche <= seuil && ddroite <= seuil){ // si capteur gauche on tourne doucement
lancement();
tourne((accelere+trim),ralenti);
// droite = analogRead(capteurDroite);
// Serial.println("Gauche");
// gauche = analogRead(capteurGauche);
}
hardstopped = 0;
}
void lancement() {
if (stoppe == 1){
analogWrite(moteurDroite, demarrage);
analogWrite(moteurGauche, demarrage);
stoppe=0;
delay (5);
}
}
void hardstop(int polarite,int moteur){
if (!hardstopped){
digitalWrite(polarite, LOW) ; // On met les moteurs en marche arrire
analogWrite(moteur, demarrage);
delay (5);
digitalWrite(polarite, HIGH) ;
hardstopped = 1;
}
}
void tourne(int vitesseGauche, int vitesseDroite){
analogWrite(moteurDroite, vitesseDroite);
analogWrite(moteurGauche, vitesseGauche);
}
void lecture(){
ggauche = analogRead(capteurGGauche);
droite = analogRead(capteurDroite); // on lit les capteurs
gauche = analogRead(capteurGauche);
ddroite = analogRead(capteurDDroite);
}
3 De alex - 05/04/2012, 17:21

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

Merci beaucoup d'avoir rpondu aussi rapidement.


Une dernire question : je n'ai pas de module pont en H, puis-je raccorder les moteurs directement sur les pins 7,6,5,4 ??
Alexandre
4 De Vincent Becker - 08/04/2012, 11:17
Surtout pas! Vous allez dtruire votre Arduino. Les pins peuvent fournir au maximum 40 mA, vos moteurs vont demander
beaucoup plus et l'Atmega va griller.
Le pont en H permet de connecter les moteurs une alimentation extrieure. On en trouve des capables de donner 1 ou 2
ampres, il faut savoir ce que demandent vos moteurs et dimensionner en fonction.
De plus le pont en H permet de faire varier la direction de rotation des moteurs.
Sur la premire version j'ai utilis celui-ci:
http://www.zartronic.fr/module-cont... (http://www.zartronic.fr/module-contr%C3%B4leur-de-moteur-2a-l298p-43.html?zenid=44cf2093832a7d6d9f5cd048497bc339)
Si vous n'avez besoin que de la marche avant, vous pouvez vous contenter de simples transistors type TIP120 ou des
Mosfet (c'est la mme chose). C'est facile cbler et a ne cote presque rien :)
Un tutoriel (en anglais) ici :
http://itp.nyu.edu/physcomp/Tutoria... (http://itp.nyu.edu/physcomp/Tutorials/HighCurrentLoads)
Cordialement,
Vincent Becker
5 De alex - 08/04/2012, 13:02
merci beaucoup de vos explications, il ne me reste plus qu'a crer ce petit robot !
Si vous voulez je pourrais poster le rsultat sur votre site ?
encore merci
cordialement
6 De Vincent Becker - 08/04/2012, 15:48
Pourquoi pas! N'hsitez pas me tenir au courant de vos travaux :)
7 De alex - 19/04/2012, 17:48
bonjour,
j'ai ralis la platine capteur et branch les transistors l'arduino puis mis le tout sous tension.....et RIEN.
je pense que cela viens de la platine capteur, j'ai du mal raliser le schma de la plaque.
Pourriez-vous m'indiquer comment avez-vous realis votre montage des capteurs ?
De plus avec les transistors je n'ai plus besoin des pins 4 et 7 ? Les pins 6 et 5 suffisent ?
Encore dsoler pour le drangement.
Cordialement
8 De Vincent Becker - 20/04/2012, 14:22
Pour la platine, je me suis inspir de cette page qui montre comment brancher un QRD1114 sur une Arduino :
http://bildr.org/2011/03/various-pr... (http://bildr.org/2011/03/various-proximity-sensors-arduino/) Il suffit de les brancher
en parallle en les connectant chacun un pin.
Pour les servos, il vaut mieux utiliser les pins 9 et 10 : en effet la librairie Servo neutralise ces deux pins par dfaut, qu'on
y branche un servo ou pas. Autant les utiliser pour garder les autres pins libres!
Le mieux avant de brancher la platine capteur est d'essayer de faire tourner les servos tous seuls. Essayez avec un puis
avec deux. Une fois que a tourne, vous pourrez implmenter les capteurs.
Et en effet, vous n'avez besoin que d'un pin par servo : la valeur de PWM transmise au servo par le pin donne la vitesse et
le sens, avec l'arrt 90.
ArduTiger, un robot qui vite les obstacles - L'encodeur du pauvre

8 sur 9

31/07/2014 23:08

Un suiveur de ligne (encore avec Arduino) - Brico bidules

9 sur 9

http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...

Haut de page
Accueil Billets rcents
Archives

Google+

Facebook

Twitter

YouTube
Propuls par Dotclear

31/07/2014 23:08