Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Arduino] Contrôle de moteur DC via Grove I2C

    10 décembre 2013 à 17:41:15

    Bonjour les ex-zéros ! :p

    Je me suis finalement décidé à créer un topic sur ce forum après de longues recherches infructueuses sur le contrôle de moteur DC.

    Voici mon objectif : Je voudrais contrôler un moteur DC via une carte Grove I2C Motor Driver v1.2 reliée à mon Arduino Uno.

                                                                       Grove I2C Motor Driver 1.2  

    Après avoir longtemps chercher sur la référence officielle Arduino, sur le site d'Adafruit et de Seeeedstudio et avoir comparer de nombreux codes de contrôle de moteur DC, j'en suis au même point qu'au départ : Je ne comprend pas comment contrôler le moteur en ligne de commande.

    Je suis par exemple censé rattacher les bornes du moteur DC au module du moteur 1 (M1+ et M1-) et fournir une alimentation externe (ça c'est okay, l'alimentation fait tourner le moteur si je la connecte directement aux bornes de ce dernier.)

    Seulement je n'ai trouver nulle part de ligne qui déclare qu'un moteur est rattaché au module M1 et que les données de contrôle doivent être envoyées à ce module.

    Voici le code de démo de Seeedstudio sur lequel je me base : 

    #include <Wire.h>
    
    #define MotorSpeedSet             0x82
    #define PWMFrequenceSet           0x84
    #define DirectionSet              0xaa
    #define MotorSetA                 0xa1
    #define MotorSetB                 0xa5
    #define Nothing                   0x01
    
    #define I2CMotorDriverAdd         0x0f   // Set the address of the I2CMotorDriver
    
    void MotorSpeedSetAB(unsigned char MotorSpeedA , unsigned char MotorSpeedB)  {
      MotorSpeedA=map(MotorSpeedA,0,100,0,255);
      MotorSpeedB=map(MotorSpeedB,0,100,0,255);
      Wire.beginTransmission(I2CMotorDriverAdd); // transmit to device I2CMotorDriverAdd
      Wire.write(MotorSpeedSet);        // set pwm header 
      Wire.write(MotorSpeedA);              // send pwma 
      Wire.write(MotorSpeedB);              // send pwmb    
      Wire.endTransmission();    // stop transmitting
    }
    
    void MotorPWMFrequenceSet(unsigned char Frequence)  {    
      Wire.beginTransmission(I2CMotorDriverAdd); // transmit to device I2CMotorDriverAdd
      Wire.write(PWMFrequenceSet);        // set frequence header
      Wire.write(Frequence);              //  send frequence 
      Wire.write(Nothing);              //  need to send this byte as the third byte(no meaning)  
      Wire.endTransmission();    // stop transmitting
    }
    
    void MotorDirectionSet(unsigned char Direction)  {     //  Adjust the direction of the motors 0b0000 I4 I3 I2 I1
      Wire.beginTransmission(I2CMotorDriverAdd); // transmit to device I2CMotorDriverAdd
      Wire.write(DirectionSet);        // Direction control header
      Wire.write(Direction);              // send direction control information
      Wire.write(Nothing);              // need to send this byte as the third byte(no meaning)  
      Wire.endTransmission();    // stop transmitting 
    }
    
    void MotorDriectionAndSpeedSet(unsigned char Direction,unsigned char MotorSpeedA,unsigned char MotorSpeedB)  {  //you can adjust the driection and speed together
      MotorDirectionSet(Direction);
      MotorSpeedSetAB(MotorSpeedA,MotorSpeedB);  
    }
    
    void setup()  {
      Wire.begin(); // join i2c bus (address optional for master)
      delayMicroseconds(10000); //wait for motor driver to initialization
    }
    
    void loop()  {
      while(1)  {
        MotorSpeedSetAB(100,20);
        delay(10); //this delay needed
        MotorDirectionSet(0b1010);  //0b1010  Rotating in the positive direction 
        delay(1000); 
        MotorDirectionSet(0b0101);  //0b0101  Rotating in the opposite direction
        delay(500);
      }
    }

    Si j'ai bien compris, les lignes ci-dessous établissent les adresses des modules auxquels sont rattachés les moteurs. Seul hic ? Dans le code, ces adresses ne sont pas utilisées >_<

    #define MotorSetA                 0xa1
    #define MotorSetB                 0xa5

    Donc une question que je me pose tandis que je rédige ce sujet : Ce code est-il censé fonctionner sans que je n'y apporte aucun complément ? o_O

    Voici une liste de ce que je pense avoir compris :

    • Les arguments 0b0101 et 0b1010 sont en fait des arguments que le moteur comprendra comme "Fais tourner le moteur dans telle direction en changeant la polarité aux bornes du moteur)
    • A chaque fois que je transmet des données au moteur, je suis obligé d'écrire un "Wire.beginTransmission(Adresse de ma carte)" suivi des données à transmettre, puis d'un bit nul indiquant la fin des instructions et enfin d'un "Wire.endTransmission()" pour avorter la transmission.
    • Les lignes ci-dessous correspondent à des entêtes à envoyer via Wire.write() afin que la carte connaisse le "rôle" des données que j'enverrais juste après.
      #define MotorSpeedSet             0x82
      #define PWMFrequenceSet           0x84
      #define DirectionSet              0xaa
    Et voici la liste de ce que je n'ai pas compris :lol::
    • Comment déclarer qu'un moteur est rattaché à un des modules de la carte Grove I2C. Car je peux comprendre qu'on veuille établir une connexion avec la carte, mais pourquoi ne pas préciser en plus avec quel élément de cette carte ? Le devinerait-elle toute seule ? :magicien:
    • Qu'est ce que c'est que cette "PWM Fréquence" et à quoi sert-elle ? Suis-je obligé de l'utiliser pour contrôler mes moteurs ?

    Voila voila, en espérant avoir des éclaircissement, merci d'avance les ex-zéros ! :D
    • Partager sur Facebook
    • Partager sur Twitter
      10 décembre 2013 à 19:59:58

      Salut,

      Tu as déjà presque tout compris grâce au code, les constantes MotorSetA et MotorSetB servent à commander les moteur séparément. Le code exemple utilise les constantes DirectinoSet et MotorSpeedSet qui commandent les deux moteurs simultanément.

      Regarde la documentation : http://www.robotshop.com/media/files/pdf/datasheet-rob72212p.pdf

      La fréquence de la PWM, c'est la fréquence à laquelle ta tension d'alimentation est découpée. Pour plus d'info tape PWM ou MLI sur google.

      Tout cela n'explique pas pourquoi cela ne fonctionne pas, tu as bien configuré les switch pour l'adresse ? explication ici pour le savoir : http://www.seeedstudio.com/wiki/Grove_-_I2C_Motor_Driver_V1.2

      • Partager sur Facebook
      • Partager sur Twitter
        11 décembre 2013 à 15:53:43

        Merci pour tes indications et pour la doc !

        Donc c'est en réglant la fréquence de la PWM que je peux régler la vitesse du moteur ?

        J'ai par mégarde laisser branché mon petit système sans l'alimentation externe et sans faire de reset de l'arduino (Alimenté par le câble série), serait-il possible que ma carte Grove I2C soit endommagée sans que je le vois ? Car les LED d'indication de direction s'allument toujours mais le fait est qu'aucun code de contrôle de mon moteur ne passe :(

        J'ai écris ce code en espérant avoir compris la marche à suivre. Est-il correct ? (Je précise que lorsque je le téléverse, rien ne se passe d'où mon doute quant à l'intégrité de ma carte Grove I2C) :

        #include <Wire.h>
        
        #define CarteI2C 0x0f
        #define Moteur1 0xa1
        #define Fin 0x01
        
        void setup() {
          Wire.begin();
          delay(1000);
        }
        
        void loop() {
          Wire.beginTransmission(CarteI2C);
          Wire.write(Moteur1);
          Wire.write(0b10);
          delay(1500);
          Wire.write(Fin);
          Wire.endTransmission();
        }
        • Partager sur Facebook
        • Partager sur Twitter
          11 décembre 2013 à 19:27:57

          Salut,

          Non ton code ne peut pas faire tourner de moteur correctement, regarde bien :

          Chaque commande attends deux arguments.  La doc dit qu'il faut donner direction et vitesse après avoir utilisé la commande 0xa1.

          Si tu veut juste un mouvement pour tester la carte, tu peut mettre le code dans le setup, essaie avec ça :

          #include <Wire.h>
           
          #define CarteI2C 0x0f
          #define Moteur1 0xa1
          #define Fin 0x01
          
          //Direction
          #define FORWARD 0x01
          #define REVERSE 0x02
           
          void setup() {
            Wire.begin();
            delay(1000);
            Wire.beginTransmission(CarteI2C);
            Wire.write(Moteur1);
            Wire.write(REVERSE);
            Wire.write(100);
            Wire.endTransmission();
          }
           
          void loop() {
          while(1);
          
          }

          La vitesse n'est pas proportionnel à la fréquence de ta pwm mais à son rapport cyclique. C'est la proportion de temps pendant laquelle le signal est à l'état haut, c'est à dire alim ON. Tu règle ta vitesse en jouant sur ce rapport. Grossomodo, tu as un compteur qui compte en boucle jusqu'à 255 à une certaine vitesse(fréquence de ta PWM * 255). Quand le compteur repart à 0, ta sortie passe à 1 dans tout les cas et toi la vitesse que tu donne, c'est le moment à laquelle ta sortie redescend, c'est donc un nombre entre 0 et 255, et plus il est grand et plus ta sortie est longtemps à l'état haut.

          Essaie ce code et penses à vérifier que tes switch d'adresse sont bien positionnés.



          • Partager sur Facebook
          • Partager sur Twitter
            11 décembre 2013 à 19:43:11

            Non mon moteur ne tourne pas avec le code que tu m'as fourni. Et je suppose que ce n'est pas normal ;)

            Donc j'en déduit que ma carte Grove I2C est bien endommagée.. :(

            • Partager sur Facebook
            • Partager sur Twitter
              21 janvier 2014 à 20:16:07

              Bonjour,

              J'aimerai utiliser une carte grove i2c afin de faire tourner un moteur dans les 2 sens. Je précise que je n'ai pas besoin de modifier la vitesse de rotation ou bien de rajouter un deuxième moteur.

              En cherchant sur internet, j'ai trouvé plusieurs codes mais très peu d'explications sur leur signification. Je viens donc sur ce forum en espérant trouver des réponses à mes questions.

              Tout d'abord, à quoi correspondent les "0x0f, 0xa1", je me doute que c'est en base 16 mais je me demandais comment connaître le "numéro" que j'ai besoin car selon les codes, les numéros changent pour le moteur, la carte i2c...

              Ensuite, est-ce que j'ai besoin de configurer la fréquence PWM pour l'utilisation écrite ci-dessus? Si oui, pouvez-vous expliquer ce que cela change concrètement au niveau du moteur.

              Enfin, que signifie le #define fin?

              Merci d'avance pour vos réponses!

              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                22 janvier 2014 à 12:36:27

                La carte Grove I2Cest certainement un plus commercial pour des gros moteurs . Un rapport cyclique variable fera le

                même effet dans un transistor . Quel est l'ampérage de vos moteurs ?

                Un transistor 2N 2222 est passant jusqu' à 600 mA .

                • Partager sur Facebook
                • Partager sur Twitter
                  25 janvier 2014 à 10:14:22

                  J'ignore l’ampérage du moteur mais je sais que la batterie qui l'alimente a du courant de 1.2A en sortie.

                  Cependant ce n'est pas la vitesse du moteur que je désire pouvoir changer, c'est uniquement son sens.

                  J'ai déjà essayé de changer la rotation du moteur en utilisant 4 transistors (dont 2 2N2222) mais sans résultat.

                  -
                  Edité par Killluminatix 25 janvier 2014 à 10:15:26

                  • Partager sur Facebook
                  • Partager sur Twitter
                    25 janvier 2014 à 15:56:14

                    Pour bien comprendre comment fonctionne le pilotage d'un moteur à courant continu, je t'invite à lire la partie du tuto dédiée aux moteurs : http://eskimon.fr/285-arduino-601-le-moteur-courant-continu

                    Tu comprendras comment un pont en H fonctionne et tu verras pourquoi tes petite 2N2222 vont se mettre à fumer rapidos si tu continu.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Retrouvez moi sur mon blog et ma chaine Youtube !

                    Anonyme
                      25 janvier 2014 à 17:30:14

                      Passer par circuit intégré fait gagner du cablage :

                      http://mchobby.be/wiki/index.php?title=Pont-H_L293D

                      http://arduino103.blogspot.fr/2011/06/pont-h-transistor-pour-controler-un.html

                      :zorro:

                      • Partager sur Facebook
                      • Partager sur Twitter
                        25 janvier 2014 à 19:37:04

                        Ce que j'avais déjà essayé avec 4 transistors était bien un pont en H, je ne savais juste pas que ça s'appelait ainsi. Après n'avoir jamais réussi à faire tourner mon moteur avec un tel schéma, mon professeur m'a dit d'utiliser un motor shield grove I2C. J'ai donc abandonné l'idée du pont en H et je me suis renseigné sur ce motor shield, ce qui m'a amené ici. Le lien de Eskimon va m'être très utile. Merci à abuche pour ces éclaircissements sur le pont en H mais je vais utiliser un grove I2C donc tout sera déjà inclus dedans. Je vous remercie pour vos réponses.

                        -
                        Edité par Killluminatix 25 janvier 2014 à 20:13:56

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          25 janvier 2014 à 20:22:01

                          Motor shield , il y en a un qui sort tous les 6 mois . Faudrait déjà une référence avant de poser , ou de répéter

                          la " salade " d'un prof !

                          http://www.seeedstudio.com/wiki/Motor_Shield_V2.0#Demo_2:Drive_a_Stepper_Motor

                          • Partager sur Facebook
                          • Partager sur Twitter
                            11 juin 2014 à 13:08:25

                            Bonjour,

                            je ne sais pas si c'est encore d'actualité, mais j'ai développé une petite librairie pour piloter ce module sans se fatiguer...

                            Toutes les infos sont disponibles ici :

                            https://docs.google.com/document/d/1GKYt1Xt_V-GMoAMd6tpYQ3wSU-0rPhq1cQm4HAK8qmQ/pub

                            C'est bien entendu libre d'utilisation...

                            Bon Arduino à vous !

                            David Souder

                            • Partager sur Facebook
                            • Partager sur Twitter

                            [Arduino] Contrôle de moteur DC via Grove I2C

                            × 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