[Non réglé] Programmer un moteur pas à pas

Bonjour,

Je suis assez nouveau dans le Arduino et on me demande de faire un projet dans lequel je dois pouvoir contrôler un moteur à pas. Dans l'image ci-jointe, on voit mon projet "matériellement" (désolé pour le cable management je suis pas le meilleur). Je ne peux pas changer le projet tel que représenté ainsi (ou du moins pas beaucoup, si vous avez des recommandations vous pouvez quand même les faire).

Mon souci, c'est qu'avec le premier bouton, le moteur doit s'enclencher et avec le 2ème, je dois pouvoir changer le sens du moteur, mais rien ne fonctionne... Voici mon code :

int activation=0,sens=0;

void setup()
{
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,INPUT);
  pinMode(12,INPUT);
}

void loop()
{
  switch(digitalRead(12)) {
    case 0 : break;
    case 1 : activation=!activation;
    	break;}
  switch(digitalRead(11)) {
    case 0 : break;
    case 1 : sens=!sens;
    	break;}
  if(activation&&sens) {
    digitalWrite(9,LOW);
    digitalWrite(10,HIGH);
  }else{if(activation&&!sens) {
    digitalWrite(10,LOW);
    digitalWrite(9,HIGH);
  }else{if(!activation) {
    digitalWrite(10,LOW);
    digitalWrite(9,LOW);
  }}}
  
  delay(100);
}

J'espère que vous pourrez m'aider,

Merci de votre compréhension et bonne journée à tous!

je n'ai pas regardé le montage mais quand vous faites cela

   switch(digitalRead(12)) {
    case 0 : break;
    case 1 : activation=!activation;
    	break;}

comme votre arduino pédale super vite par rapport au temps "humain" vous allez basculer la valeur d'activation sans doute plusieurs milliers de fois durant l'appui du bouton... la valeur finale est donc plus ou moins aléatoire en fonction du temps d'appui

==> vous ne pouvez pas gérer un bouton comme cela, ce qui compte ce n'est pas l'état dans lequel il est, mais le CHANGEMENT d'état (pour détecter l'appui, c'est donc une transition, un front)

Si vous avez le droit aux bibliothèques externes, pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau

PS: appuyez sur ctrl-T dans l'IDE, votre code sera indenté et ce sera plus simple à lire...

Salut,
Attention, met tes variables activation et sens en bool (0-1).. sinon tu inverse une variable int qui se situe entre -32767 à +32767 et tu risques d'avoir des soucis

bool activation = 0, sens = 0;

mskna17:
Salut,
Attention, met tes variables activation et sens en bool (0-1).. sinon tu inverse une variable int qui se situe entre -32767 à +32767 et tu risques d'avoir des soucis

bool activation = 0, sens = 0;

Sur le fond, oui ce serait mieux que ce soit des booléens. En C++ c'est un type à part entière et donc ça ne "vaut" pas 0 et 1, ça vaut vraiment faux et vrai

Sur la forme ça fonctionne à cause de la promotion automatique des entiers vers une valeur de vérité (bool) lors de l'application d'un opérateur booléen (! not) sur un entier

quand vous faites !0 le 0 est d'abord changé (promu) en false par le compilateur, et donc ! false, c'est true et comme on stocke ça ensuite dans un int, il y a la promotion inverse, true est traduit en 1. Ce sont des règles qui font partie de la norme du C++

=> Donc on va bien alterner entre 0 et 1

mskna17:
Attention, met tes variables activation et sens en bool (0-1).. sinon tu inverse une variable int qui se situe entre -32767 à +32767 et tu risques d'avoir des soucis

Effectivement il vaut mieux définir les variable en bool.

Cependant il n'y a pas de problème si ce sont des int. ! est un opérateur logique, donc !activation vaut true si activation est 0 et false si activation est différent de 0.

Oups, grillé par J-M-L

J-M-L:
je n'ai pas regardé le montage mais quand vous faites cela

   switch(digitalRead(12)) {

case 0 : break;
   case 1 : activation=!activation;
    break;}



comme votre arduino pédale super vite par rapport au temps "humain" vous allez basculer la valeur d'activation sans doute plusieurs milliers de fois durant l'appui du bouton... la valeur finale est donc plus ou moins aléatoire en fonction du temps d'appui

==> vous ne pouvez pas gérer un bouton comme cela, ce qui compte ce n'est pas l'état dans lequel il est, mais le CHANGEMENT d'état (pour détecter l'appui, c'est donc une transition, un front)

Si vous avez le droit aux bibliothèques externes, pour simplifier votre gestion des boutons, éventuellement utilisez [la librairie de @bricoleau](http://forum.arduino.cc/index.php?topic=375232.0) 


PS: appuyez sur ctrl-T dans l'IDE, votre code sera indenté et ce sera plus simple à lire...

Non, je n'ai malheureusement pas le droit à des bibliothèques externes. Sinon, normalement, pour ce qui est du bouton, on est censé pouvoir recevoir une valeur 0 ou 1 selon si on le presse ou non grâce à l'INPUT_PULLUP ou à une résistance mise manuellement de 10kOhms (corrigez-moi si je me trompe). Dans mon cas j'ai essayé la résistance externe.

Sinon je viens de passer mes variables en bool, normalement en C ça ne fait pas de grande différence.

Par contre, suite à un essai avec débogueur, j'ai remarqué que mes valeurs restent toujours à 0. L'Arduino ne détecte donc pas les changements effectués

Le problème n'est pas de recevoir 0 ou 1 lorsque le bouton est actif, mais de faire l'action uniquement si il y a eu changement d'état du bouton.
Pour cela il faut que tu mémorises l'état précédent du bouton et que tu le compares à l'état courant.

Seul souci à cette solution je crois : il fonctionnera donc bel et bien comme un bouton. Or, je dois pouvoir le faire fonctionner comme un interrupteur (si j'appuie et lâche le bouton "activation", le moteur doit s'activer (ou se désactiver s'il est déjà actif))

pour ce qui est du bouton, on est censé pouvoir recevoir une valeur 0 ou 1 selon si on le presse ou non

Vous ne recevez rien du tout, vous lisez l’état. La loop tournant plusieurs milliers de fois par seconde vous allez lire cet état "Bouton appuyé" au moins plusieurs centaines de fois si vous le tenez une seconde enfoncé et donc vous inversez l’état autant de centaines de fois, ce qui fait que la valeur résultant est plus ou moins aléatoire

Ce que vous voulez c’est inverser la valeur lorsque le bouton change d’état pour un appui, une seul fois, et ne pas continuer à changer tant qu’il n’a pas été relâché

lire les tutos d’eskimon, et notamment l’article Un simple bouton. vous y verrez plus clair

Oui c'est ça. Pour y arriver, j'ai essayé de placer un delay(100) à la fin de mon loop. Comment devrais-je m'y prendre ?

nitrouille:
Comment devrais-je m'y prendre ?

Comme je te l'ai indiqué: en comparant l'état du bouton à l'état précédent pour voir s'il vient d'être appuyé.

Une autre remarque: le titre est «Programmer un moteur pas à pas», mais ni le schéma ni le programme ne correspondent à un moteur pas à pas, mais plutôt à un moteur à courant continu.

Même avec un delay(100) votre boucle va tourner 10 fois par seconde...

Lisez et comprenez le tuto posté précédemment

Le titre devrait plutôt être : Programmer/commander un moteur Courant Continu

Erreur de cablage sur ton circuit tel qu'il est présenté sur l'image "Capture.png" :

  1. Il manque les condensateurs de découplage sur les alims du L293D (broche 8 : 1µF et
    broche 16 : 0,1µF)
  2. Il manque des condensateurs pour anti rebond : 22nF en // des boutons (compensé par le soft)
  3. Il faut forcer la broche 9 (3.4EN) du L293D au +5v de façon à activer les drivers 3 & 4
    du circuit ==> relier la ligne 29-ghij au +5v.
    NOTA: Cette broche 9 du L293D peut aussi servir à contrôler la vitesse de rotation et le freinage du moteur

A quoi servent les 3 résistance de 220 Ω au centre de la plaque d'essai ?

Sinon, pour le soft tu peux essayer ceci (avec contrôle de vitesse de rotation) :
Si problème, ou besoin de modifs : me demander.

bool activation = false, sens = false;
bool Btn1_state = false, Btn2_state = false;
bool Btn_Action = false;
int Rebond = 50;    // A ajuster en fonction de test sur le circuit


void setup()
{	
  pinMode(A5, INPUT);	// contrôle vitesse de rotation	
  pinMode(6, OUTPUT);	// contrôle vitesse de rotation
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(LED_BUILTIN, LOW);
  
  delay(500);
}

void loop() {

  do {
    switch (digitalRead(12)) {
      case 0:
        Btn1_state = false ;
        break;
      case 1:
        delay(Rebond);
        if ( (digitalRead(12)) && !Btn1_state) {
          activation = !activation;
          Btn1_state = !Btn1_state;
          Btn_Action = true;
        }
        break;
    }

    switch (digitalRead(11)) {
      case 0:
        Btn2_state = false ;
        break;
      case 1:
        delay(Rebond);
        if ( (digitalRead(11)) && !Btn2_state) {
          sens = !sens;
          Btn2_state = !Btn2_state;
          Btn_Action = true;
        }
        break;
    }
    analogWrite(6, map(analogRead(A5),0,1023,0,255));	// contrôle vitesse de rotation	
  }
  while (!Btn_Action);

  digitalWrite(LED_BUILTIN, activation);
  Btn_Action = false;
  
  if (activation) {
    switch (sens) {
      case 0:
        digitalWrite(9, LOW);
        digitalWrite(10, HIGH);
        break;
      case 1:
        digitalWrite(9, HIGH);
        digitalWrite(10, LOW);
        break;
    }
  }
  else {
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
  }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.