Go Down

Topic: moteur pas à pas bipolaire (Read 27865 times) previous topic - next topic

Vincent

Normalement il suffit d'alterner 1010 et 0101 sur ton moteur. Pour qui tourne en continu tu fait ça en boucle, et pour un nombre de pas précis, il faut une boucle avec une limite et qui alterne 1010 et 0101.

jfs

#31
May 12, 2008, 08:56 am Last Edit: May 12, 2008, 10:08 am by jfs Reason: 1
Effectivement  ça devrait marcher, néanmoins il faut tout de même 4 phases pour qu'il tourne correctement. (1000, 0010, 0100, 0001 ou 1010, 0110, 0101, 1001)

J'ai tout repris à zéro (je soupçonne un décalage de phase).

En pas entier et une bobine alimentée j'ai maintenant 24 pas effectifs avec ce code ( je devrais tout de même en avoir 48):

Code: [Select]
int A_Pin = 13;    // H-bridge patte 1
int B_Pin = 9;     // H-bridge patte 2
int C_Pin = 10;    // H-bridge patte 9
int D_Pin = 12;    // H-bridge patte 15

int a;
int pos=7;
int i;

void Step_0();
void Step_1();
void Step_3();
void Step_5();
void Step_7();


void Step_0(){
   digitalWrite(A_Pin, LOW);    // 0
   digitalWrite(B_Pin, LOW);    // 0
   digitalWrite(C_Pin,LOW);     // 0
   digitalWrite(D_Pin,LOW);     // 0
}


void Step_1(){
   digitalWrite(A_Pin, HIGH);   // 1
   digitalWrite(B_Pin, LOW);    // 0
   digitalWrite(C_Pin,LOW);     // 0
   digitalWrite(D_Pin,LOW);     // 0
 }
void  Step_3(){
   digitalWrite(A_Pin, LOW);     // 0  
   digitalWrite(B_Pin, LOW);     // 0  
   digitalWrite(C_Pin, HIGH);    // 1  
   digitalWrite(D_Pin, LOW);     // 0  
 }
void  Step_5(){
   digitalWrite(A_Pin,LOW);      // 0  
   digitalWrite(B_Pin,HIGH);     // 1
   digitalWrite(C_Pin, LOW);     // 0  
   digitalWrite(D_Pin, LOW);     // 0
   }
void  Step_7(){
   digitalWrite(A_Pin,LOW);      // 0
   digitalWrite(B_Pin, LOW);     // 0  
   digitalWrite(C_Pin, LOW);     // 0  
   digitalWrite(D_Pin, HIGH);    // 1
   }



void setup() {
 pinMode(A_Pin, OUTPUT);                                                                    
 pinMode(B_Pin, OUTPUT);
 pinMode(C_Pin, OUTPUT);                                                                    
 pinMode(D_Pin, OUTPUT);
 }



int del = 4000;
int nb_pas = 1;

void loop() {
 

 
for  (i=0;i<nb_pas;i++)
{

if (i<=nb_pas && pos==7)
{
              Step_1();
                  pos=1;
                  delayMicroseconds(del);
                   i++;
}
if (i<=nb_pas && pos==1)
 {
                  Step_3();
             pos=3;
                  delayMicroseconds(del);
                   i++;
                 
}
if (i<=nb_pas && pos==3)
 {
   
              Step_5();
                   pos=5;
                  delayMicroseconds(del);
                  i++;
                 
}
if (i<=nb_pas && pos==5)
 {
                           

                  Step_7();
               pos=7;
                  delayMicroseconds(del);
                  i++;
                 
}

           
}
for (a=0;a< 1;a++)
{
delay (1000);
}

}


La variable "pos" est indispensable pour situer où le cycle s'est fini, sans elle on resterait toujours entre Step_1 et Step_3.

Je vais essayer en pas entier et deux bobines alimentées  :)


Edit: si je mets plus que 1 à nb_pas ça ne marche plus  :-/
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Vincent

Ca pourrait peut être venir du fait que i est incrémenter à la fois dans le for et dans les if, mais sans certitude.

Vincent

J'ai fait ça en me basant sur des pas entiers. J'ai testé avec des leds et c'est ok

Code: [Select]


int pinA = 1;
int pinB = 2;
int pinC = 3;
int pinD = 4;

int etatPin = 0;
int nbPas = 10;
int delaiEntrePas = 1000;
int i;

void setup()
{
 pinMode(pinA, OUTPUT);
 pinMode(pinB, OUTPUT);
 pinMode(pinC, OUTPUT);
 pinMode(pinD, OUTPUT);
}

void loop()
{
  for(i=0; i<nbPas; i++)
  {
    digitalWrite(pinA, etatPin);
    digitalWrite(pinB, ~ etatPin);
    digitalWrite(pinC, etatPin);
    digitalWrite(pinD, ~ etatPin);
 
    etatPin = ~ etatPin;
   
    delay(delaiEntrePas);
  }
 
  while(1)
  {
    // fin
  }
}




jfs

#34
May 12, 2008, 07:59 pm Last Edit: May 12, 2008, 09:15 pm by jfs Reason: 1
Je viens d'essayer ton code, l'aiguille que j'ai collé sur l'axe de mon moteur fait un pas en avant et un en arrière :-/ , cela 5 fois de suite puis s'arrête.  

Peux tu me commenter ces lignes ? (Edit : j'ai trouvé : http://www.arduino.cc/en/Reference/BitwiseXorNot)

Code: [Select]


    digitalWrite(pinD, ~ etatPin);
 
    etatPin = ~ etatPin;
   



Merci encore de te pencher sur mon problème de moteur  :)
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Vincent

Y'a pas de quoi  ;)

En fait je crois que je me suis trompé dans les pin. Essayes en changeant l'ordre des pin.
Pour le code :

Code: [Select]

// ~ permet d'avoir le complément de etatPin, en gros si etatPin = 0, pinD = 1 et vis versa
digitalWrite(pinD, ~ etatPin);

// idem, mais on complémente etatPin
etatPin = ~ etatPin;


Ceci permet donc d'avoir 0101 et 1010. Au début, etatPin = 0 donc on a 0101 puis on complémente etatPin, du coup on a 1010. Après faut dire que j'ai pas de moteur PAP donc je me rend pas compte si ça marche vraiment  :( .


jfs

#36
May 12, 2008, 09:18 pm Last Edit: May 12, 2008, 09:22 pm by jfs Reason: 1
J'ai éditer mon message précédent  ;).

j'ai interverti les pin, mais sans résultat, plus rien ne bouge.

La piste que tu ouvres avec ton code me parait excellente (merci), mais il fait jouer seulement deux pas, pour que ça avance il en faut minimum quatre (j'espère ne pas me tromper.. :-?)

Par contre il me semble qu'a un moment tout est à zéro ?
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Vincent

En fait pour des pas entiers, il suffirait pas d'avoir 1000, 0100, 0010, 0001 ?

jfs

Presque, comme ça on est en pas entier avec une bobine alimentée à la fois :

ABCD
1000
0010
0100
0001
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Vincent

#39
May 12, 2008, 10:58 pm Last Edit: May 12, 2008, 11:01 pm by Vincent Reason: 1
Alors essayes ça :

Code: [Select]

int pinA = 1;
int pinB = 2;
int pinC = 3;
int pinD = 4;

// ici il y a les séquences des différentes pin pour faire un tour
int etatPinA[4] = {1,0,0,0};
int etatPinB[4] = {0,0,1,0};
int etatPinC[4] = {0,1,0,0};
int etatPinD[4] = {0,0,0,1};

int nbPas = 5;
int i = 0;

int delaiEntrePas = 100;

void setup()
{
 pinMode(pinA, OUTPUT);
 pinMode(pinB, OUTPUT);
 pinMode(pinC, OUTPUT);
 pinMode(pinD, OUTPUT);
}

void loop()
{
 // ici on écrit sur la pin la séquence correspondante
 digitalWrite(pinA, etatPinA[i]);
 digitalWrite(pinB, etatPinB[i]);
 digitalWrite(pinC, etatPinC[i]);
 digitalWrite(pinD, etatPinD[i]);
 delay(delaiEntrePas);
 
 nbPas--;
 
 if((nbPas != 0) && (i != 3)) // si nbPas différent de 0 et i différent de 3, on passe au pas suivant
 {
   i++;
 }
 else if((nbPas != 0) && (i == 3)) // si nbPas différent de 0 et i égal à 3, on retourne au premier pas
 {
   i = 0;
 }
 else // si nbPas égal à 0 fin
 {
   while(1)
   {
     // fin
   }
 }
 
}



Je n'ai pas testé, mais je pense que ça devrait le faire, en tous cas si ça marche pas ça doit pas être grand chose.

Vincent

Du coup comme ça, si ça fonctionne, les demi pas devrait être assez simple à faire, il suffira de modifier la séquence et les conditions sur i

jfs

:) ça fonctionne, j'ai malgré tout du changé la fréquence "delaiEntrepas" et le passer à 7500000 et mettre "delayMicroseconds()" à la place de "delay()".

En dessous de 8 pas cela ne fonctionne pas et le nombre de pas programmés se retrouve divisés par 2 (pour un moteur 48 pas je dois mettre 96 pour un tour complet).
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Vincent

Pour la fréquence j'ai mis ça comme ça.
Par contre, bizarre pour cette histoire de pas..

jfs

#43
May 13, 2008, 10:07 pm Last Edit: May 13, 2008, 10:48 pm by jfs Reason: 1
Possible que ne connaissant pas la position du moteur, la séquence ne commence pas au bon endroit et le moteur se "fige", ce qui n'est peut-être pas le cas lors d'un séquence complète (8 pas programmés, 4 pas effectués).  :-?


En mettant les séquences ainsi :

Code: [Select]
int etatPinA[8] = {1,1,0,0,0,0,0,1};
int etatPinB[8] = {0,1,1,1,0,0,0,0};
int etatPinC[8] = {0,0,0,1,1,1,0,0};
int etatPinD[8] = {0,0,0,0,0,1,1,1};


On est en demi-pas, les positions sont doublées, mais en dessous de 16 pas ça ne marche pas.  Fréquence des pas à 1350 µsecondes.

Il faut mettre les positions à 7 à la place de 3 dans les conditions du bas.

A part ça l'idée d'utiliser des tableaux est vraiment bien  [smiley=thumbsup.gif]
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

jfs

#44
May 15, 2008, 07:49 pm Last Edit: May 15, 2008, 07:51 pm by jfs Reason: 1
Je me gratte un peu la tête sur ce problème de pas minimum...

Imaginons le moteur (utilisé en demi pas) dans une position de départ où le premier pas effectué sera avec une seule 1 bobine alimentée:


-On programme l'arduino pour faire 1 pas.
-On allume l'arduino, le moteur avance de 1 pas et se fige.
-On éteint l'arduino, le moteur se libère, mais il reste sur sa position. (la prochaine est avec 2 bobines alimentée)
-On rallume l'arduino, la première séquence est avec 1 bobine alimentée (donc celle où l'on se trouve), le moteur ne bouge pas et la séquence s'arrête.

Si mon raisonnement est juste il faut connaitre la position du moteur pour qu'au deuxième démarrage on commence la séquence au pas N°2.

Est-ce que je patauge dans la choucroute ?  ;D
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Go Up