Piloter un robot Arduino esquivant les obstacles grâce au capteur à ultrasons.

Dans cet article nous voulons construire un robot mobile capable d’éviter des obstacles. Un petit robot qu’avancera toujours en ligne droite et que face à une barrière, tournera sur lui-même afin de l’éviter. Pour cela nous allons utiliser la plaque de Arduino UNO, un contrôleur de moteurs et un capteur de distance. Une fois réalisé le montage, on ajoutera quelques enseignes led.

Table de matières:

Éléments nécessaires pour ce projet.

  • Carte Arduino UNO ou équivalent.
  • Plaque d’essai ou mini-breadboard.
  • Module contrôleur de moteurs L298N.
  • Module HC-SR04, capteur à ultrasons et support.
  • Châssis robot Arduino 2WD.
  • 2 roues.
  • 1 roue universelle.
  • 2 moteurs réducteurs TT de double axe.
  • Interrupteur ON/OFF à 2 pins.
  • Porte-batteries et 4 piles AA pour alimenter la carte.
  • Batterie de 9V pour le contrôleur et les moteurs.
  • Cables, vis et écrous.
Éléments nécessaires pour ce projet.

Assemblage du robot.

On commence par le montage des moteurs, les assemblant dans leur supports en forme de T, au châssis de la voiture.

Placement des moteurs sur le châssis

Attention à l’image: les moteurs son placés dans la même direction, des deux côtés du châssis, et la petite roue du vélocimètre, est du côté intérieur du moteur.

On installe la roue universelle avec 4 écrous d’extension qui doivent se situer du côté inférieur du châssis.

Installation de la roue universelle sur le châssis

Ensuite, on ajoute le boitier à piles.

Placement du boitier à piles sur le châssis

Il n’y a pas d’endroit prédéterminé pour placer le porte-piles, les fixations que nous proposons sur l’image peuvent être modifiées.

On connecte, maintenant, l’interrupteur du côté supérieur et central du châssis et les deux roues.

Connexion de l'interrupteur au centre du châssis

Ensuite, on fixe la carte Arduino et le module contrôleur de moteurs cherchant la meilleure place pour les installer dans l’ espace que nous avons sur le châssis de la voiture. Dans l’image, nous avons fixée la carte avec deux écrous, et le module avec une seule vis. On peut utiliser quelques rondelles ou joints du côté inférieur de la voiture pour que la carte et le module soient plus stables.

 fixation de la carte Arduino et le module contrôleur de moteurs sur la voiture

Maintenant on connectera la carte et le contrôleur:

Les connexions INA et INB, utilisés pour contrôler la vitesse de chaque moteur, vont être reliés avec le pins PWM de la carte:

  • ENA -> pin 6
  • IN1 -> pin 2
  • IN2 -> pin 7
  • IN3 -> pin 4
  • IN4 -> pin 3
  • ENB -> pin 5

Cela fait, on connectera les moteurs au module L298N: il existe 4 connexions, dites OUT 1, OUT 2, OUT 3 et OUT 4. Dans notre cas, nous avons relié les cables du moteur droit avec les connexions OUT 1 (noir) et OUT 2 (rouge). Et les cables du moteur gauche sont connectés à OUT 3 (rouge) et OUT 4 (noir).

On va utiliser l’interrupteur que nous avions posé dans la partie centrale du châssis, pour couper l’énergie fournie par la pile de 9V aux moteurs et au module contrôleur. Pourtant, on doit connecter le cable rouge de la pile à l’interrupteur et le pin de l’interrupteur qui reste libre on le relie, avec un cable rouge aussi, à l’alimentation du module. Le cable noir de la pile on le connecte au pin central des trois qui sont disponibles dans le module. Ce cable doit, en plus, se relier avec une des connexion GND de la carte Arduino (dans l’image le cable noir de la pile de 9V se dédouble en un cable jaune – relié au pin central de module, et un cable violet – relié au pin GND de la plaque).

On utilisera le porte-batteries pour alimenter la carte Arduino.

Teston maintenant les moteurs:

Code:

// MOTEUR 1
int IN1 = 2;
int IN2 = 7;
int ENA = 6;
// MOTEUR 2
int IN3 = 4;
int IN4 = 3;
int ENB = 5;

void setup() {
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENB, OUTPUT);
}

void loop() {
  //avance();
  //recul();
  //droite();
  gauche();
}
void arret(uint16_t temps) {
  arreter();
  delay(temps);
}
void avance(){
 // MOTEUR 1 
  analogWrite (ENA, 150);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  // MOTEUR 2
  analogWrite(ENB, 150);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}
