Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino : Robot qui s'arrete "sans raisons"

Enfin surement que si hein mais je vois pas ^^

    14 février 2017 à 12:43:34

    Bonjour à tous,

    Voila je suis sur le cours avancé d'Arduino après avoir réussi le premier, mais avant d'allez trop loin je voulais essayer de me faire un bête petit robot. Mais voila, se n'est pas encore C3-PO qu'il est déjà borné !!!

    Je m'explique : 

    C'est un simple plateau muni de 2 roues motorisé (1 moteur qui fonctionne dans les 2 sens par roue) et d'une roue libre, sur le dit plateau j'ai installé 3 SRF05 (1 frontal et 1 de chaque coté).

    Lorsque je le met en route, il roule à pleine vitesse tant que la distance libre à l'avant est de 100cm, puis ralentit de moitié tant qu'il y a au moins 21cm avant de s’arrêter.

    Une fois à l’arrêt, il "sonde" à droite puis à gauche et en fonction du coté disposant de la plus grande distance, il tourne.

    Jusque là rien de bien sorcier me direz vous ... et bien si, justement, le bougre va fonctionner de 1 à 10 fois (grosso modo) puis s’arrêter ... et ne plus rien faire jusqu’à se que je passe la main devant le détecteur frontal au quel cas il va re-fonctionner peut être 1 ou 3 fois et de nouveau s’arrêter...

    Pourtant sur l'affichage console tout semble bon (je n'ai malheureusement pas de câble assez long pour le tester avec les moteurs en route donc les valeurs console ne sont afficher qu'avec les moteurs éteints).

    Voici le code :

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    
    /**
     * declaration des variables et objets
     */
    Adafruit_MotorShield monShield = Adafruit_MotorShield();//objet pour communiquer avec le motor shield
    
    Adafruit_DCMotor *moteurGauche = monShield.getMotor(3);//pointeur sur moteur gauche relier sur le plot m3
    Adafruit_DCMotor *moteurDroit = monShield.getMotor(2);//pointeur sur moteur droit relier sur le plot m2
    
    const int PIN_SRF_AVANT = 3;//pin du scan SRF avant
    const int PIN_SRF_ARRIERE = 4;//pin du scan SRF arriere
    const int PIN_SRF_DROITE = 5;//pin du scan SRF droit
    const int PIN_SRF_GAUCHE = 6;//pin du scan SRF gauche
    
    const int VIT_SON = 59;//valeur en µSec de la vitesse d'un allez retour du son sur 1cm
    const int NBR_MESURE = 10;//Nombre de mesure que doit effectuer le SRF05 afin d'avoir une moyenne
    
    /**
     * Setup :
     * on y initialise la communication avec le motor shield
     */
    void setup() {
      monShield.begin();//activation de la communication avec le shield
      Serial.begin(9600);//activation de la console
    }
    
    /**
     * Loop :
     */
    void loop() {
      /**Action en fonction de la distance calculé**/
      int distanceAvant = BalayageUS(PIN_SRF_AVANT);//appel de la fonction de scan US vers l'avant
      int distanceDroite = 0;//initialisation de la variable de stockage de la distance dispo sur la droite
      int distanceGauche = 0;//initialisation de la variable de stockage de la distance dispo sur la gauche
    
      Serial.print("Distance avant : ");
      Serial.println(distanceAvant);
    
      if(distanceAvant >= 100) {//Si la distance vers l'avant est superieur a 100cm
        EnAvant();//on lance la fonction EnAvant    
      }else if(distanceAvant < 100 && distanceAvant >= 30) {//sinon si la distance vers l'avant est entre 100 et 30cm
        EnAlerteAvant();//on lance la fonction d'alerte en avant
      }else if(distanceAvant < 30) {//sinon si distance vers l'avant est inferieur ou egale a 30cm
        Stop();//on appel la fonction de stop
        
        distanceDroite = BalayageUS(PIN_SRF_DROITE);//appel de la fonction de scan US vers la doite
        Serial.print("Distance droite : ");
        Serial.println(distanceDroite);
        
        distanceGauche = BalayageUS(PIN_SRF_GAUCHE);//appel de la fonction de scan US vers la gauche
        Serial.print("Distance gauche : ");
        Serial.println(distanceGauche);
    
        ChoixRotation(distanceDroite, distanceGauche);//appel la fonction qui defini le sens de rotation
      }
    }
    
    /**
     * Fonctions de gestion des mouvements et scan
     * 
     * CheckOK : Verifie au lancement que tout se passe bien et retourne 1 au loop pour dire que l'on peu faire fonctionner
     * 
     * EnAvant : Gerera le deplacement vers l'avant tant qu'il n'y a pas d'obstacle a moins de 100cm. Ralentira entre 100 et 30cm puis stopera
     * EnAlerteAvant : Reduit la vitesse de marche avant si un obstacle est entre 100 et 30 cm
     * Stop : Gerera l'arret si un obstacle est a moins de 30cm
     * ChoixRotation : Determine le sens dans le quel doit tourner le robot en fonction des valeur distanceDroite et distanceGauche du loop
     * TourneADroite : Fera tourner de 90° vers la droite
     * TourneAGauche : Fera tourner de 90° vers la gauche
     * EnArriere : Gerera le deplacement vers l'arriere afin d'eviter de toucher lors de AGauche ou ADroite
     * BalayageUS : Gere le scan US en fonction du pin envoyé en parametre
     */
     /**********Fonction EnAvant**********/
     void EnAvant() {
      moteurGauche -> setSpeed(255);//definition de la vitesse de rotation
      moteurDroit -> setSpeed(255);//des deux moteur au max
      
      moteurGauche -> run(FORWARD);//fait fonctionner les moteurs
      moteurDroit -> run(FORWARD);//dans le sens marche avant
     }
    
     /**********Fonction EnAlerteAvant**********/
     void EnAlerteAvant() {
      moteurGauche -> setSpeed(127);//reduit la vitesse de moitier
      moteurDroit -> setSpeed(127);//des deux moteurs
     }
    
     /**********Fonction Stop**********/
     void Stop() {
      moteurGauche -> run(RELEASE);//stop les
      moteurDroit -> run(RELEASE);//deux moteurs
     }
    
     /**********Fonction ChoixRotation**********/
     void ChoixRotation(int distanceDroiteRecu, int distanceGaucheRecu) {
      /**Condition pour savoir de quel coté tourner**/
      if(distanceDroiteRecu >= distanceGaucheRecu) {//si la distance dispo a droite est superieur ou egale a celle dispo a gauche
        TourneADroite();//on tourne a droite
      }else if(distanceDroiteRecu < distanceGaucheRecu) {//sinon si distance dispo a droite inferieur a celle de gauche
        TourneAGauche();//on tourne a gauche
      }
     }
    
     /**********Fonction TourneADroite**********/
     void TourneADroite() {
      EnArriere();//on recule pendant 1/4sec pour eviter...
      delay(250);//...de toucher en tournant
      
      moteurGauche -> run(FORWARD);//fait tourner le moteur dans le sens de la marche
      moteurDroit -> run(RELEASE);//stop le moteur droit
      delay(250);//pendant 1/4sec
      
      moteurGauche -> run(RELEASE);//On stop la rotation
      delay(250);//petit delais le temps de faire les nouvelles mesures
     }
    
     /**********Fonction TourneAGauche**********/
     void TourneAGauche() {
      EnArriere();//on recule pendant 1/4sec pour eviter...
      delay(250);//...de toucher en tournant
      
      moteurGauche -> run(RELEASE);//stop le moteur gauche
      moteurDroit -> run(FORWARD);//fait tourner le moteur droit dans le sens de la marche
      delay(250);//pendant 1/4sec
      
      moteurDroit -> run(RELEASE);//on stop la rotation
      delay(250);//petit delais le temps de faire les nouvelles mesures
     }
    
     /**********Fonction EnArriere**********/
     void EnArriere() {
      moteurGauche -> run(BACKWARD);//fait tourner les deux moteur
      moteurDroit -> run(BACKWARD);//dans le sens inverse de la marche
     }
    
     /**********Fonction BalayageUS**********/
     int BalayageUS(int srfChoisi) {
      
      unsigned long mesure = 0;//contiendra la moyenne des mesure effectue
      unsigned long cumul = 0;//contiendra la valeur de chacune des 10 prises
    
      //boucle de prise de mesure (s'effectue 10 fois et cumul les resultats dans mesure
      for(int i = 0; i < NBR_MESURE; i++) {
        pinMode(srfChoisi, OUTPUT);//on configure le pin en mode emetteur
        digitalWrite(srfChoisi, LOW);//on initialise le pin en etat bas
    
        delayMicroseconds(2);//delais d'attente pour eliminer les parasytes entre chaque mesure
    
        digitalWrite(srfChoisi, HIGH);//on emet le signal...
        delayMicroseconds(10);//...pendant 10 µSec...
        digitalWrite(srfChoisi, LOW);//...on coupe le signal
    
        pinMode(srfChoisi, INPUT);//on passe en mode recepteur
        mesure = pulseIn(srfChoisi, HIGH);//fonction native pulseIn qui calcul le temps entre emission et reception du signal US
    
        cumul += mesure;//on aditionne les 10 mesures prise
        delay(50);//delais obligatoire entre chaque prise
      }
    
      mesure = cumul / NBR_MESURE;//on divise le total des mesure par le nombre de prise afin de faire la moyen
      mesure = mesure / VIT_SON;//on converti la mesure en cm
    
      return mesure;//on renvoi la mesure moyenne en cm
     }

    Voila j’espère que vous pourrez m'aider, d'avance merci et si besoin d'autre précision je suis à l’écoute :)

    • Partager sur Facebook
    • Partager sur Twitter

    Arduino : Robot qui s'arrete "sans raisons"

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown