Go Down

Topic: Problème contrôle moteurs (liaison série). (Read 2000 times) previous topic - next topic

STI2D78

Bonjour à toutes et à tous,
Je suis nouveau sur ce forum. Je suis un pationé d'informatique qui réalise des études dans ce domaine (Terminale STI2D). J'ai une question à vous poser : Mon programme devrait marcher en théorie, mais en pratique, il ne fonctionne pas. Il est bien compilé vers ma carte arduino mega 2560, mais il est buggé : les moteurs ne réagissent pas du tout comme prévu. Je soupçonne la variable de type string d'être responsable de tout ces bugs. Je tiens à préciser que j'ai utiliser un motor shield de marque Adafruit pour cette réalisation.
Voilà mon programme :

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor1 = AFMS.getStepper(200, 1);
Adafruit_StepperMotor *myMotor2 = AFMS.getStepper(200, 2);

void setup() {
  Serial.begin(9600);
  AFMS.begin();
  myMotor1->setSpeed(1000);
  myMotor2->setSpeed(1000);
}

void loop()

  while(Serial.available()>0)
  {
    String chaine="";
    chaine = Serial.readStringUntil('\n');


    if (chaine=="m1")

    { 
      myMotor1->step(1000, FORWARD, SINGLE);
      Serial.println(chaine);
      chaine="";
    }

    if (chaine=="m2");
    {
      myMotor2->step(1000, FORWARD, SINGLE);
      Serial.println(chaine);
      chaine="";         
    }

    if (chaine=="m3");
    {
      int i=0;
      for (i=0;i=1000;i++)
      {
        myMotor1->step(1, FORWARD, SINGLE);
        myMotor2->step(1, FORWARD, SINGLE);
      }
      Serial.println(chaine);
      i=0;   
      chaine="";       
    } 

  }     
}

B@tto

Salut,

1) Je n'ai même pas lu ton code. Pourquoi ? on sait même pas ce que tu veux faire avec ...
2) "Marque adafruit" : c'est un peu comme si tu dis "j'ai acheté une renault, je mets quoi dans le moteur ? Du gasoil ou du sans plomb ?"
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

3Sigma


Je suis un pationé d'informatique


Ca tombe bien, tu vas pouvoir t'éclater avec les 3 facettes du développement: programmer (apparemment c'est fait), tester (ça aussi puisque tu as vu que ça ne marchait pas), debugger et apprendre à le faire (c'est pas le plus rigolo mais c'est indispensable).

C'est donc parti pour les conseils en débuggage de tonton 3Sigma. Le résultat final, ce sera que tu auras trouvé tout seul le problème sans que personne ne te dise ce qui foire dans ton code.
Etape n°1: qu'est-ce qui ne fonctionne pas ? La commande des moteurs ou la liaison série ?
Indice n°1: "je ne sais pas" ne fait pas partie des réponses possibles.
Indice n°2: pour répondre à la question, il faut faire 2 programmes: un avec uniquement la commande des moteurs, l'autre avec uniquement la lecture sur la liaison série.

STI2D78

Tout d'abord, merci de vos réponses qui m'ont, pour certaines, éclairé.

Etape n°1: qu'est-ce qui ne fonctionne pas ? La commande des moteurs ou la liaison série ?
J'ai fais ce que vous m'avez conseillé, c'est-à-dire de créer 2 programmes. Le programme de commande des moteurs fonctionne parfaitement (le soucis ne vient donc pas de ce côté là). Et le programme de la liaison série fonctionne lui aussi. Je me suis donc longuement penché sur mon programme général pour savoir pourquoi je ne pouvais pas commander mes moteurs par liaison série. J'ai trouvé certaines erreurs et je les ai ensuite corrigées.  Mon nouveau programme fonctionne donc aux petits oignons, mais, une erreur (assez gênante) persiste. Mon programme récupère les chaînes de caractères rentrées dans le Serial monitor (ou envoyées depuis un logiciel fait en C#), les interprètes et effectue des actions. Exemple : j'envoie un "A", le programme effectue l'action A; j'envoie un"B", le programme effectue l'action B et ainsi de suite. L'erreur est donc celle ci : Le programme reconnaît les chaînes rentrées (il les affiche dans le monitor), mais il effectue soit l'action A, soit l'action B (quelle que soit la commande envoyée). En gros, si j'envoie un "A", il fait l'action A et si j'envoie n'importe quelle autre lettre, il fait l'action B. J'ai donc besoin de votre aide sur ce point. Merci d'avance pour vos réponses.


#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor1 = AFMS.getStepper(200, 1);
Adafruit_StepperMotor *myMotor2 = AFMS.getStepper(200, 2);

void setup() {
  Serial.begin(9600);
  AFMS.begin();
  myMotor1->setSpeed(1000);
  myMotor2->setSpeed(1000);
}

void loop()

debut:

  while(Serial.available()>0)
  {
    String chaine;
    chaine = Serial.readStringUntil('\n');

    if (chaine=="moteur1")
    { 
      myMotor1->step(1000, FORWARD, SINGLE);
      Serial.println(chaine);
      goto debut;     
    }

    if (chaine=="moteur2");
    {
      myMotor2->step(1000, FORWARD, SINGLE);
      Serial.println(chaine);
      goto debut;         
    }

    if (chaine=="moteur3");
    {
      myMotor1->step(1000, BACKWARD, SINGLE);
      Serial.println(chaine);
      goto debut;       
    } 

    if (chaine=="moteur4");
    {
      myMotor2->step(1000, BACKWARD, SINGLE);
      Serial.println(chaine);
      goto debut;       
    } 
  }     
}






Merci encore une fois pour avoir pris le temps de me lire.

B@tto

Aie aie aie ... déjà oublie goto. En plus aucun intérêt.

Ensuite il manque des choses avant le while :

Code: [Select]
if(Serial.available()) {
delay(5); // sinon le buffer n'a pas le temps de se remplir
while(Serial.available()>0)
...
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

fdufnews


Non B@tto, il utilise la méthode readStringUntil qui attend un caractère (la fin de ligne en l'occurence) pour retourner.

En fait l'erreur est bien plus bête
Code: [Select]
   if (chaine=="moteur1")
    { 
      myMotor1->step(1000, FORWARD, SINGLE);
      Serial.println(chaine);
      goto debut;     
    }

    if (chaine=="moteur2");                                        // <--- OH la grosse boulette
    {
      myMotor2->step(1000, FORWARD, SINGLE);
      Serial.println(chaine);
      goto debut;         
    }


A part pour le premier test, sur tous les autres tu as mis un point virgule  après le test donc il est inopérant.
Si tu n'avais pas mis des goto tu t'en serais aperçu tout de suite car tu aurais déroulé toutes les conditions les unes après les autres.

Les goto c'est le diable, il faut les proscrire. En plus dans ton cas ils sont parfaitement inutiles puisque toutes les séquences sont comprises dans un if et sont mutuellement exclusives.

B@tto

Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

STI2D78

Tout d'abord, un grand merci pour vos réponses rapides et précises.
En fait, j'ai placé des goto car mon programme déroulait toutes les conditions en même temps (comme tu l'as dit).
Oui, tu as raison, c'est "la grosse boulette". Ce qui montre bien qu'on est pas à l'abri des erreurs bêtes... (la faute a un copié-coller pour aller plus vite  :~ ).
Du coup, je n'ai pas besoin du delay(5) ?

STI2D78

Je suis épaté ! Le système marche nickel  :smiley-eek:
Encore une fois (et au risque de me répéter) MERCI BEAUCOUP.
Je dois vous avouer que le fait que vous portez de l'attention à un nouveau comme moi m'a énormément plu. Vous comptez maintenant un nouveau dans vos rangs.
Commentaire à deux balles pour terminer : c'est fou comment on peut faire énormément de choses avec une carte arduino (et ça devient encore plus impressionnant quand on couple ça a du C# pour faire des Windows Forms).

Go Up