Cette nouvelle version du robot est munie de 3 capteurs à ultrasons HC-SR04 situés côte à côte à l'avant du robot. Les deux capteurs situés sur les côtés sont légèrement inclinés vers l'extérieur, ce qui élargit encore un peu plus le champ de vision du robot.
En plus du champ de vision amélioré, l'ajout des deux capteurs supplémentaires permet de faire tourner le robot du bon côté: si un obstacle est détecté en avant à droite, mais pas à gauche, on fera tourner le robot vers la gauche, et vice-versa si un obstacle est détecté à gauche mais pas à droite.
Matériel
C'est le même matériel que la dernière fois, mais avec deux capteurs HC-SR04 supplémentaires: un châssis pour robot à deux roues motrices (chaque roue étant directement reliée à un motoréducteur), un Arduino Uno (en fait c'est un Duemilanove, mais peu importe), un contrôleur de moteur L293D, 3 sondes ultrasonores HC-SR04, 6 piles AA rechargeables NiMh pour alimenter les moteurs, et une pile de 9 V pour alimenter l'Arduino.
Circuit
Là encore, je n'ai rien changé aux branchements du robot initial, ce qui explique au moins partiellement l'utilisation quelque peu désordonnée des différentes pins de l'Arduino.
Le schéma ci-dessous indique les branchements du L293D à l'Arduino, aux deux moteurs et à son alimentation. Ne pas oublier de relier ensemble toutes les masses: le GND de l'Arduino, les 4 pins GND du L293D et la pin GND de chaque capteur HC-SR04 sont toutes reliées ensemble.
Il nous reste à brancher les pins qui permettent l'échange d'information entre chaque capteur ultrasonore et l'Arduino. Puisque les pins disponibles sur l'Arduino devenaient rares, j'ai décidé d'utiliser les pins A0, A1, A2 et A3 comme des entrées/sorties numériques plutôt que comme des entrées analogiques. C'est permis! Pour ce faire, il s'agit d'utiliser dans le sketch les fonctions digitalRead ou digitalWrite.
Capteur A (à droite)
Pin Trig à Arduino 12
Pin Echo à Arduino 11
Capteur B (au centre)
Pin Trig à Arduino A0
Pin Echo à Arduino A1
Capteur C (à gauche)
Pin Trig à Arduino A2
Pin Echo à Arduino A3
Le sketch:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************** | |
* | |
* Robot éviteur d'obstacle muni de trois capteurs à ultrasons HC-SR04. | |
* | |
* Comportement: Le robot avance en ligne droite, sauf s'il | |
* rencontre un obstacle, auquel cas il tourne sur place jusqu'à | |
* ce qu'il n'y ait plus d'obstacle devant lui. | |
* | |
* http://electroniqueamateur.blogspot.com/2014/04/robot-eviteur-dobstacles-version-20.html | |
* | |
****************************************************************/ | |
// définitions de constantes | |
#define motorPin1a 3 // Marche avant du premier moteur | |
#define motorPin1b 4 // Marche arrière du premier moteur | |
#define speedPin1 9 // pin d'activation L293D pour le premier moteur | |
#define motorPin2a 5 // Marche avant du deuxième moteur | |
#define motorPin2b 6 // Marche arrière du deuxième moteur | |
#define speedPin2 10 // pin d'activation L293D pour le deuxième moteur | |
// capteur à ultrasons: | |
#define trigPinDroite 12 | |
#define echoPinDroite 11 | |
#define trigPinCentre A0 | |
#define echoPinCentre A1 | |
#define trigPinGauche A2 | |
#define echoPinGauche A3 | |
// variables globales | |
int Mspeed = 0; // vitesse du moteur | |
int seuil = 30; // distance minimale pour laquelle on accepte un obstacle | |
long look (short capteur){ // évaluation de la distance de l'obstacle | |
long temps; | |
short trigPin, echoPin; | |
if (capteur == 0){ // capoteur de droite | |
trigPin = trigPinDroite; | |
echoPin = echoPinDroite; | |
} | |
if (capteur == 1){ // capoteur du centre | |
trigPin = trigPinCentre; | |
echoPin = echoPinCentre; | |
} | |
if (capteur == 2){ // capoteur de gauche | |
trigPin = trigPinGauche; | |
echoPin = echoPinGauche; | |
} | |
// Nous envoyons un signal haut d'une durée de 10 microsecondes, en sandwich | |
// entre deux signaux bas. Des ultrasons sont émis pendant que le signal est haut | |
digitalWrite(trigPin, HIGH); | |
delayMicroseconds(10); | |
digitalWrite(trigPin, LOW); | |
// Lors de la réception de l'écho, le module HC-SR04 émet | |
// un signal logique haut (5 v) dont la durée est égale au | |
// temps écoulé entre l'émission et la réception de l'ultrason. | |
pinMode(echoPin, INPUT); | |
temps = pulseIn(echoPin, HIGH); | |
return temps * 340/(2*10000); | |
} | |
void setup() { | |
// réglage des broches à output | |
pinMode(motorPin1a, OUTPUT); | |
pinMode(motorPin1b, OUTPUT); | |
pinMode(speedPin1, OUTPUT); | |
pinMode(motorPin2a, OUTPUT); | |
pinMode(motorPin2b, OUTPUT); | |
pinMode(speedPin2, OUTPUT); | |
pinMode(echoPinDroite, INPUT); | |
pinMode(trigPinDroite, OUTPUT); | |
digitalWrite(trigPinDroite, LOW); | |
pinMode(echoPinCentre, INPUT); | |
pinMode(trigPinCentre, OUTPUT); | |
digitalWrite(trigPinCentre, LOW); | |
pinMode(echoPinGauche, INPUT); | |
pinMode(trigPinGauche, OUTPUT); | |
digitalWrite(trigPinGauche, LOW); | |
} | |
void loop() { | |
long distanceDroite, distanceCentre, distanceGauche; | |
long previousDroite, previousCentre, previousGauche; | |
Mspeed = 700; // vitesse du moteur 0 à 1023 | |
distanceDroite = look(0); // y a-t-il un obstacle à droite? | |
distanceCentre = look(1); // y a-t-il un obstacle au centre? | |
distanceGauche = look(2); // y a-t-il un obstacle à gauche? | |
if (distanceDroite > seuil && distanceCentre > seuil && distanceGauche > seuil){ | |
// aucun obstacle détecté, donc marche avant: | |
analogWrite(speedPin1, Mspeed); | |
digitalWrite(motorPin1a, HIGH); | |
digitalWrite(motorPin1b, LOW); | |
analogWrite(speedPin2, Mspeed); | |
digitalWrite(motorPin2a, HIGH); | |
digitalWrite(motorPin2b, LOW); | |
delay(100); | |
} | |
else { // on a détecté un obstacle | |
// nouvelle vérification pour éviter les faux positifs | |
previousDroite = distanceDroite; | |
previousCentre = distanceCentre; | |
previousGauche = distanceGauche; | |
distanceDroite = look(0); // y a-t-il un obstacle à droite? | |
distanceCentre = look(1); // y a-t-il un obstacle au centre? | |
distanceGauche = look(2); // y a-t-il un obstacle à gauche? | |
if ((distanceDroite <= seuil) && (previousDroite)<= seuil ){ | |
// obstacle confirmé | |
if (distanceDroite < distanceGauche) { // on tourne à gauche | |
analogWrite(speedPin1, Mspeed); | |
digitalWrite(motorPin1a, HIGH); | |
digitalWrite(motorPin1b, LOW); | |
analogWrite(speedPin2, Mspeed); | |
digitalWrite(motorPin2a, LOW); | |
digitalWrite(motorPin2b, HIGH); | |
delay(110); | |
if (distanceGauche <= seuil){ // il y a aussi un obstacle proche à gauche | |
delay(700); // on continue de tourner un peu plus | |
} | |
} | |
else // l'obtacle à gauche est plus proche que l'obstacle à droite | |
{ | |
// on tourne assez longtemps vers la droite | |
analogWrite(speedPin1, Mspeed); | |
digitalWrite(motorPin1a, LOW); | |
digitalWrite(motorPin1b, HIGH); | |
analogWrite(speedPin2, Mspeed); | |
digitalWrite(motorPin2a, HIGH); | |
digitalWrite(motorPin2b, LOW); | |
delay(900); // tournons de façon significative | |
} | |
} | |
else if ((distanceGauche <= seuil) &&(previousGauche <= seuil)) { | |
// obstacle à gauche seulement, on tourne à droite | |
analogWrite(speedPin1, Mspeed); | |
digitalWrite(motorPin1a, LOW); | |
digitalWrite(motorPin1b, HIGH); | |
analogWrite(speedPin2, Mspeed); | |
digitalWrite(motorPin2a, HIGH); | |
digitalWrite(motorPin2b, LOW); | |
delay(100); | |
} | |
else if ((distanceCentre <= seuil) && (previousCentre <= seuil)){ | |
// mince obstacle droit devant, on tourne à droite | |
analogWrite(speedPin1, Mspeed); | |
digitalWrite(motorPin1a, LOW); | |
digitalWrite(motorPin1b, HIGH); | |
analogWrite(speedPin2, Mspeed); | |
digitalWrite(motorPin2a, HIGH); | |
digitalWrite(motorPin2b, LOW); | |
delay(90); | |
} | |
} | |
} | |
Comportement du robot:
Le robot tourne à gauche s'il perçoit la présence d'un obstacle en avant à droite, et il tourne à droite s'il perçoit la présente d'un obstacle en avant à gauche. Si l'obstacle est droit devant, il tourne à droite. Il n'est doté d'aucune mémoire, ce qui peut le rendre assez hésitant lorsqu'il arrive face à un coin de mur, mais le sketch induit juste assez d'asymétrie pour éviter que le robot se prenne dans une boucle sans fin. Il finit généralement par trouver une voie de sortie, même si ce n'est pas toujours de la façon la plus élégante et efficace!
Yves Pelletier (Twitter: @ElectroAmateur)
Yves Pelletier (Twitter: @ElectroAmateur)
Bonjour,
RépondreSupprimerAvez vous déjà testé un pan & tilt pour n'utiliser qu'un seul capteur ?
J'y ai pensé, mais je n'ai pas essayé.
SupprimerMerci pour cet article, il m'a bien aidé.
RépondreSupprimer