Projet ICN robot parlant 2018/2019

De Informatique et Création Numérique
(Différences entre les versions)
Aller à : Navigation, rechercher
 
(44 révisions intermédiaires par un utilisateur sont masquées)

Version actuelle en date du 22 mai 2019 à 13:54

Projet robot parlant Gautier ICN 2018/2019


[modifier] I/ PARTI MANUEL

Première étape; montage du robot (avec le manuel)(facile mais demande d'être minutieux)

2eme etape :soudure sur le robot des fils et branchement des fils sur la carte arduino


II/ PARTI PROGRAMMATION


Pour bien apprendre à travailler avec arduino je vous conseil ce site: https://openclassrooms.com/fr/courses/2778161-programmez-vos-premiers-montages-avec-arduino


Exemple de fonction utile:

setup() qui s'exécute qu'une fois ;

loop() qui s'exécute à l'infini ;

void (qui se met toujours devant loop et setup ) ;

pinMode() qui permet de définir une sortie en mode envoi d'électricité ou non ;

digitaWrite() qui envoie de l'électricité par une sortie ;

delay() qui met le programme en pause pendant un nombre défini de millisecondes.

switch :switch case contrôle le flux des programmes en permettant aux programmeurs de spécifier un code différent à exécuter dans diverses conditions.

Une instruction switch compare la valeur d'une variable aux valeurs spécifiées dans les instructions case.

break :quitte l'instruction switch et est généralement utilisé à la fin de chaque cas.

#define : est un composant C utile qui permet au programmeur de nommer une valeur constante avant la compilation du programme.

Serial.begin: Définit le débit de données en bits par seconde (bauds) pour la transmission de données en série.

default:

unsigned long: sont des variables de taille étendue pour le stockage de numéros et stockent 32 bits (4 octets).

Contrairement aux longs standards, les long unsigned ne stockent pas les nombres négatifs, ce qui les situe entre 0 et 4 294 967 295 (2 ^ 32 - 1).

for: L'instruction for est utilisée pour répéter un bloc d'instructions entre accolades.

Un compteur d’incrément est généralement utilisé pour incrémenter et terminer la boucle.

L'instruction for est utile pour toute opération répétitive et est souvent utilisée en combinaison avec des tableaux pour opérer sur des collections de données / pins.

pulseIn: Lit une impulsion ( HIGHou LOW) sur une broche.

Par exemple, si valueest HIGH, pulseIn()attend que la broche passe de LOWà HIGH, commence le chronométrage, puis attend que la broche disparaisse LOWet arrête le chronométrage.

Renvoie la durée de l'impulsion en microsecondes ou abandonne et renvoie 0 si aucune impulsion complète n'a été reçue dans le délai imparti.

if: Si

else: sinon

else if: sinon si

while: Une while boucle boucle en boucle de façon continue et infinie jusqu'à ce que l'expression entre parenthèses () devienne fausse.



/*Programme d'évitement d'obstacle sans contact*/
//initialisation
// Constantes pour la navigation
#define PROCHE 700 //de base 200
#define DANGER 400 // de base 100
#define AFOND 150
#define PRUDENT 50
#define NBMESURE 5
#define AJUSTE 1.05
// Constantes pour le sonar
// pin 12 et 13 pour le capteur à ultrason
const int ECHO_PIN=13; //(mettre la pin correspondante au capteur a ultrason) //pin numérique utilisé pour le capteur ultrasons.
const int TRIGGER_PIN=12;
const unsigned long MEASURE_TIMEOUT=25000UL; // 25ms = ~8m à 340m/s
const float SOUND_SPEED=340.0/1000;
// Constantes pour le contrôleur de moteurs
int pwmB = 3;
int bin2 = 4;
int bin1 = 5;
int stby = 6;
int ain1 = 7;
int ain2 = 8;
int pwmA = 9;
void avance(int v)//Déclare la fonction qui fait avancer le robot
 {
 Serial.println("Avant");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, HIGH);//Lance le courant
 digitalWrite(ain2, LOW);
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, HIGH);
 digitalWrite(bin2, LOW);
 analogWrite(pwmA, v*AJUSTE);//Donne la puissance du moteur 1
 analogWrite(pwmB, v);//Donne la puissance du moteur 2 (pour qu'il aille droit)
 }
 void recule(int v)//Déclare la fonction qui fait avancer le robot
 {
 Serial.println("Avant");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, LOW);//Lance le courant
 digitalWrite(ain2, HIGH);
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, LOW);
 digitalWrite(bin2, HIGH);
 analogWrite(pwmA, v*AJUSTE);//Donne la puissance du moteur 1
 analogWrite(pwmB, v);//Donne la puissance du moteur 2 (pour qu'il aille droit)
 }
 void arret(void)//Déclare la fonction qui fait stopper le robot
 {
 digitalWrite(stby, LOW);//arrête les moteurs
 }
 void tourneDroite(int v) //Déclare la fonction qui fait effectuer un tour au robot
 {
 Serial.println("TourneDroite");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, LOW);//Lance le courant...
 digitalWrite(ain2, HIGH);//et fait en sorte qu'un des moteurs tourne a l'envers pour que le robot tourne sur lui-même
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, HIGH);
 digitalWrite(bin2, LOW);
 analogWrite(pwmA, v*AJUSTE);//Donne la puissance du moteur 1
 analogWrite(pwmB, v);//Donne la puissance du moteur 2 
 }
 void tourneGauche(int v) //Déclare la fonction qui fait effectuer un tour au robot
 {
 Serial.println("TourneDroite");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, HIGH);//Lance le courant...
 digitalWrite(ain2, LOW);//et fait en sorte qu'un des moteurs tourne a l'envers pour que le robot tourne sur lui-même
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, LOW);
 digitalWrite(bin2, HIGH);
 analogWrite(pwmA, v*AJUSTE);//Donne la puissance du moteur 1
 analogWrite(pwmB, v);//Donne la puissance du moteur 2 
 }
 #if 0
 void tour(void) //Déclare la fonction qui fait effectuer un tour au robot
 {
 Serial.println("Tour");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, LOW);//Lance le courant...
 digitalWrite(ain2, HIGH);//et fait en sorte qu'un des moteurs tourne a l'envers pour que le robot tourne sur lui-même
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, HIGH);
 digitalWrite(bin2, LOW);
 analogWrite(pwmA, 131.125);//Donne la puissance du moteur 1
 analogWrite(pwmB, 125);//Donne la puissance du moteur 2 
 delay(3750);//Donne le temps durant lequel le robot va tourner sur lui-même
 digitalWrite(stby, LOW);//arrête les moteurs
 }
 +
 void demitour(void)
 {
 Serial.println("DemiTour");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, LOW);
 digitalWrite(ain2, HIGH);
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, HIGH);
 digitalWrite(bin2, LOW);
 analogWrite(pwmA, 131.125);
 analogWrite(pwmB, 125);
 delay(890);
 digitalWrite(stby, LOW);
 }
 void quarttour(void)
 {
 Serial.println("QuartDeTour");
 digitalWrite(stby, HIGH);//démarre les moteurs
 digitalWrite(ain1, LOW);
 digitalWrite(ain2, HIGH);
 digitalWrite(stby, HIGH);
 digitalWrite(bin1, HIGH);
 digitalWrite(bin2, LOW);
 analogWrite(pwmA, 131.125);
 analogWrite(pwmB, 125);
 delay(450);
 digitalWrite(stby, LOW);
 }
 #endif
 void setup() {
 Serial.begin(9600);
 pinMode(pwmB, OUTPUT);
 pinMode(bin2, OUTPUT);
 pinMode(bin1, OUTPUT);
 pinMode(stby, OUTPUT);
 pinMode(ain1, OUTPUT);
 pinMode(ain2, OUTPUT);
 pinMode(pwmA, OUTPUT);
 /* Initialise les broches */
 pinMode(TRIGGER_PIN, OUTPUT);
 digitalWrite(TRIGGER_PIN, LOW); // La broche TRIGGER doit être à LOW au repos
 pinMode(ECHO_PIN, INPUT);
 #if 0
 int m=mesure();
 avance(PRUDENT);
 delay(5000);
 arret();
 exit(0); 
 #endif
 }
 void loop() {
 int m=mesure();
 // mettez votre code principal ici, pour exécuter à plusieurs reprises:
 switch (m){ //utilisation de la condition switch
  case 0: // l'obstacle est dans la zone DANGER
    Serial.println("*DANGER*");
    arret(); // on arrête le robot
    delay(200);
    recule(PRUDENT); // on le fait reculer un peu
    delay(400);
    recherche(); // on recherche la bonne voie
    break;
  case 1: //l'obstacle est dans la zone PROCHE
    Serial.println("Attention...");
    avance(PRUDENT); // on ralentit la vitesse
  default:
    avance(AFOND);
  }
 }
 int mesure(){
 //fonction qui mesure une distance avec le capteur
 float cumul = 0; // variable de mesure
 float moyenne = 0; //variable pour la moyenne
 for (int t = 0; t < NBMESURE; t++) { // boucle pour effectuer les mesures
   /* 1. Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
   digitalWrite(TRIGGER_PIN, HIGH);
   delayMicroseconds(10);
   digitalWrite(TRIGGER_PIN, LOW);
   /* 2. Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
   long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
   /* 3. Calcul la distance à partir du temps mesuré */
   float distance_mm = measure / 2.0 * SOUND_SPEED;   
   cumul += distance_mm;
 }
 moyenne=cumul/NBMESURE; //on calcule la moyenne des mesures
 /* Affiche les résultats en cm */
 Serial.print(F("Distance: "));
 Serial.print(moyenne/10.0, 2);
 Serial.print(F("cm, "));
 if (moyenne<=(float)DANGER){//on teste si l'obstacle est dans la zone DANGER
  return 0; //si oui, on retourne le code de danger
 }
 else if (moyenne>(float)DANGER && moyenne<=(float)PROCHE){//on teste s'il est dans la zone PROCHE
  return 1; //si oui, on retourne le code de proche
 }
 else{ // Aucun obstacle proche
  return 2; // on retourne le code de sans risque
 }
 }
 void recherche(){
 //fonction pour rechercher un passage
 tourneGauche(AFOND); //on positionne le robot à gauche (facultatif)
 delay(300);
 int etat=0; //variable de test de possibilité d'avancer
 while (etat!=2){ // tant que la distance n'est pas suffisante
  etat=mesure(); // on effectue la mesure
  Serial.println(etat);
  tourneDroite(PRUDENT); //on fait tourner le robot
 }
 Serial.println("La voie est libre !");
 //retour au programme principal
 }

