Robot autonome à yeux ultrasoniques

Dans le marché des robots on trouve des robots commandables par des télécommandes; Mon objectif ici et de rendre ce robot autonome, avec 2 capteurs de distance à ultrasons pour lui permettre d’éviter les obstacles. Voir la vidéo!

Il était assez facile de le faire fonctionner et le croquis est assez simple, je vais le décrire ci-dessous, mais je vais d’abord élaborer sur le matériel.

MATÉRIEL

La carte MBoard est une carte Arduino de style Leonardo et à côté des deux pilotes de moteur, figurent des en-têtes pour les cartes nRF24L01, SDcard, XBee et Electronic Bricks. Ces fonctions reprennent toutes les broches d’E / S disponibles. Vous devez donc trouver dans la fiche technique comment accéder à ces broches dans les en-têtes ci-dessus. J’ai alimenté le tableau avec une batterie plomb-acide scellée 6V3Ah, ce qui donne beaucoup de puissance aux moteurs.

Chaque télémètre à ultrasons (type HC-SR04) nécessite 2 broches (déclencheur, écho); J’ai utilisé D0 et D1 disponibles sur l’en-tête UART et D2 et D3 disponibles sur l’en-tête IIC. Ces capteurs ont besoin de 5V; Malheureusement, le MBoard n’a que 3V3 disponibles sur les en-têtes, j’ai donc dû souder un fil au bas de la carte à un point 5V. J’ai connecté ce 5V à une planche à pain pour le partager.

J’ai ajouté 2 voyants rouges sur la carte de connexion pour indiquer quand chaque capteur à ultrasons observait un obstacle situé à moins de 10 cm, ainsi qu’une sonnerie pour émettre un bip avant de revenir en arrière. Pour ces sorties numériques, j’utilisais les en-têtes EB, qui sont connectés aux broches d’entrée analogique A0-A6, mais peuvent également être configurés pour une sortie numérique.

J’ai laissé le module nRF24L01 branché mais je ne l’ai pas utilisé pour ce projet.

Plus tard, j’ai déplacé les capteurs dans une position plus basse, entre le haut et la plinthe du robot.

LOGICIEL

Le schéma est assez simple: chaque boucle commence par 2 mesures ultrasonores (mises en œuvre en fonction des paramètres de la gâchette et de l’écho) en calculant distance1 et distance2. Je fixe un délai d’expiration pour le pulseIn à 6000 microsecondes, ce qui correspond à environ 100 cm; nous n’avons pas besoin de mesurer au-delà de cela.

Si les deux distances sont supérieures à 50 cm, continuez tout droit. si un obstacle se trouve à moins de 50 cm, éloignez-vous de l’autre côté.

Si l’une des distances est inférieure à 10 cm, allumez la LED correspondante (juste pour un avertissement visuel).

Continuez ce mouvement pendant 100 millisecondes, puis revenez au début de la boucle.

Si les deux mesurent moins de 10 cm, arrêtez les moteurs et faites marche arrière brièvement. Pour éviter d’entrer dans une boucle infinie, j’ai ajouté un élément aléatoire au mouvement inverse: soit l’inverse vers la gauche, la droite ou la droite.

Ci-dessous, mon croquis Arduino, identique à celui utilisé dans la vidéo:

/ * Plate-forme robot 2 roues motrices et tortues 
   Arduino Leonardo 
   Tom Tobback août 2015 
   broches: 
   EB0 A0 
   EB1 A1 
   EB2 A2 
   EB3 A3 
   EB4 A4 
   EB5 A5 
   D5 RX  
   D1 TX 
   D2 SDA iic 
   D3 SCL iic 
   D4 SDcard (pas d'épingle) 
   D5 nRF 
   D6 Moteur nRF 
   D7 Moteur IN1 
   D8 Moteur IN2 
   D9 Moteur nRF 
   D10 Moteur ENA 
   D11 Moteur ENB 
   D12 Moteur IN3 
   D13 Moteur IN4 
   D14 nRF 
   D15 nRF 
   D16 nRF

* / 
int in1 = 7;
int in2 = 8;
int in3 = 12;
int in4 = 13;
int ena = 10;
int enb = 11;

int trig1 = 3;
int echo1 = 2;
int trig2 = 0;
int echo2 = 1;
buzzer int = A0;
int led1 = A1;
int led2 = A2;

int left_pwm, right_pwm;
int max_speed = 200;          // sur 0-255 
int distance1, distance2;

void  setup () {
  
  pinMode (in1, OUTPUT );
  pinMode (in2, OUTPUT );
  pinMode (ena, OUTPUT );
  pinMode (in3, OUTPUT );
  pinMode (in4, OUTPUT );
  pinMode (enb, OUTPUT );
  pinMode (trig1, OUTPUT );
  pinMode (echo1, INPUT );
  pinMode (trig2, OUTPUT );
  pinMode (echo2, INPUT );
  pinMode (buzzer, OUTPUT );
  pinMode (led1, OUTPUT );
  pinMode (led2, OUTPUT );

  left_pwm = max_speed;
  right_pwm = max_speed;
  arrêt moteur ();
  
  Série . commencer (9600);
  Série . println ( "robot autonome v2 à 2 yeux" );
  pour ( int i = 0; i <3; i ++) {
     digitalWrite (buzzer, HIGH );
    digitalWrite (led1, HIGH );
    digitalWrite (led2, HIGH );
    délai (100);
    digitalWrite (buzzer, LOW );
    digitalWrite (led1, LOW );
    digitalWrite (led2, LOW );
    retard(100);
  }
}

 boucle vide () {
  
  distance1 = ultrason (trig1, echo1);
  Série . print ( "distance1,2 (cm): \ t" );
  Série . imprimer (distance1);
  Série . print ( "\ t" );
  distance2 = ultrason (trig2, echo2);
  Série . imprimer (distance2);
  Série . print ( "\ t" );
  
  si (distance1 <10) {
     digitalWrite (led1, HIGH );
  }  else {
     digitalWrite (led1, LOW );
  }
  si (distance2 <10) {
     digitalWrite (led2, HIGH );
  }  else {
     digitalWrite (led2, LOW );
  }
  
  if (distance1 <10 && distance2 <10) {       // si les deux côtés sont inférieurs à 10 cm, arrêtez et revenez en arrière
    arrêt moteur ();
    Série . println ( "Stop" );
    goback (500);                               // aléatoire gauche, droite, droite
  }
  autre
  { 
    if (distance1> 50 && distance2> 50) {     // rien à voir dans un rayon de 50 cm, vitesse maximale vers l'avant
      left_pwm = max_speed;
      right_pwm = max_speed;
    Série . println ( "Forward" );
    }
    autre 
    {
      if (distance1> distance2) {               // si quelque chose de moins de 50cm, éloigne-toi du plus proche
        left_pwm = 0;
        right_pwm = max_speed;
        Série . println ( "gauche" );
      }
      autre
      {
        left_pwm = max_speed;
        right_pwm = 0;
        Série . println ( "Right" );
      }        
    }
 
  move (left_pwm, right_pwm);
     
  }
    
  délai (100);
}

void motorstop () {      // arrêt du moteur en marche libre
  
  analogWrite (ena, 0);
  analogWrite (enb, 0);
  digitalWrite (sonnerie, HAUT );
  délai (300);
  digitalWrite (buzzer, LOW );

}

void  move ( int left, int right) {
  
  digitalWrite (in1, HIGH );
  digitalWrite (in2, LOW );
  analogWrite (ena, à gauche);
  
  digitalWrite (in3, HIGH );
  digitalWrite (in4, LOW );
  analogWrite (enb, right);
  
}

void goback ( int t) {             // recule du temps t, direction aléatoire
  
  digitalWrite (in1, LOW );
  digitalWrite (in2, HIGH );
  analogWrite (ena, max_speed * random (0,2));  // aléatoire 0 ou 1
  
  digitalWrite (in3, LOW );
  digitalWrite (in4, HIGH );
  analogWrite (enb, max_speed * random (0,2));  // aléatoire 0 ou 1        
  
  délai (t);
  
}


int ultrasonic ( int trig, int echo) {
  longue durée;
 int distance;
 digitalWrite (trig, LOW );                // trigger OFF 
 delayMicroseconds (2);                   
 digitalWrite (trig, HIGH );               // trigger ON 
 delayMicroseconds (10); 
 digitalWrite (trig, LOW );                // 
 durée de déclenchement OFF =  pulseIn (echo, HIGH , 6000);   // timeout de 6000us signifie que nous ne mesurons pas au-delà de 1 mètre, nous renverrons 0
 
 // Calculez la distance (en cm) en fonction de la vitesse du son (340,29 m / s) 
 distance = ( int ) (durée * 340,29L / 10000/2);
 si (distance == 0) distance = 100;      // temporisation, au - delà de la distance de 1 mètre 
 retour à distance;
}