Accès rapide :
La vidéo
Présentation de la LegoduinoCar
Les principaux composants électroniques
Le cablage de la carte Arduino
Le programme de contrôle
Pour aller plus loin...
Cette vidéo vous montre comment construire un petit véhicule autonome à base de composants électroniques Arduino et de briques de construction. Un programme de déplacement autonome du véhicule est proposé. Il peut aussi être piloté par Bluetooth ou par télécommande infrarouge.
La Legoduino est un petit véhicule autonome géré par une carte Arduino. Il peut aussi être controllé soit par bluetooth, soit par télécommande infra-rouge. Il a été fabriqué par les jeunes du club d'informatique de Valderoure (petite commune française).
La structure est basée sur des briques de construction célèbres que vous aurez certainnement reconnu. Peut-être en avez vous déjà un peu chez vous. Sinon, vous pouvez même commander les pièces sur ce site. Il en va de même pour les moteurs qui sont produits par le même frabriquant de jouets.
Le véhicule peut très facilement avancer ou reculer, tant que les deux rouges motorisées tournent dans le même sens. Il peut aussi effectuer des rotations sur lui même, dans un sens ou dans l'autre, en inversant le sens de rotation des deux roues. Voici une seconde vue, avec un autre angle de vision sur la structure du véhicule : on y voit notament que les moteurs sont solidement attachés sur la structure formant le chassis (dans un prototype précédent, nous avions les moteurs qui se décrochaient trop facilement). On y voit aussi, en bas et à droite, un support pour l'un des deux modules de detection d'obstacles par ultrasons (HC-SR04). Il y en un devant et un autre derrière le véhicule. Enfin, on y voit différentes briques permettant de bloquer la breadboard ainsi que la carte Arduino.
Et voici encore une autre vue sur le dessous du véhicule. Notez la présence des petites roues qui peuvent pivoter sur elles-mêmes en cas de rotation du véhicule. Ce point serait très certainement à améliorer ! Les plaques permettent de bien renforcer la structure (le chassis).
Bien entendu, il nous faut une carte Arduino : nous avons choisi une carte Arduino Uno R3 (ou compatible). Mais d'autres cartes pourraient aussi convenir (Arduino Mega, ...).
Le véhicule est donc motorisé via deux blocs moteurs. Ils doivent pouvoir fonctionner indépendemment l'un de l'autre pour pouvoir permettre la rotation du véhicule. Nous avons donc choisis d'utiliser un composant L293D : il permet de contrôler chaque moteur indépendemment de l'autre (arrêt, allumage, puissance et sens de rotation). Un schéma de cablage vous est présenté plus bas dans ce document.
Ensuite, nous avons utilisé deux modules de detection d'obstacles par ultrasons (HC-SR04). Ils permettent de détecter les risques de collisions et d'arrêter le véhicule avant impact. Il y en a un pour quand le véhicule recule et un autre pour quand il avance. Notez que nous avons cherché à coincer les cables avec des axes situés dans la structure (moins çà bouge, mieux c'est). La bibliothèque de code associée à ce composant est disponible en activant le lien suivant : HCSR04 - Library for HC-SR04 ultrasonic distance sensor.
En termes de communication avec le véhicule, nous avons deux solutions : soit par bluetooth, soit par télécommande infrarouge. Pour le bluetooth, nous avons utilisé un composant de type HC-05.
Pour l'infrarouge, les kits Arduino en fournissent plus ou moins systématiquement. La bibliothèque de code associée au composant IR-Receiver est disponible à l'adresse suivante : https://www.arduinolibraries.info/libraries/i-rremote
On utilise aussi un buzzer qui signale toute détection d'obstacle. Quelques résistances seront aussi utiles (buzzer et composant HC-05). Enfin, on alimente le tout avec une pile 9V.
Maintenant, il faut assembler le tout. Je vous propose de suivre le schémat de cablage ci-dessous. Vous pouvez de plus télécharger le fichier d'origine de ce cablage : LegoduinoCar.fzz
Et voici maintenant le programme. Pour les explications complémentaires, je vous renvois vers la vidéo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
#include "Arduino.h" #include "stdlib.h" #include "time.h" #include "IRremote.h" // Configuration du récepteur infrarouge const int receiver = 7; IRrecv irrecv(receiver); decode_results results; // Configuration des capteurs ultrasons #include "SR04.h" const int TRIG_PIN1 = 3; const int ECHO_PIN1 = 2; const int TRIG_PIN2 = 6; const int ECHO_PIN2 = 5; SR04 sr04_1 = SR04(ECHO_PIN1,TRIG_PIN1); SR04 sr04_2 = SR04(ECHO_PIN2, TRIG_PIN2); // Configuration du buzzer const int pinBuzzer = 4; // Gestion bas-niveau des moteurs const int motor1_enablePin = 11; //pwm const int motor1_in1Pin = 13; const int motor1_in2Pin = 12; const int motor2_enablePin = 10; //pwm const int motor2_in1Pin = 9; const int motor2_in2Pin = 8; void setMotor1(int speed, bool reverse) { analogWrite(motor1_enablePin, speed); digitalWrite(motor1_in1Pin, ! reverse); digitalWrite(motor1_in2Pin, reverse); } void setMotor2(int speed, bool reverse) { analogWrite(motor2_enablePin, speed); digitalWrite(motor2_in1Pin, ! reverse); digitalWrite(motor2_in2Pin, reverse); } // Gestion plus haut niveau des moteurs const int SENS_AVANCE = 1; const int SENS_RECULE = 0; bool modeAuto = false; // false -> pilotage manuel // true -> mode autonome int speed1 = 0; bool sens1 = true; int speed2 = 0; bool sens2 = true; bool choisirSens() { return rand() % 2 == 0; } void stop() { speed1 = 0; sens1 = SENS_AVANCE; speed2 = 0; sens2 = SENS_AVANCE; setMotor1( speed1, sens1 ); setMotor2( speed2, sens2 ); } void avance() { speed1 = 255; sens1 = SENS_AVANCE; speed2 = 255; sens2 = SENS_AVANCE; setMotor1( speed1, sens1 ); setMotor2( speed2, sens2 ); } void recule() { speed1 = 255; sens1 = SENS_RECULE; speed2 = 255; sens2 = SENS_RECULE; setMotor1( speed1, sens1 ); setMotor2( speed2, sens2 ); } bool checkAvance() { return sens1 == sens2 && sens1 == SENS_AVANCE && speed1 == 255; } bool checkRecule() { return sens1 == sens2 && sens1 == SENS_RECULE && speed1 == 255; } void tourneGauche() { speed1 = 255; sens1 = 0; speed2 = 255; sens2 = 1; setMotor1( speed1, sens1 ); // Right setMotor2( speed2, sens2 ); // Left delay( 1650 ); speed1 = 0; sens1 = 0; speed2 = 0; sens2 = 0; setMotor1( speed1, sens1 ); // Right setMotor2( speed2, sens2 ); // Left } void tourneDroite() { speed1 = 255; sens1 = 1; speed2 = 255; sens2 = 0; setMotor1( speed1, sens1 ); // Right setMotor2( speed2, sens2 ); // Left delay( 1650 ); speed1 = 0; sens1 = 0; speed2 = 0; sens2 = 0; setMotor1( speed1, sens1 ); // Right setMotor2( speed2, sens2 ); // Left } // Traduit la pression des boutons de la télécommande par une des actions void translateIR() { switch(results.value) { // Détecte si la touche pressée est la touche Power case 0xFFA25D: //Serial.println("POWER"); modeAuto = true; avance(); break; // Détecte si la touche pressée est la touche Volume+ case 0xFF629D: avance(); modeAuto = false; break; // Détecte si la touche pressée est la touche Arrière case 0xFF22DD: tourneGauche(); modeAuto = false; break; // Détecte si la touche pressée est la touche Play/Pause case 0xFF02FD: stop(); modeAuto = false; break; // Détecte si la touche pressée est la touche Avance case 0xFFC23D: tourneDroite(); modeAuto = false; break; // Détecte si la touche pressée est la touche Volume- case 0xFFA857: recule(); modeAuto = false; break; //default: //Serial.println(" other button "); } } void setup(){ Serial.begin( 9600 ); // On initialise les pins du moteur 1 pinMode(motor1_in1Pin, OUTPUT); pinMode(motor1_in2Pin, OUTPUT); pinMode(motor1_enablePin, OUTPUT); // On initialise les pins du moteur 2 pinMode(motor2_in1Pin, OUTPUT); pinMode(motor2_in2Pin, OUTPUT); pinMode(motor2_enablePin, OUTPUT); // On active l'infrarouge irrecv.enableIRIn(); // On initialise le générateur de nombre pseudo aléatoire srand( time( NULL ) ); } void loop(){ if (irrecv.decode(&results)) { translateIR(); irrecv.resume(); } while ( Serial.available() > 0 ) { int code = Serial.read(); Serial.print( code ); switch( code ) { case 'a': avance(); modeAuto = false; break; case 's': stop(); modeAuto = false; break; case 'r': recule(); modeAuto = false; break; case 'g': tourneGauche(); modeAuto = false; break; case 'd': tourneDroite(); modeAuto = false; break; case 't': modeAuto = true; avance(); } } // capteur avant long distance_1 = sr04_1.Distance(); if ( distance_1 > 0 && distance_1 < 10 ) { // si on voit un obstacle if ( checkAvance() ) { tone( pinBuzzer, 1000, 500 ); if ( modeAuto == true ) { recule(); delay(2000); if ( choisirSens() ) { tourneGauche(); } else { tourneDroite(); } avance(); } else { stop(); } } } // capteur arrière long distance_2 = sr04_2.Distance(); if ( distance_2 > 0 && distance_2 < 10 ) { // si on voit un obstacle if ( checkRecule() ) { tone( pinBuzzer, 1000, 500 ); stop(); } } delay( 100 ); } |
Tone
et celle permettant la gestion de le télécommande infrarouge, IRremote
. Si c'est aussi votre cas, alors ouvrez le fichier
IRremoteInt.h
et localisez le bloc de code suivant.
1 2 3 4 |
#else //#define IR_USE_TIMER1 // tx = pin 9 #define IR_USE_TIMER2 // tx = pin 3 #endif |
Normalement, si vous permuttez les deux lignes de commentaires, le problème doit être résolu. Voici le code après permutation.
1 2 3 4 |
#else #define IR_USE_TIMER1 // tx = pin 9 //#define IR_USE_TIMER2 // tx = pin 3 #endif |
Si ce projet vous a plu et que vous souhaitiez poursuivre son développement, sachez que je vous propose le code d'un projet Android permettant de contrôler le véhicule par bluetooth. Vous trouverez ce projet à l'adresse suivante : la télécommande Android.
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :