LALU Guillaume 04/10/2013 PROJET : Réalisation d un robot
SOMMAIRE I Introduction II Présentation du robot 2.1 Différents modules du robot 2.2 Montage du robot 2.3 Le cerveau du robot : la carte Arduino 2.4 Diagramme de fonctionnement III Développement software 3.1 Squelette du software 3.2 Interruption Hardware 3.3 Fonction de télémétrie : détection d obstacle 3.4 Gestion de l accéléromètre 3.5 Mesure de la température 3.6 Géo-localisation 3.7 Réception Infrarouge 3.8 Intensité sonore 3.9 Communication Bluetooth 3.10 Affichage sur un écran LCD IV Analyse de performances 4.1 Télémétrie 4.2 Mesure de la température V Améliorations envisageables 5.1 Ajout de nouveaux capteurs 5.2 Batteries plus puissantes 5.3 Mesure de la consommation énergétique du robot 5.4 Amélioration de l application de contrôle du robot sous Android
5.5 Intégration d un linux embarqué sur une nouvelle carte VI Conclusion VII Bibliographie
I Introduction De nos jours la robotique est omniprésente dans notre quotidien, surtout quand il s agit de réaliser des taches dangereuses, automatisables, ou demandant une grande précision. Ce qui est certain c est la complexité croissante de ces systèmes embarquant de plus en plus de technologies. Dans ces systèmes robotisés autonomes ou semiautonomes les capteurs occupent une place prédominante, c est ce qui permet aux systèmes d appréhender leur environnement, l analyse quant à elle est rendu possible grâce aux microprocesseurs qui vont traite et réagir suivant les différents signaux qui lui sont rapportés grâce à divers protocoles de communication. Différents actionneurs permettent d interagir avec l environnement (servomoteur, moteurs, pistons ). Le problème est de faire interagir intelligemment tout ces éléments. II Présentation du robot 2.1 Différents modules du robot Vue schématisé des divers éléments :
Robot en pièces détachées :
2.2 Montage du robot Après assemblage : 2.3 Le cerveau du robot : la carte Arduino Le système peut être alimenté avec des tensions de 5V à 12V via le connecteur d alimentation ou par le port USB Le microcontrôleur de cette carte est un ATMEL cadencé à 16 MHz
De nombreuses entrées sorties sont disponibles ainsi que 4 liaisons séries et une liaison I2C. 2.4 Diagramme de fonctionnement La détection d un obstacle ou la réception d une commande par liaison Bluetooth Entraine le déclenchement d une interruption.
III Développement software 3.1 Squelette du software L environnement de développement fournit par Arduino ( ) permet de simplifier le travail de programmation incluant de nombreuses librairies et fonctionnalités de base, un compilateur dédié et même un terminal. Le squelette du code est le suivant : Une première partie dédiée à l inclusion des librairies et à la déclaration des différentes constantes et variables La fonction setup() : Permet d initialiser le système. La fonction loop() : Qui représente le fonctionnement normal du système c est une boucle infinie, on y effectue les traitements normaux ainsi que les appels aux différentes fonctions codés pour chaque module.
3.2 Interruption Hardware Il est possible d interrompre le fonctionnement normal du programme grâce à une routine d interruption codée comme ceci : Interruption suite a la détection d'un obstacle attachinterrupt(int_pin_3_id, evitement, FALLING); Le premier paramètre correspond au numéro de la broche sur laquelle le récepteur ultrasonique du télémètre est relié. Le deuxième est le nom de la fonction à effectué suite a l interruption matérielle. Le dernier défini l événement déclenchant l appel a la fonction (ici un front descendant) En résumé voici la fonction de gestion des interruptions: attachinterrupt(<n de la broche>, <Nom de la fonction>, <Evénement déclencheur>); 3.3 Fonction de télémétrie : détection d obstacle On utilise un télémètre afin de mesuré la distance à un obstacle. Le principe du télémètre est le suivant un signal ultrason est émis, puis après réflexion sur un obstacle est reçue par un récepteur la largeur de l impulsion reçue étant proportionnelle à la distance. Extrait de la datasheet du capteur HC-SR04
/*Programme gérant le calcul de distance a un obstacle et l évitement de celui-ci si la distance est inferieure a 40cm*/ #include <Wire.h> //Connexion du Télémètre const int Trig = 41; const int Echo = 3; //LED const int LED_obstacle_devant = 39; //LED Rouge //Arduino PWM Speed Control: const int E1 = 5; const int M1 = 4; const int E2 = 6; const int M2 = 7; const int speed = 255;//rapport cyclique règle la vitesse //Variable globale volatile float dist = 500.0; //Telemetre (en cm) /*Interrupt pin identifier*/ const int INT_PIN_3_ID = 1; /*Liaison serie*/ const int BAUD_RATE = 9600; //Debit du port serie /*Initialisation*/ void setup() //Ouverture de la liaison serie au debit BAUD_RATE Serial.begin(BAUD_RATE); /*Brochage des E/S*/ //Télémètre pinmode(trig, OUTPUT); pinmode(echo, INPUT); //LED
pinmode(led_obstacle_devant, OUTPUT); //LED Rouge /*Interrupions*/ //Interruption par détection d'un obstacle attachinterrupt(int_pin_3_id, evitement, FALLING); void loop() //Activation du télémètre digitalwrite(trig, LOW); delaymicroseconds(2); digitalwrite(trig, HIGH); delaymicroseconds(10); // 10µs d'attente pour envoyer le signal au télémètre digitalwrite(trig, LOW); //recuperation de la distance à l'obstacle dist = pulsein(echo,high)/58.0; //dist en cm void evitement() //Evitement si il y a un obstacle a 40 cm devant le robot if (dist < 40) digitalwrite(led_obstacle_devant,high); //Allume la led indiquant la détection d'un obstacle recule (); tourner_gauche(); void recule() for(int i =0;i<10000;i++) //Boucle d'attente digitalwrite(m1,low); //M1 marche arriere digitalwrite(m2,low); //M2 marche arriere analogwrite(e1, speed); //PWM Speed Control analogwrite(e2, speed); //PWM Speed Control
void tourner_gauche() for(int i =0;i<20000;i++) //Boucle d'attente digitalwrite(m1,high); //M1 marche avant digitalwrite(m2,low); //M2 marche arriere analogwrite(e1, speed); //PWM Speed Control analogwrite(e2, speed); //PWM Speed Control 3.4 Gestion de l accéléromètre Ce dernier permet de récupérer les différentes accélérations suivants les 3 axes x, y et z c est un signal analogique donnée en mv/g en sortie de ce module. La tension d alimentation est de 3,3V. #include <Math.h> #include <Wire.h> #define PI 3.1415926535897932384626433832795 #define ADC_ref 3.3 #define sensitivity_x 0.330 //Sensibilite de 330 mv/g #define sensitivity_y 0.330 #define sensitivity_z 0.330 //Accelerometre int X0,Y0,Z0; /*Entree Analogiques*/ //Accelerometre const int ADXL_X = 0; //AnalogIn 0 const int ADXL_Y = 1; //AnalogIn 1 const int ADXL_Z = 2; //AnalogIn 2 /*Liaison serie*/ const int BAUD_RATE = 9600; //Debit du port serie
/*Initialisation*/ void setup() // analogreference(default); //Tension de reference pour les entree analogiques //Ouverture de la liaison serie au debit BAUD_RATE Serial.begin(BAUD_RATE); //recuperation des valeurs de l'accelerometre en mv/g X0 = analogread(adxl_x); Y0 = analogread(adxl_y); Z0 = analogread(adxl_z); delay(50); /*Boucle infini*/ void loop() calcul(); //Accelerometre delay(100); //Rafraichissement /*Calculs lies a l'accelerometre*/ void calcul() int X1,Y1,Z1; float a_x,a_y,a_z; //Accelerations en g (m/s²) float roulis, tangage, orientation; //Angles X1 = analogread(adxl_x); Y1 = analogread(adxl_y); Z1 = analogread(adxl_z); //Calcul des accelerations a_x = ((X1 - X0)/1024.0*ADC_ref)/sensitivity_x; a_y = ((Y1 - Y0)/1024.0*ADC_ref)/sensitivity_y; a_z = ((Z1 - Z0)/1024.0*ADC_ref)/sensitivity_z; //Calcul des angles en degrés roulis = atan2(-a_y,-a_z)*(180/pi); tangage = atan2(-a_x,-a_z)*(180/pi); //oscillations laterales //oscillations avant/arriere
orientation = atan2(-a_y,-a_x)*(180/pi); //orientation //Affichage des valeurs calculees //Accelerations Serial.print("X = "); Serial.print(a_X); Serial.println(" g"); Serial.print("Y = "); Serial.print(a_Y); Serial.println(" g"); Serial.print("Z = "); Serial.print(a_Z); Serial.println(" g"); //ANGLES Serial.print("Orientation: "); Serial.print(orientation); Serial.println(" deg"); Serial.print("Roulis: "); Serial.print(roulis); Serial.println(" deg"); Serial.print("Tangage: "); Serial.print(tangage); Serial.write(" deg\n"); On divise par 1024 les valeurs obtenues car ce sont des valeurs analogiques codés sur 10 bits soit 2^10 valeurs (de 0 à 1023).
3.5 Mesure de la température On utilise un circuit intégré (LM20) pour sonder la temperature. La formule Suivante donne la relation entre la mesure récupérée par la carte arduino(v 0 ) et la temperature : #include <Math.h> #include <Wire.h> const int LM20 = 10; //Entree analogique AnalogIn 10 const int BAUD_RATE = 9600; //Débit du port série volatile float val_temp = 20.0; //temperature /*Initialisation*/ void setup() // analogreference(default); //Tension de reference pour les entree analogiques //Ouverture de la liaison serie au debit BAUD_RATE Serial.begin(BAUD_RATE); /*Boucle infini*/ void loop() mesure_temperature(); delay(100); //Rafraichissement void mesure_temperature() float V_out; //Tension recupere fonction de la temperatue float Vcc = 5.0; // Tension d'entree = 5,0 V /*Recuperation de Vout therm pour la thermistance ou LM20 pour le capteur*/ V_out = analogread(lm20)*(vcc/1024.0); // Conversion Numerique analogique Vref = 5V et code sur 10 Bits (1024) V_out en V
/*Calcul de la temperature avec le capteur LM20*/ //+5V:pin 25 GND:pin 26 Vout:pin 15 val_temp = -1481.96 + sqrt((2.1962*pow(10.0,6))+((1.8639 - V_out)/(3.88*pow(10.0,- 6)))); //Cf datasheet LM20 TI: http://www.ti.com/lit/ds/symlink/lm20.pdf Serial.print("Temperature mesuree: "); Serial.print(val_temp,1); Serial.println(" C"); 3.6 Géo-localisation On utilise pour cela une puce GPS (GlobalSat EM-406A) renvoyant une trame NMEA (National Marine Electronics Association) #include <Math.h> #include <Wire.h> #include <string.h> #include <nmea.h> #include <stdio.h> const int LED_GPS = 34; //LED Bleue /*Liaison serie*/ const int BAUD_RATE = 9600; //Debit du port serie const int BAUD_RATE_GPS = 4800; //Debit du port serie pour le GPS volatile float course=0.0; //Direction du robot (Bousole) (en ) volatile float vitesse = 0.0; //Vitesse moyenne (en m/s) float latitude = 0.0, longitude = 0.0; /*GPS*/ NMEA gps(all); // Prise en compte de toutes les trames GPS:(GGA,RMC,VTG) /*Initialisation*/ void setup() //USB Serial.begin(BAUD_RATE);
//Serial 2 Tx: 16 Rx: 17 liaison serie avec le GPS Serial2.begin(BAUD_RATE_GPS); //initialize serial pinmode(led_gps, OUTPUT); //LED Bleue /*Boucle infini*/ void loop() geoloc(); digitalwrite(led_gps,low);//eteind la led bleue delay(500); /*--------------------------------------------GPS--------------------------------------------*/ void geoloc() char c; //Caractere permettant de recuperer les trames String date="jjmmaa"; //JourMoiAnnee String temps_utc="hhmmss????"; //Heure UTC String jour="jj/",moi="mm/",annee="20aa"; String Date="jj/mm/aaaa"; String heure="hh:",minute="mm:",seconde="ss"; String UTC="hh:mm:ss"; String N_S="?",E_W="?"; //Indicateur de points cardinaux String protocole="$gpgga"; while (Serial2.available()>0) // Lecture de la trame GPS c = Serial2.read(); //recuperation des caracteres // Verifie que la trame est complete
while (gps.decode(c)) /*Recuperation de l'heure*/ temps_utc = gps.term(1);//recupere l'heure UTC (rajouter 1h pour l'heure d'hiver) //Mise en forme de l'heure hh:mm:ss heure[0]=temps_utc[0]; heure[1]=temps_utc[1]; minute[0]=temps_utc[2]; minute[1]=temps_utc[3]; seconde[0]=temps_utc[4]; seconde[1]=temps_utc[5]; UTC = heure + minute + seconde; // Verifie que la reception GPS est valide (status) if (gps.gprmc_status() == 'A') Serial.println("Reception d'une trame GPS valide:"); digitalwrite(led_gps, HIGH);//Allume la led bleue a la reception d'une trame GPS RMC course = gps.gprmc_course();//recupere l'orientation du robot en 0 : Nord 90 : Est 180 : Sud 270 : Ouest vitesse = gps.gprmc_speed(kmph); //Vitesse en Km/h vitesse = vitesse*(1000/3600); //Conversion des Km/h en m/s Serial.println("\n-----------------Orientation et vitesse------------------"); Serial.print("Orientation du robot: "); Serial.print(course,2); Serial.println(" "); Serial.print("Vitesse: "); Serial.print(vitesse,2); Serial.println(" m/s"); //Position: Serial.println("------------------------POSITION------------------------"); latitude = gps.gprmc_latitude();
longitude = gps.gprmc_longitude(); N_S = gps.term(4); //Indicteur Nord/Sud E_W = gps.term(6); //Indicatreur Est/Ouest Serial.print("Latitude: "); Serial.print(latitude,5); Serial.write(" "); Serial.println(N_S); Serial.print("Longitude: "); Serial.print(longitude,5); Serial.write(" "); Serial.println(E_W); Serial.println("------------------------Info UTC------------------------"); date = gps.term(9);//recupere la date //Mise en forme de la date jj/mm/aaaa jour[0]=date[0]; jour[1]=date[1]; moi[0]=date[2]; moi[1]=date[3]; annee[2]=date[4]; annee[3]=date[5]; Date = jour + moi + annee; /*Affichage de la date*/ Serial.write("Date: "); Serial.println(Date); Serial.write("\nHeure: "); Serial.println(UTC); //Position
Serial.write("\nPosition: "); Serial.write(" - Latitude: "); Serial.print(latitude,5); Serial.write(" "); Serial.println(N_S); Serial.write(" - Longitude: "); Serial.print(longitude,5); Serial.write(" "); Serial.println(E_W); //Envoi par USB de la course et de la vitesse Serial.write("\nOrientation: "); Serial.print(course,0); Serial.write(" \n"); Serial.write("Vitesse: "); Serial.print(vitesse); Serial.write(" m/s\n"); Serial.print(c);//Affichage des trames reçues La console affiche : Reception d'une trame GPS valide: ------------------------Info UTC------------------------ Date: 21/02/2013 Heure: 12:18:01 ------------------------POSITION------------------------ Position: - Latitude: 48.41393 Â N - Longitude: -4.48546 Â W -----------------Orientation et vitesse------------------ Orientation du robot: 159.89Â Vitesse: 0.00 m/s B $GPGGA,121802.000,4824.8358,N,00429.1276,W,1,06,1.8,77.3,M,52.0,M,,0000*7C $GPGSA,A,3,10,23,13,02,20,04,,,,,,,2.8,1.8,2.2*37 $GPRMC,121802.000,A,4824.8358,N,00429.1276,W,0.16,178.05,210213,,,A*7 Le code suivant envoi ses informations grace au module bluetooth //Permet de recupere par Bluetooth les dernieres informations GPS connues void donnees_geoloc()
//Envoi par Bluetooth des informations relatives a la geolocalisation Serial1.write("\n*Données GPS*"); /* Serial1.write("\nDate: "); for(int i =0;i<sizeof(Date_c);i++) Serial1.write(Date_c[i]); Serial1.write("\nHeure: "); for(int i =0;i<sizeof(UTC_c);i++) Serial1.write(UTC_c[i]); */ //Position Serial1.write("\nLatitude: "); Serial1.print(latitude,5); Serial1.write(" "); Serial1.print(N_S_c); Serial1.write("\nLongitude: "); Serial1.print(longitude,5); Serial1.write(" "); Serial1.print(E_W_c);
L application Bluetooth SPP (https://play.google.com/store/apps/details?id=mobi.dzs.android.bluetoothspp&hl=fr) permet de loguer ce qui est reçue sur le Smartphone ou la tablette : [Receive data:] Connectingâ Bluetooth connect ok. * GPS * Reception d'une trame(rmc) valide Date: 21/02/2013 Heure: 12:18:01 Position: - Latitude: 48.41393 Â N - Longitude: -4.48546 Â W 3.7 Réception infra rouge(ir) Il permet de télécommander le robot grâce à une télécommande IR //Capteur IR if (irrecv.decode(&results)) digitalwrite(led_ir_rx,high); Serial.println(results.value, HEX); //Contient les valeurs associées aux touches de la télécommande /* double remote_control[21]=0xfd00ff,0xfd807f,0xfd40bf, 0xFD20DF,0xFDA05F,0xFD609F, 0xFD10EF,0xFD906F,0xFD50AF, 0xFD30CF,0xFDB04F,0xFD708F,
0xFD08F7,0xFD8877,0xFD48B7, 0xFD28D7,0xFDA857,0xFD6897, 0xFD18E7,0xFD9867,0xFD58A7; */ switch (results.value) case 0xFD807F: //Bouton Vol+ avance(); break; case 0xFD609F: //Bouton >> tourner_droite(); break; case 0xFD20DF: //Bouton << tourner_gauche(); break; case 0xFD906F: //Bouton VOLrecule(); break; case 0xFD00FF: //Bouton rouge arret(); break; default: //Robot à l'arret arret(); break; irrecv.resume(); // Receive the next value 3.8 Intensité Sonore On la récupère grâce a un micro, chaque son est caractérisé par une tension analogique, si cette dernière dépasse un certain seuil la led Tricolore RGB passe du vert au rouge void ecoute() digitalwrite(led_rgb_green,high);//allume la LED verte val_mic = analogread(mic); //Lecture de la valeur retourne par le microphone Serial.print("Valeur renvoyée par le micro:"); Serial.println(val_mic,2);
if(val_mic >= 20) digitalwrite(led_rgb_green,low);//eteint la LED verte digitalwrite(led_rgb_red,high);//allume la LED rouge delay(100); 3.9 Communication Bluetooth Un module de communication Bluetooth est utilisé pour communiquer avec la tablette, il est interfacé en liaison série avec la carte arduino. A la réception d un caractère envoyé par la tablette le robot connait l action à effectuer void Rx_cmd() //float rc_temp; digitalwrite(led_rgb_green,low);//eteint la LED verte digitalwrite(led_rgb_red,low);//eteint la LED rouge while(serial1.available()) //is there anything to read? digitalwrite(led_rgb_blue, HIGH); //Allume la LED bleue char getdata = Serial1.read(); //Lecture du 1er caractere Serial.println(getData); //Affiche le cactere reçu par le module Bluetooth sur le port USB switch (getdata) case 'a': //Avancer Serial1.write("Avancer\n"); avance();
break; case 'd': //Tourner a droite Serial1.write("Tourner a droite\n"); tourner_droite(); break; case 'g': //Tourner a gauche Serial1.write("Tourner a gauche\n"); tourner_gauche(); break; case 'r': //Reculer Serial1.write("Reculer\n"); recule(); break; case 's': //Stop Serial1.write("Stop\n"); arret(); break; case 't': //Envoi de la temperature mesure_temperature(); Serial1.write("\nLa temperature est de: "); Serial1.print(val_temp,1); Serial1.write(" C\n"); break; case 'p': //Reception GPS donnees_geoloc(); break; default: break;
3.10 Affichage sur un écran LCD L écran LCD est interfacé par la liaison I2C, il affiche les caractères alphanumériques de base, sur 2 lignes et 16 colonnes. Il est possible d afficher des caracteres speciaux exemple le : const byte degreesymbol = B11011111; Ou encore de créer son propre caractère matriciellement, chaque caractères est composé de 40 pixels (8 lignes 5 colonnes) Exemple : une flèche vers la droite les 1 sont les pixels activés byte fleche_droite[8] = B11000, B11100, B11110, B11111, B11111, B11110, B11100, B11000 ; III Analyse de performances 4.1 Télémétrie Echantillon de 500 mesures de distances, le télémètre est placé à 20 cm d un obstacle, l histogramme est réalisé avec le logiciel R (http://www.r-project.org/)
Ce télémètre est précis à 0,15 cm 4.2 Mesure de la température Egalement réalisé grâce à R, on échantillonne 500 mesures de temperature (temperature ambiante) Le capteur est précis à 0,3 C V Améliorations envisageables 5.1 Ajout de nouveaux capteurs
Dans le but de mieux éviter les obstacles le rajout de télémètres sur les cotés et à l arrière serait envisageable. Une camera orientable grâce a des cerveaux moteurs pourrait permettre de contrôler le robot à distance même dans le cas ou on ne voit plus ce dernier (exemple zones dangereuses, robots espions, démineurs ). Divers détecteurs (gaz, mouvement, ). Roues codeuses pour asservir plus précisément la vitesse des moteurs et mieux gérer la direction. 5.2 Batteries plus puissantes Des batteries plus puissantes pour alimenter les moteurs, celle d origine montrent leurs limites lors du changement de direction. Problème presque résolue en mettant deux hacheurs contrôlant chacun 2 moteurs (cote droit/cote gauche) et chaque hacheur est alimenté par une batterie. celles ci 5.3 Mesure de la consommation énergétique du robot Permettrai de mieux gérer la charge des batteries ainsi que le dimensionnement de 5.4 Amélioration de l application de contrôle du robot sous Android Pour le moment c est une application (Bluetooth SPP) qui permet de contrôler le robot, elle permet de personnaliser ses boutons et d afficher des informations envoyées. Une application personnalisée pourrait par exemple utiliser le capteur de position d un Smartphone pour contrôler la direction du robot. 5.5 Intégration d un linux embarqué sur une nouvelle carte Dans le but d améliorer la réactivité et la complexité du robot une carte capable de faire fonctionner un linux embarqué et ainsi faire du temps réel, du calcul (asservissement) et pourquoi pas du traitement d image VI Conclusion Ce robot montre les nombreuses possibilités d intégration de divers modules et cela de manière assez simple grâce à Arduino. De nombreuses librairies sont fournies et un petit environnement de développement facile a prendre en main et cependant complet fait de se système une bonne base pour la création de systèmes plus complexes. Le développement d une application android est une amélioration intéressante à developper.
VII Bibliographie http://www.r-project.org/ http://arduino.cc/en/reference/homepage http://arduino.cc/en/main/arduinoboardmega2560 http://www.robot-maker.com/index.php?app=portal http://radio.pagesperso-orange.fr/rs232.htm http://www.maartenlamers.com/nmea/index.html http://www.cypress.com/?docid=2732 «Arduino Cookbook - Michael Margolis O'Reilly Media - 2011» http://www.gpsfrance.net/adresse-vers-coordonnees-gps http://www.csgnetwork.com/multitimedisp.html http://wiring.org.co/learning/libraries/basicpositioning.html http://www.kronosrobotics.com/projects/gps.shtml http://www.dfrobot.com/index.php?route=product/product&filter_name=led%20rgb&pr oduct_id=175#.uk8a79lxotl http://www.dfrobot.com/index.php?route=product/product&product_id=351#.uk8a59l xotl http://domoduino.tumblr.com/ http://www.forward.com.au/pfod/serialbluetoothconnections/serialbluetoothconnectio nviausb.html http://www.hw-group.com/products/hercules/index_en.html http://www.figarosensor.com/ http://www.ladyada.net/make/xbee/arduino.html http://examples.digi.com/ http://nononux.free.fr/index.php?page=elec-brico-bluetooth-android-microcontroleur http://www.pobot.org/un-reseau-sans-fil-avec-des-xbee http://www.maartenlamers.com/nmea/nmea.html#gprmc_utc http://diopter.fr/index.php/technique/systeme-numerique/41-adx-335-et-arduino http://www.electronicsblog.net/simple-angle-meter-using-adxl335-accelerometerarduino/ http://jeromeabel.net/ressources/xbee-arduino