• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Faites réagir votre robot avec des capteurs

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Maintenant que votre robot est mobile, il va devenir important de savoir ce qu'il doit faire.

Un robot doit avoir une mission (même si elle paraît très simple) car c'est ce qui va guider votre construction, le choix de vos capteurs et votre programmation.

Nous avons vu dans le cours d’initiation à Arduino, plusieurs capteurs et la façon de les connecter et de les programmer.

Nous allons dans ce chapitre observer ces capteurs sous un autre angle : quel capteur va répondre à vos attentes ?

Je vais donc aborder plusieurs types de missions et voir comment équiper le robot en conséquence !

Bien sûr, un robot peut tenter de cumuler l'ensemble des missions, mais vous verrez que du coup, ce n'est pas si évident.

J'oriente ce chapitre sur un robot autonome mobile, avec une roue folle. Il dispose donc pour le moment de deux moteurs, de la carte Arduino (alimentée séparément) et donc de la possibilité d'avancer, de reculer, de tourner sur place (le tout plus ou moins rapidement).

Attaquons notre première mission...

Je contourne un obstacle que je touche

Alors pour éviter un obstacle que l'on touche, et bien il faut déjà se rendre compte qu’on l’a touché ! Il vous faut donc des capteurs de contact de type tout ou rien : soit je touche un obstacle, soit je ne le touche pas.

Le principe est simple : si le robot avance il doit pouvoir se rendre compte qu'il touche un obstacle.

Les microrupteurs sont tout indiqués pour cette mission. Mais où les placer ?

Je dirais que c'est le plus délicat ! En effet, en fonction de la forme de votre robot ou de l'obstacle, le point de contact n'est pas toujours au même endroit.

Le modèle "moustaches de chat"

Nous allons imiter le principe des moustaches qui servent au chat à détecter des objets. En effet si quelque chose touche la moustache du chat, il le sent (Non Lukas,  nous n’avons pas besoin de votre chat pour vérifier). De même, si le contact est à gauche ou à droite, il sait où se trouve l'obstacle.

Il vous suffit donc de placer des microrupteurs à l'avant de votre robot. Il vous en faudra au moins deux (pour différencier l'obstacle à droite et l'obstacle à gauche). Voici une plateforme qui montre un tel montage :

Les contacteurs à l'avant du robot agissent comme des moustaches (www.elektormagazine.fr)
Les contacteurs à l'avant du robot agissent comme des moustaches (www.elektormagazine.fr)

La limite de ce système est que si l'obstacle est fin et arrive exactement entre les deux moustaches, le robot ne va pas savoir qu'il est bloqué. On peut ruser en ajoutant une barre souple d'une moustache à l'autre qui, du coup, couvrira toute la zone. Il existe une petite construction qui permet d'affiner ce montage : le pare-choc.

Le pare-choc schématisé
Le pare-choc schématisé

La pièce noire est mobile verticalement sur l'axe vert et peut aussi pivoter à droite ou à gauche (point de pivot en bas de l'axe vert). Du coup, la zone couverte s'étend sur tout l'avant sur presque 180°. Le plus difficile est de concevoir une pièce qui déclenche bien les contacts en fonction de la zone touchée (contacteur gauche pour la gauche, contacteur droite pour la droite et les deux pour le centre) et qui revient à sa place ensuite. Il peut donc être utile d'ajouter de petits ressorts (au niveau de l'axe vert et des côtés) pour que la pièce reprenne sa position.

Voici un exemple :

Un pare-choc avant qui différencie droite, gauche et centre (http://www.clg-rondeau-rambouillet.ac-versailles.fr)
Un pare-choc avant qui différencie droite, gauche et centre (http://www.clg-rondeau-rambouillet.ac-versailles.fr)

Ce pare-choc n'est pas semi-circulaire, mais il suffit à répondre à l'objectif : différencier droite, gauche et centre.

Comment coder la réaction du robot ?

Votre programme doit être organisé correctement pour que ce soit clair. Il vous faut donc :

  • Créer des fonctions pour avancer et reculer (2 moteurs dans le même sens), tourner à droite ou à gauche (1 moteur dans un sens et l'autre en sens inverse, ou 1 moteur arrêté et l'autre en marche), et s'arrêter (2 moteurs à l'arrêt).

  • Connecter correctement vos microrupteurs pour repérer un contact éventuel, et  les repérer  par des noms de variable compréhensibles (ex: contactGauche et contactDroite).

Une fois que c’est fait, et bien le reste est assez simple... il suffit de penser à la place du robot : 

  • Si je sens un contact à droite, c'est que l'obstacle est à droite. Je m'arrête, je recule pendant un temps donné, je tourne à gauche pendant un temps donné, puis j'avance à nouveau.

  • Si je sens un contact à gauche, c'est que l'obstacle est à gauche. Je m'arrête, je recule pendant un temps donné, je tourne à droite pendant un temps donné, puis j'avance à nouveau.

  • Si je sens un contact à droite et à gauche, c'est que l'obstacle est devant. Je m'arrête, je recule pendant un temps donné, je tourne à droite (ou à gauche) pendant un temps donné, puis j'avance à nouveau.

C'est tout ! Du coup, si vos fonctions sont claires, le code sera très lisible ! Voici un exemple en pseudo code :

//initialisation des variables
//on définit les pin pour chaque contact
int contactGauche = 3; //microrupteur connecté au pin 3 en mode pull-up
int contactDroite = 4; //microrupteur connecté au pin 4 en mode pull-up
void setup() {
  pinMode(contactGauche, INPUT_PULLUP); //pas d'utilisation de résistance externe
  pinMode(contactDroite, INPUT_PULLUP); //idem
  avance();
}
void loop() {
  // les pins mode INPUT_PULLUP, on va donc les lire en inversant leur valeur pour que les tests soient plus clairs
  boolean toucheGauche = !digitalRead(contactGauche); //on créé un variable d'état en inversant la valeur du pin
  boolean toucheDroite = !digitalRead(contactDroite); //on créé une autre variable en inverant aussi sa valeur
  if (toucheGauche && toucheDroite) { // contact au centre
    arret();
    delay(500);
    recule();
    delay(1000);
    tourneDroite();
    delay(1000);
    avance();
  }
  else if (toucheGauche && !toucheDroite) { // contact à gauche
    arret();
    delay(500);
    recule();
    delay(1000);
    tourneDroite();
    delay(1000);
    avance();
  }
  else if (!toucheGauche && toucheDroite) { // contact à droite
    arret();
    delay(500);
    recule();
    delay(1000);
    tourneGauche();
    delay(1000);
    avance();
  }
  delay(100); //attente pour bien repérer le contact au centre éventuel
}
//fonctions de mouvement de la plateforme
void arret() {
  //commande d'arrêt des deux moteurs
}
void avance() {
  //commande pour faire tourner les deux moteurs dans le même sens
}
void recule() {
  //commande pour faire tourner les deux moteurs dans le même sens mais en  arrière
}
void tourneDroite() {
  //commande pour faire tourner un moteur dans un sens et l'autre dans le sens inverse afin que la plate-forme tourne à droite
}
void tourneGauche() {
  //commande pour faire tourner un moteur dans un sens et l'autre dans le sens inverse afin que la plate-forme tourne à gauche
}

Ce programme vous semble complètement indéchiffrable ? Il vous manque encore quelques bases de programmation, je vous conseille de reprendre mon cours d’initiation à Arduino pour y voir plus clair.

Notez que je n’ai pas écrit le programme de chaque fonction dirigeant le mouvement du robot (avance(),  recule(), etc.), l’objet de ce chapitre étant plutôt de ce concentrer sur le programme global et l’interaction avec les capteurs. Vous pouvez les construire en vous référant au cours d'initiation (chapitre sur les moteurs) avec l'utilisation d'un L293D, ou bien voir comment créer de telles fonctions avec un shield moteur dans un prochain chapitre !

Vous pouvez tester sur votre plateforme, le robot va agir comme sa mission le lui demande ! C'est-y-pas-merveilleux ?!

Si vous n'avez pas de plateforme encore construite ou si vous souhaitez vérifier le bon fonctionnement de votre code, voici un moyen de suivre le déroulement du programme. Pour le montage, vous connectez deux boutons poussoir sur les pins 3 et 4 de l'Arduino en mode pull-up. En appuyant sur celui de droite, celui de gauche ou les deux, vous devriez obtenir la bonne séquence d'affichage sur la console série.

//initialisation des variables
//on définit les pin pour chaque contact
int contactGauche = 3; //microrupteur connecté au pin 3 en mode pull-up
int contactDroite = 4; //microrupteur connecté au pin 4 en mode pull-up

void setup() {
  Serial.begin(9600);
  pinMode(contactGauche, INPUT_PULLUP); //pas d'utilisation de résistance externe
  pinMode(contactDroite, INPUT_PULLUP); //idem
  avance();
}

void loop() {
  // les pins mode INPUT_PULLUP, on va donc les lire en inversant leur valeur pour que les tests soient plus clairs
  boolean toucheGauche = !digitalRead(contactGauche); //on créé une variable d'état en inversant la valeur du pin
  boolean toucheDroite = !digitalRead(contactDroite); //on créé une autre variable en inversant aussi sa valeur
  if (toucheGauche && toucheDroite) { // contact au centre
    Serial.println("Je touche au centre");
    arret();
    delay(500);
    recule();
    delay(1000);
    tourneDroite();
    delay(1000);
    avance();
  }
  else if (toucheGauche && !toucheDroite) { // contact à gauche
    Serial.println("Je touche a gauche");
    arret();
    delay(500);
    recule();
    delay(1000);
    tourneDroite();
    delay(1000);
    avance();
  }
  else if (!toucheGauche && toucheDroite) { // contact à droite
    Serial.println("Je touche a droite");
    arret();
    delay(500);
    recule();
    delay(1000);
    tourneGauche();
    delay(1000);
    avance();
  }
  delay(100);
}
//fonctions de mouvement de la plateforme
void arret() {
  Serial.println("Je m'arrete");
  //commande d'arrêt des deux moteurs
}
void avance() {
  Serial.println("J'avance");
  //commande pour faire tourner les deux moteurs dans le même sens
}
void recule() {
  Serial.println("Je recule");
  //commande pour faire tourner les deux moteurs dans le même sens mais en  arrière
}
void tourneDroite() {
  Serial.println("Je tourne a droite");
  //commande pour faire tourner un moteur dans un sens et l'autre dans le sens inverse afin que la plate-forme tourne à droite
}
void tourneGauche() {
  Serial.println("Je tourne a gauche");
  //commande pour faire tourner un moteur dans un sens et l'autre dans le sens inverse afin que la plate-forme tourne à gauche
}

Ce genre de code vous permet de vérifier (ou de débugger) votre programme sans avoir à tout connecter.

Ce modèle “moustaches de chat” a-t-il des limites ?

(Je vois que vous suivez Cunégonde, toujours la petite question qui pique )

Oui évidemment ! Je vous dresse une petite liste des problèmes probables :

  • L'obstacle est en hauteur ou trop bas pour toucher les moustaches ou le pare-choc. Vous voyez alors votre robot rentrer bêtement dedans et s'obstiner à avancer, quitte à arracher tout son matériel (fils et autres), et vous vous précipiterez pour le tirer de là (ha les parents !).

  • Votre robot évolue sur un plan en hauteur (genre table du salon). Il ne va pas détecter le vide qui s'approche et qui le menace. Si vous ne réagissez pas assez vite, il va tomber (bêtement encore) et sûrement se casser un truc ou pire...

  • Il est programmé pour que lorsqu'il touche un objet, il recule avant de tourner. En théorie, il retourne d'où il est passé sans encombre. Mais si votre chien, chat, petite soeur passe à ce moment, le robot le/la percutera (oui Lukas, ça marche aussi avec une grand-mère) ce qui provoquera une réaction improbable du sujet percuté. Le robot lui continuera son processus (j'allais dire bêtement ;) ).

C'est la raison pour laquelle les robots doivent avoir des missions précises dans un environnement précis. C'est plus sûr pour tout le monde !

Voyons maintenant une mission un peu plus difficile...

J'évite les obstacles sans les toucher

Voilà qui est plus ardu. Sans toucher veut dire que l'on doit pouvoir détecter un obstacle à distance et évaluer à quelle distance on se trouve de l'obstacle. Nous avons deux sortes de capteurs qui peuvent répondre à nos besoins. Il fonctionnent sur le même principe : capter un écho.

  • Le premier est le capteur infrarouge, qui va capter la lumière infrarouge qui rebondit sur l'obstacle.

  • Le second est le capteur à ultrasons, qui va capter un son qui rebondit sur un obstacle.

Le capteur de distance à infrarouge

Nous avons vu dans le cours d'initiation comment utiliser une photodiode (ou diode réceptrice infrarouge), voyons maintenant comment l'utiliser comme capteur de distance.

Il nous faut réaliser un montage qui envoie de la lumière infrarouge et qui la capte, dans le même temps. Voici le schéma de principe :

Principe de la détection de distance par réflexion de lumière infrarouge
Principe de la détection de distance par réflexion de lumière infrarouge

L'idéal est de prévoir une petite séparation entre la diode émettrice et la réceptrice, pour éviter qu'elles ne se "voient" directement (entourer la photodiode d'un petite tube en plastique noir genre paille est largement suffisant).

Voici un capteur de distance infrarouge tout fait :

Un capteur de distance infrarouge du commerce (www.robotshop.com)
Un capteur de distance infrarouge du commerce (www.robotshop.com)

Plus l'obstacle va être proche, plus la quantité de lumière infrarouge renvoyée par l'obstacle va être importante, donc plus la tension captée et numérisée par le CAN A0 va avoir une valeur élevée. Pour résumer, plus la valeur captée par A0 est élevée, plus l'objet est proche. Il suffit donc ensuite de programmer le robot pour qu'il agisse en fonction de la distance de l'objet. Nous allons le voir un peu plus loin.

Ça marche sur toutes sortes d'obstacles ? Parce que je croyais que le noir absorbait les ondes lumineuses ?

(Ha sacré Cunégonde ! Vous ne lâchez rien hein ?)

Alors en effet, il y a deux principaux inconvénients avec ce capteur :

  • La distance mesurable reste faible (environ 10 cm si le capteur est bien conçu) ce qui limite la vitesse de votre robot. En effet s'il arrive trop vite sur l'obstacle et que le capteur n'a pas eu le temps d'analyser la distance, vous risquez le choc.

  • La couleur de l'obstacle agit sur la distance mesurable. En effet, un objet de couleur noire ne va quasiment rien réfléchir, donc ne sera pas détecté par votre capteur (Lukas, rassurez-vous, même si vous ne réfléchissez pas souvent, vous seriez vus par le capteur).

Le cône de réception (la zone de détection) fait que votre robot pourra capter la présence d'un objet légèrement au-dessus ou en-dessous du capteur. C'est donc un peu mieux qu'une moustache. Mais pour une détection optimale, il faudrait presque trois capteurs (devant, devant-droite et devant-gauche) donc trois pins analogiques utilisés...

Évidemment, pour trouver le placement le plus efficace pour votre capteur, il vous faudra faire plusieurs tests et ajustements.

Avant de voir le code type, passons au capteur à ultrasons.

Le capteur de distance à ultrasons

Nous avons abordé dans le cours d'initiation ce capteur (SRF05) et les calculs de distances qui y sont liés. C'est d'ailleurs la grande différence entre le capteur de distance à  infrarouge (dont il est assez difficile de paramétrer une mesure de distance précise) et le capteur à ultrasons qui permet presque d'obtenir une mesure au centimètre (à condition que l'obstacle se situe entre 5cm et 150 cm, au-delà de ces limites la fiabilité diminue).

Le cône de détection est aussi plus important que le capteur infrarouge (entre 30 et 60° vers la zone concernée). Le robot détecte donc des objets plus haut, plus à droite, plus à gauche et plus bas.

Plusieurs méthodes de programmation sont possibles :

  • Soit on procède comme nous allons le voir ensuite, c'est-à-dire en réalisant une mesure régulière.

  • Soit on procède comme la chauve-souris (non Lukas, on ne dort pas la tête en bas) c'est-à-dire que plus on capte que l'objet se rapproche, plus on fait des mesures rapprochées dans le temps, et plus il s'éloigne, plus on espace les mesures. Cette méthode libère du temps processeur mais risque de ne pas détecter un objet qui surgirait dans le champs. Mais comme nos robots évoluent dans un milieu protégé...

Il est tout à fait possible de monter le capteur sur un servo-moteur, afin qu'il scanne de droite à gauche pendant qu'il roule en ligne droite. Ou bien, lors de l'approche d'un obstacle, plutôt que faire tourner le robot, on fait juste tourner la "tourelle" du capteur pour chercher le meilleur chemin.

Voyons maintenant le programme type permettant au robot d’éviter un obstacle, qu’il l’ait détecté à distance avec un capteur à infrarouge ou à ultrasons.

Programme d'évitement d'obstacle sans contact

La structure de ce programme est globalement la même pour le capteur infrarouge et pour le capteur à  ultrasons. Voici le principe :

  • Je roule tout droit (en mesurant)  tant que tout va bien.

  • Je détecte que je m'approche d'un obstacle.

  • Je ralentis (facultatif, mais permet d'observer si l'obstacle persiste ou s'il disparaît).

  • Je détecte que l'objet est trop près de moi, je m'arrête.

  • Je recule un peu (facultatif, mais permet de ne pas toucher pendant les rotations).

  • Je tourne sur moi-même (ou fais pivoter ma tourelle) à droite puis à gauche pour chercher un passage (mesure d'une distance assez grande).

  • Là, deux possibilités de programme : Soit je m'engage dans le passage dès que je le trouve, soit je m'engage dans le passage le "plus libre" (ce qui nécessite de stocker les mesures effectuées en fonction de la position, puis de s'orienter correctement).

  • Je reprends ma route.

Il vous faut donc créer des fonctions de mouvement (on peut ajouter une notion de vitesse en paramètre) comme pour les moustaches. Il est toujours préférable de créer une fonction de mesure de distance (qui renvoie soit une distance, soit un état, par exemple : ok, proche, stop).

Voici un exemple de code. Il utilise le capteur SRF05. J'ai ajouté la communication avec le moniteur série pour les tests, elle est bien sûr facultative (mais bien pratique pour tester son programme ;)) :

#define PROCHE 20
#define DANGER 10
#define AFOND 200
#define PRUDENT 50
#define NBMESURE 5
#define VSON 59
//initialisation
int pinSRF=2; //pin numérique utilisé pour le capteur ultrasons.

void setup() {
  Serial.begin(9600);
  avance(AFOND); //on démarre le robot
}

void loop() {
  switch (mesure()){ //utilisation de la condition switch
    case 0: //l'obstacle est dans la zone DANGER
      Serial.println("*DANGER*");
      arret(); // on arrête le robot
      delay(200);
      recule(PRUDENT); // on le fait reculer un peu
      delay(200);
      recherche(); // on recherche la bonne voie
      break;
    case 1: //l'obstacle est dans la zone PROCHE
      Serial.println("Attention...");
      avance(PRUDENT); // on ralentit la vitesse
    default:
      avance(AFOND);
  }
}
//fonctions
int mesure(){
  //fonction qui mesure une distance avec le capteur
  unsigned long mesure = 0; // variable de mesure
  unsigned long cumul = 0; //variable pour la moyenne
  for (int t = 0; t < NBMESURE; t++) { // boucle pour effectuer les mesures
    pinMode (pinSRF, OUTPUT); //on prépare le pin pour envoyer le signal
    digitalWrite(pinSRF, LOW); //on commence à l'état bas
    delayMicroseconds(2); //on attend que le signal soit clair
    digitalWrite(pinSRF, HIGH);//mise à l'état haut
    delayMicroseconds(10); //pendant 10 µs
    digitalWrite(pinSRF, LOW); //mise à l'état bas
    pinMode(pinSRF, INPUT); //on prépare le pin pour recevoir un état
    mesure = pulseIn(pinSRF, HIGH); // fonction pulseIn qui attend un état haut et renvoie le temps d'attente
    cumul+=mesure; //on cumule les mesures
    delay(50); //attente obligatoire entre deux mesures
  }
  mesure=cumul/NBMESURE; //on calcule la moyenne des mesures
  mesure=mesure/VSON;//on transforme en cm
  
  if (mesure<=DANGER){//on teste si l'obstacle est dans la zone DANGER
    return 0; //si oui, on retourne le code de danger
  }
  else if (mesure>DANGER && mesure<=PROCHE){//on teste s'il est dans la zone PROCHE
    return 1; //si oui, on retourne le code de proche
  }
  return 2; // on retourne le code de sans risque
}
void recherche(){
  //fonction pour rechercher un passage
  tourneGauche(AFOND); //on positionne le robot à gauche (facultatif)
  delay (300);
  int etat=0; //variable de test de possibilité d'avancer
  while (etat!=2){ // tant que la distance n'est pas suffisante
    etat=mesure(); // on effectue la mesure
    tourneDroite(PRUDENT); //on fait tourner le robot
  }
  Serial.println("La voie est libre !");
  //retour au programme principal
}
void arret(){
  Serial.println("Je stoppe");
  //fonction d'arrêt des moteurs
}
void avance(int v){
  Serial.print("J'avance");
  affiche(v);
  //fonctin de mise en route des deux moteurs dans le sens avant
  // on utilise la variable v pour le pilotage PWM
}
void recule(int v){
  Serial.print("Je recule");
  affiche(v);
  //fonctin de mise en route des deux moteurs dans le sens arrière
  // on utilise la variable v pour le pilotage PWM
}
void tourneDroite(int v){
  Serial.print("Je tourne a droite");
  affiche(v);
  //fonction de rotation à droite : un moteur dans un sens, l'autre dans le sens opposé
  // on utilise la variable v pour le pilotage PWM
}
void tourneGauche(int v){
  Serial.print("Je tourne a gauche");
  affiche(v);
  //fonction de rotation à gauche : un moteur dans un sens, l'autre dans le sens opposé
  // on utilise la variable v pour le pilotage PWM
}
void affiche(int v){
  //fonction complémentaire d'affichage
  if (v==AFOND){
    Serial.println(" a fond !");
  }
  else{
    Serial.println(" prudemment...");
  }
}

Ce code ne contient pas les commandes pour les moteurs, je vous laisse le faire .

J'attire tout de même votre attention sur le début du programme. Vous y trouvez la directive (car ce n'est pas une fonction) #define . C'est une directive qui permet de fixer des noms de constantes. Il faut penser à bien écrire les constantes en majuscule pour un meilleur repérage dans le code. On l'utilise comme suit :

#define NOMDECONSTANTE VALEUR

Lors de la compilation, à chaque fois que l'IDE trouvera NOMDECONSTANTE dans le code, il le remplacera par la valeur. Du coup, pas d'utilisation de mémoire dynamique ! Vous rencontrerez souvent cette directive dans les programmes (et ce, dans plusieurs langages !). N'hésitez pas à l'utiliser.

Bon, vous avez maintenant un robot qui évite les obstacles sans les toucher. Que pourrait-il faire d'autre ?

Je suis une ligne noire sur le sol

Ha ben oui ! En voilà une bonne idée !

(Non Lukas, le titre ne veut pas dire qu'il faut s'habiller en noir et s'aplatir par terre, il s'agit du verbe suivre !)

Comment notre robot peut-il réaliser ce tour de force ? Et bien rappelez-vous que la couleur noire réfléchit très mal la lumière.

Ben on peut utiliser une photodiode infrarouge alors ?

(Oui Cunégonde, mais la prochaine fois, laissez-moi le temps de le dire !)

En effet, notre problème de tout à l'heure devient une solution. En utilisant notre capteur de distance infrarouge et en le dirigeant vers le sol, nous obtiendrons une mesure très faible lorsque l'infrarouge rebondira sur du noir, et une mesure plus forte sur d'autres couleurs. Pour une efficacité totale, la couleur blanche est conseillée.

Comment va fonctionner un tel programme ?

Tout d'abord, ça dépend du matériel de l'épaisseur de la ligne.

Deux capteurs, ligne épaisse (plus de 5 cm)

C'est le cas le plus simple. Vos deux capteurs sont au dessus de la ligne. Ils renvoient chacun une valeur faible. Si en avançant, le robot s'éloigne de la ligne, l'un des deux capteurs va le remarquer.

Donc si une valeur forte est renvoyée par le capteur de droite, c'est qu'on quitte la ligne par la droite, on doit donc tourner à gauche. À l'inverse, une valeur forte renvoyée par le capteur de gauche signifie qu'il faut aller à droite.

On ajuste donc le mouvement dans la direction opposée du capteur qui détecte la sortie.

Si les deux capteurs envoient en même temps une valeur forte, on vient de sortir de la ligne en allant tout droit. Il faut faire demi-tour et chercher le passage.

Deux capteurs, ligne fine (de 5mm à 1 cm)

C'est déjà plus compliqué. Si la ligne est fine, il faut que les capteurs se situent de part et d'autre de celle-ci.

On teste cette fois-ci la chute de valeur (donc survol de la ligne noire).

Si le capteur de gauche "voit" la ligne noire, c'est qu'on se décale vers la droite et inversement, si le capteur de droite "voit" la ligne noire, c'est qu'on se décale à gauche. Donc on ajuste dans la direction du capteur qui repère la ligne.

Si les deux capteurs "voient" la ligne en même temps, c'est qu'on est à une intersection. Il faudra donc trouver un moyen de se retrouver avec une seule ligne entre les deux capteurs.

Il est important dans cette configuration, de faire vérifier au robot qu'il a bien une ligne noire entre ses deux capteurs (avec une rotation vers la droite, puis la gauche), sinon il pourrait quitter la ligne sans s'en apercevoir et aller batifoler n'importe où... ;)

Un capteur, une ligne de taille minimum (au moins 2 cm)

Là c'est plus difficile. Ça ne peut fonctionner qu'en contrôlant qu'on est sur la ligne. 

Tant que le capteur reçoit une valeur basse (il voit la ligne) tout est ok.

S'il reçoit une valeur haute, c'est qu'il vient de quitter la ligne. Le problème c'est qu'on ne sait pas de quel côté. Il faut dont stopper et faire un balayage droite/gauche pour la retrouver et le remettre en route.

Le mouvement du robot sera moins fluide, plus saccadé. Mais il réussira tout de même sa mission !

Les contraintes pour la construction

Pour que les données reçues soient claires (valeur haute hors ligne et valeur basse sur la ligne), il faut que le capteur soit situé à bonne distance du sol. C'est un réglage important à faire. Trop proche et la lumière infrarouge ne rebondira pas vers le capteur. Trop éloigné et le capteur donnera des variations trop faibles pour une analyse correcte. L'idéal c'est de concevoir un montage avec un capteur facilement réglable en hauteur.

L'autre point découle du premier. Le capteur étant proche du sol, le robot ne pourra pas se permettre d'évoluer dans un environnement chaotique. Bref, il faut que la zone soit plate et sans obstacles.

J'en profite pour vous montrer un nouveau composant qui est très efficace pour le suivi de ligne noire : le CNY70.

Le CNY70. Emetteur/récepteur infrarouge (http://5hertz.com)
Le CNY70. Émetteur/récepteur infrarouge (http://5hertz.com)

Il a l'air gros comme ça, mais il est tout petit (moins d'1 cm de côté) et il ne coûte par cher (1 à 3€). On le trouve facilement dans les magasins d'électronique ou sur des sites de vente en ligne (il suffit de taper sa référence dans un moteur de recherche). Voici comment le connecter à votre Arduino :

Connexion du CNY70 à l'Arduino
Connexion du CNY70 à l'Arduino

Le repérage des pattes est simple du fait de la différence de couleur.

Il faut le placer assez près du sol pour de bonnes mesures, mais vu le prix, ça vaut le coup de se faire un robot double capteur !

En résumé

Nous venons de voir trois missions données à un robot :

  • Éviter un obstacle après être entré en contact avec (grâce aux micro-rupteurs) ;

  • Éviter un obstacle avant la collision (en utilisant un capteur infrarouge ou à ultrasons) ;

  • Suivre une ligne noire sur le sol (grâce aux capteurs infrarouges).

Sommes-nous à la fin des missions ?

Bien sûr que non, il est possible de réaliser bien des choses avec des robots mobiles suffisamment équipés en capteurs. D'ailleurs rien ne vous empêche de cumuler plusieurs sortes de capteurs !

Le plus compliqué reste les réglages et la programmation. Mais si vous avez un objectif clair, c'est bien plus simple.

Voici quelques exemples de missions à réaliser :

  • Le robot ne tombe pas de la table sur laquelle il se trouve (difficile).

  • Le robot se dirige vers une source de lumière (assez facile avec une photo-résistance, vue dans le cours d'initiation).

  • Le robot prend et déplace des objets (il faut lui prévoir une sorte de pince et un moyen de détecter qu'il peut prendre un objet. Il faut aussi qu'il différencie mur et objets à prendre ;)).

  • Le robot se dirige vers une source de lumière en restant sur une ligne noire et en évitant des obstacles sans les toucher (réalisable avec vos connaissances, mais nécessite une grosse organisation du programme !).

  • Le robot "rebondit sur une ligne noire" (pratique pour délimiter des zones d'action ou des labyrinthes).

  • Le robot cherche une ligne noire et la suit (pratique pour un retour à la base).

Je vous laisse inventer la suite !

Bien, nous avons fait le tour de ce que je souhaitais aborder concernant l'utilisation des capteurs avec un robot mobile. Nous allons maintenant apprendre à utiliser notre premier shield : un shield moteur !

Exemple de certificat de réussite
Exemple de certificat de réussite