//Initialiser la carte

#include "WaveUtil.h"
  1. include "WaveHC.h"
  1. include "WaveUtil.h"
  2. include "WaveHC.h"


Carte SdReader ; // Cet objet contient les informations pour la carte. FatVolume vol ; // Ceci contient les informations pour la partition sur la carte FatReader racine ; // Ceci contient les informations du système de fichiers sur la carte

uint8_t dirLevel ; // niveau de retrait pour les noms de fichier / répertoire (pour prettyprinting) dir_t dirBuf ; // tampon pour les lectures de répertoire

WaveHC wave ; // C'est le seul objet wave (audio), puisque nous ne jouerons qu'un seul à la fois.


III/ FAIRE "PARLER" LE ROBOT


J'utilise ce site pour comprendre et suivre les étapes pour que mon robot puisse parler: https://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/solder

-Et j'utilise le Kit Adafruit Wave Shield pour Arduino - v1.1 : https://www.google.com/shopping/product/1?q=kit+Adafruit+Wave+Shield+pour+Arduino+-+v1.1&client=ms-android-samsung&biw=412&bih=652&tbs=vw:l,ss:44&prmd=sivn&prds=num:1,of:1,epd:15594950604929701068,paur:ClkAsKraX59nDazOXY9qSFMHlDclp4GBwRTiBT-BHcM9LYLNYGSlZZEpXNhEQN6mfYKT3XpWVnv0Y7fgutzNiEFiFXYwCwSslsdnrlxy4Mh-ijnzEIEftXHenhIZAFPVH72yU2k2ksjnwmZ8KScQrCTH96Vz9A,prmr:1,pid:15594950604929701068,cs:1