void recul(){
 // MOTEUR 1 
  digitalWrite(ENA, HIGH);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  // MOTEUR 2
  digitalWrite(ENB, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}
void droite(){
 // MOTEUR 1 
  analogWrite (ENA, 150);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  // MOTEUR 2
  analogWrite (ENB, 150);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}
void gauche(){
 // MOTEUR 1 
  analogWrite (ENA, 150);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  // MOTEUR 2
  analogWrite (ENB, 150);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}
void arreter(){
 // MOTEUR 1 
  digitalWrite(ENA, 0);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  // MOTEUR 2
  digitalWrite(ENB, 0);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

On essaye les fonctions avance, recul, droite, gauche. Si le sens de rotation des roues est correcte, bravo! sinon, pas grave, on doit réviser le code. Tenez compte que IN1 et IN2 sont les responsables du sens de rotation des moteurs, alors modifiant HIGH et LOW nous pouvons changer le sens de rotation.

Sur la partie frontale du châssis on fixera le capteur de distance utilisant un support visé ou une mini-breadboard qu’on peut coller sur le châssis.

fixation du module capteur de distance sur notre robot

Pour connecter le capteur on peut se servir d’une mini-plaque d’essai. On connectera le pin GND du capteur au pin GND de la carte Arduino à travers de la plaque d’essai, le pin VCC au pin de 5V aussi à travers de la plaque d’essai, le pin ECHO directement au pin 8 de Arduino et TRIG au pin 12 aussi directement.

Le code pour le fonctionnement du capteur:

#include <NewPing.h>
#define PIN_TRIG 12
#define PIN_ECHO 8
#define MAX_DISTANCIA 100
NewPing sonar(PIN_TRIG, PIN_ECHO, MAX_DISTANCIA);

On ajoute la bibliothèque NewPing.h, on établit quels pin digitaux vont se connecter à TRIG et ECHO. Ensuite on détermine la distance maximale du capteur et finalement, on crée l’objet sonar, du type NewPing.

Dans la fonction setup() on initialise la communication série:

Serial.begin(9600);

Dans la fonction loop(), on teste la distance que mesure le capteur:

delay(1000);
int temps = sonar.ping_median();
int distance = temps / US_ROUNDTRIP_CM;
// Imprimer le temps mesuré sur la console
Serial.print("Temps: ");
Serial.print(temps);
Serial.println(" microsecondes");
// Imprimer la distance mesurée sur la console
Serial.print("Distance: ");
// US_ROUNDTRIP_CM constante pour déterminer la distance. Convertir le temps en distance (0 = indique hors de portée)
Serial.print(distance);
Serial.println(" cm");

Téléversant le code on peut voir sur le moniteur série:

Schéma du cablage.

Cablage du projet pour piloter voiture évite-obstacles
Cablage du projet pour piloter voiture évite-obstacles

Nous avons réalisé ce montage et nous avons testé les moteurs et le capteur, tout fonctionne correctement.

Nous allons, ensuite, compléter notre code: le capteur de distance mesure continuellement le temps que le signal émis prend pour son retour au capteur; si le signal ne reviens pas, cela veut dire qu’il n’y pas d’obstacle devant et pourtant le robot avance librement. (Hors de portée est égal à 0)

if (distance > 0){

}else{
  avance();
}

Par contre, si nous recevons une donnée temporale, cela veut dire que le capteur a détecté un obstacle. Si celui-ci se trouve a moins de 30cm on fera tourner notre robot vers la droite; et on le fera reculer si l’objet est à moins de 20cm. Si la distance mesurée est égal ou majeur de 30cm, on a voie libre pour avancer.

if (distance > 0){
  if(distance < 30){
    if(distance < 20){
      recul();
      delay(200);
      arret(100);
    }else{
      droite();
      delay(400);
      arret(500);
    }
  }else{
    avance();
  }
 }else{
  avance();
}

Si on teste ce code on pourra constater que notre robot toujours reculera et tournera à droite face à un obstacle.

En plus, on peut le faire tourner à gauche aléatoirement de façon que le fait de sortir de l’impasse soit plus simple. Por le faire nous allons créer une variable afin d’enregistrer le nombre aléatoire.

long randomNumber;

Ensuite, on fera que le programme choisisse entre 1 et 2:

if (distance > 0){
  if(distance < 30){
    if(distance < 20){
      recul();
      delay(200);
      arret(100);
    }else{
      randomNumber = random(1,3);
      Serial.print("Le nombre aléatoire est = ");
      Serial.println(randomNumber);
      if (randomNumber == 1){
        gauche();
        delay(400);
        arret(500);
      }else{
        droite();
        delay(400);
        arret(500);
      }
    }
  }else{
    avance();
  }
 }else{
  avance();
}

Si on essaie ce nouveau code, on vera que quelques fois le robot tournera à droite et autres fois à gauche, de manière que le fait d’échapper de l’obstacle sera plus facile.

Enseignes lumineuses.

Une Led RGB peut nous informer sur la direction que notre robot est en train de suivre: rouge pour reculer, vert pour avancer, et bleu pour tourner.

Le nouveau montage:

Cablage avec module led RGB
Cablage avec module led RGB

Nous avons ajouté le module Led RGB sur la plaque d’essai et nous avons connecté ses pins de cette façon:

  • Le pin R est relié au pin 11 de la carte,
  • le pin G au pin 10,
  • B au pin 9,
  • et le GND au pin GND de Arduino à travers de la plaque d’essai.
fixation du module Led RGB et connexion avec la plaque

On ajoutera au code les instructions nécessaires pour le fonctionnement des enseignes lumineuses. Pour cela nous créons des constantes pour indiquer les pins correspondants:

const int PinLedRouge = 11;
const int PinLedVerte = 10;
const int PinLedBleue = 9;

Dans la fonction setup(), on les configure comme sorties:

pinMode(PinLedVerte, OUTPUT);
pinMode(PinLedRouge, OUTPUT);
pinMode(PinLedBleue, OUTPUT);

Nous déterminons les fonctions pour les couleurs:

void verte(){
  Serial.println("¡Verte!");
  digitalWrite(PinLedRouge, LOW);
  digitalWrite(PinLedVerte, HIGH);
  digitalWrite(PinLedBleue, LOW);
}
void rouge(){
  Serial.println("¡Rouge!");
  digitalWrite(PinLedRouge, HIGH);
  digitalWrite(PinLedVerte, LOW);
  digitalWrite(PinLedBleue, LOW);
}
void bleue(){
  Serial.println("¡Bleue!");
  digitalWrite(PinLedRouge, LOW);
  digitalWrite(PinLedVerte, LOW);
  digitalWrite(PinLedBleue, HIGH);
}

Dans la fonction loop(), on indique quel couleur doit s’allumer. Avant de l’appel à la fonction avance(), on allume la led verte; pour la fonction recule(), la led rouge; et pour les fonctions droite() et gauche(), la led bleue.

Code complet du projet.

#include <NewPing.h>
#define PIN_TRIG 12   // Pin de Arduino connecté au pin Trigger du capteur
#define PIN_ECHO 8   // Pin de Arduino connecté au pin Echo du capteur
#define MAX_DISTANCE 100  // Distance maximale à détecter en cm.
NewPing sonar(PIN_TRIG, PIN_ECHO, MAX_DISTANCIA);
// MOTEUR 1
int IN1 = 2;
int IN2 = 7;
int ENA = 6;
// MOTEUR 2
int IN3 = 4;
int IN4 = 3;
int ENB = 5;
long randomNumber;
const int PinLedRouge = 11;
const int PinLedVerte = 10;
const int PinLedBleue = 9;

void setup() {
  Serial.begin(9600);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(PinLedVerte, OUTPUT);
  pinMode(PinLedRouge, OUTPUT);
  pinMode(PinLedBleue, OUTPUT);
  randomSeed(analogRead(A0));  
}

void loop() {
  delay(1000);
  int temps = sonar.ping_median();
  int distance = temps / US_ROUNDTRIP_CM;
  // Imprimmer le temps mesuré sur la console
  Serial.print("Temps: ");
  Serial.print(temps);
  Serial.println(" microsecondes");
  // Imprimmer la distance mesurée sur la console
  Serial.print("Distance: ");
  // US_ROUNDTRIP_CM constante pour déterminer la distance. Convertir le temps en distance (0 = indique hors de portée)
  Serial.print(distance);
  Serial.println(" cm");
  /*  */
  if (distance > 0){  
    if(distance < 30){
      //arret();
      if(distance < 20){
        rouge();
        recul();
        delay(200);
        arret(100);
      }else{
        randomNumber = random(1,3);
        Serial.print("Le nombre aléatoire est = ");
        Serial.println(randomNumber);
        if (randomNumber == 1){
          bleue();
          gauche();
          delay(400);
          arret(500);
        }else{
          bleue();
          droite();
          delay(400);
          arret(500);
        }
      }
    }else{
      verte();
      avance();
      //delay(200);
      //arret(500);
    }
  }else{
    verte();
    avance();
  }
}
void arret(uint16_t tiempo) {
  arreter();  // arrete les moteurs
  delay(temps);        // On attent le temps que nous l'indiquons.
}

void avance(){
 // MOTEUR 1 
  analogWrite (ENA, 150);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  // MOTEUR 2
  analogWrite(ENB, 150);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}
void recule(){
 // MOTEUR 1 
  digitalWrite(ENA, HIGH);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  // MOTEUR 2
  digitalWrite(ENB, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}
void droite(){
 // MOTEUR 1 
  analogWrite (ENA, 150);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  // MOTEUR 2
  analogWrite (ENB, 150);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}
void gauche(){
 // MOTEUR 1 
  analogWrite (ENA, 150);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  // MOTEUR 2
  analogWrite (ENB, 150);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}
void arreter(){
 // MOTEUR 1 
  digitalWrite(ENA, 0);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  // MOTEUR 2
  digitalWrite(ENB, 0);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

void verte(){
  Serial.println("¡Verte!");
  digitalWrite(PinLedRouge, LOW);
  digitalWrite(PinLedVerte, HIGH);
  digitalWrite(PinLedBleue, LOW);
}
void rouge(){
  Serial.println("¡Rouge!");
  digitalWrite(PinLedRouge, HIGH);
  digitalWrite(PinLedVerte, LOW);
  digitalWrite(PinLedBleue, LOW);
} 
void bleue(){
  Serial.println("¡Bleue!");
  digitalWrite(PinLedRouge, LOW);
  digitalWrite(PinLedVerte, LOW);
  digitalWrite(PinLedBleue, HIGH);
}
Articles similaires
Laisser un commentaire