Code pour librairie HC have:

/*

* This example plays every .WAV file it finds on the SD card in a loop
*/
  1. include <WaveHC.h>
  2. include <WaveUtil.h>

SdReader card; // This object holds the information for the card FatVolume vol; // This holds the information for the partition on the card FatReader root; // This holds the information for the volumes root directory WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time

uint8_t dirLevel; // indent level for file/dir names (for prettyprinting) dir_t dirBuf; // buffer for directory reads


/*

* Define macro to put error messages in flash memory
*/
  1. define error(msg) error_P(PSTR(msg))

// Function definitions (we define them here, but the code is below) void play(FatReader &dir);

//////////////////////////////////// SETUP void setup() {

 Serial.begin(9600);           // set up Serial library at 9600 bps for debugging
 
 putstring_nl("\nWave test!");  // say we woke up!
 
 putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
 Serial.println(FreeRam());
 //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
 if (!card.init()) {         //play with 8 MHz spi (default faster!)  
   error("Card init. failed!");  // Something went wrong, lets print out why
 }
 
 // enable optimize read - some cards may timeout. Disable if you're having problems
 card.partialBlockRead(true);
 
 // Now we will look for a FAT partition!
 uint8_t part;
 for (part = 0; part < 5; part++) {   // we have up to 5 slots to look in
   if (vol.init(card, part)) 
     break;                           // we found one, lets bail
 }
 if (part == 5) {                     // if we ended up not finding one  :(
   error("No valid FAT partition!");  // Something went wrong, lets print out why
 }
 
 // Lets tell the user about what we found
 putstring("Using partition ");
 Serial.print(part, DEC);
 putstring(", type is FAT");
 Serial.println(vol.fatType(), DEC);     // FAT16 or FAT32?
 
 // Try to open the root directory
 if (!root.openRoot(vol)) {
   error("Can't open root dir!");      // Something went wrong,
 }
 
 // Whew! We got past the tough parts.
 putstring_nl("Files found (* = fragmented):");
 // Print out all of the files in all the directories.
 root.ls(LS_R | LS_FLAG_FRAGMENTED);

}

//////////////////////////////////// LOOP void loop() {

 root.rewind();
 play(root);

}

/////////////////////////////////// HELPERS /*

* print error message and halt
*/

void error_P(const char *str) {

 PgmPrint("Error: ");
 SerialPrint_P(str);
 sdErrorCheck();
 while(1);

} /*

* print error message and halt if SD I/O error, great for debugging!
*/

void sdErrorCheck(void) {

 if (!card.errorCode()) return;
 PgmPrint("\r\nSD I/O error: ");
 Serial.print(card.errorCode(), HEX);
 PgmPrint(", ");
 Serial.println(card.errorData(), HEX);
 while(1);

} /*

* play recursively - possible stack overflow if subdirectories too nested
*/

void play(FatReader &dir) {

 FatReader file;
 while (dir.readDir(dirBuf) > 0) {    // Read every file in the directory one at a time
 
   // Skip it if not a subdirectory and not a .WAV file
   if (!DIR_IS_SUBDIR(dirBuf)
        && strncmp_P((char *)&dirBuf.name[8], PSTR("WAV"), 3)) {
     continue;
   }
   Serial.println();            // clear out a new line
   
   for (uint8_t i = 0; i < dirLevel; i++) {
      Serial.write(' ');       // this is for prettyprinting, put spaces in front
   }
   if (!file.open(vol, dirBuf)) {        // open the file in the directory
     error("file.open failed");          // something went wrong
   }
   
   if (file.isDir()) {                   // check if we opened a new directory
     putstring("Subdir: ");
     printEntryName(dirBuf);
     Serial.println();
     dirLevel += 2;                      // add more spaces
     // play files in subdirectory
     play(file);                         // recursive!
     dirLevel -= 2;    
   }
   else {
     // Aha! we found a file that isnt a directory
     putstring("Playing ");
     printEntryName(dirBuf);              // print it out
     if (!wave.create(file)) {            // Figure out, is it a WAV proper?
       putstring(" Not a valid WAV");     // ok skip it
     } else {
       Serial.println();                  // Hooray it IS a WAV proper!
       wave.play();                       // make some noise!
       
       uint8_t n = 0;
       while (wave.isplaying) {// playing occurs in interrupts, so we print dots in realtime
         putstring(".");
         if (!(++n % 32))Serial.println();
         delay(100);
       }       
       sdErrorCheck();                    // everything OK?
       // if (wave.errors)Serial.println(wave.errors);     // wave decoding errors
     }
   }
 }

}

Ensuite j'ai converti un fichier audio sur audaciti et ensuite je l'ai mis sur la carte SD que jai ensuite remis sur l'arduino et donc maintenant le robot fais du bruit (un bruit de robot) à l'infinie :)

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils