Help : Moteur pas à pas et fourche optique

Bonjour bonjour!

J'ai pour projet un robot à câble :slight_smile:
Il s'agit de 3 moteurs pas à pas qui enroulent et déroulent des câbles qui sont liés en un point

Les dispositifs fonctionnent avec un moteur pas à pas et une fourche optique pour contrôler le déroulement et l'enroulement des câbles. Ce qui permet de rectifier les erreurs de sur-épaisseur et de décalage des câbles.

J'envoie ensuite des suites de vitesses et de nombres de tours effectués sous la forme d'arrays.

Le problème et que je bute sur le code :fearful:

#include <AccelStepper.h>
#define STEPPER1_DIR_PIN 6
#define STEPPER1_STEP_PIN 7

AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);

int MOTOR_0_SPEED_FLOOR_[][4] = {
  { -1089, -655, -1536, -289},
  { -984, -1415, -580, -1688},
  { -1128, -719, -1503, -375},
  { -987, -1350, -629, -1545},
  { -991, -1352, -619, -1485},
  { -1090, -737, -1363, -458},
  { -1086, -740, -1326, -476},
};

int MOTOR_0_NUMBER_TOOTH_FLOOR_[][4] = {
  {130, 86, 172, 42},
  {126, 171, 82, 209},
  {149, 103, 193, 60},
  {140, 183, 98, 219},
  {147, 194, 102, 229},
  {166, 122, 209, 85},
  {173, 128, 216, 93},
};



const int fourchePin1 = 11;     //Sortie de la fourche pin11



int a = 1;                      //Numéro de la ligne
int b = 1;                      //Numéro de la colonne

int State1 = 0 ;                //Etat Fourche1
int Old_State1 = 0;              //Ancien Etat Fourche1


int i;                          //Valeur nombre de pas stepper1

// Initialisation
void setup() {

  stepper1.moveTo(1600 * 20);                        //Distance infinie stepper1

}
void loop()
{

  for (a = 0; a < 7; a++)
  {
    for (b = 0; b < 4; b++)
    {
      stepper1.setMaxSpeed(MOTOR_0_SPEED_FLOOR_[a][b]);                     //Vitesse stepper1
      stepper1.setAcceleration(MOTOR_0_SPEED_FLOOR_[a][b]);                 //Acceleration stepper1

      State1 = digitalRead(fourchePin1);                                    //Etat de la Fourche
      if (State1 != Old_State1)                                             //Mesure entre l'état de la fourche et la valeur suivante
      {
        i = i + 1;                                                          //Incrémentation
        Old_State1 = State1;
      }
      if (i > MOTOR_0_NUMBER_TOOTH_FLOOR_[a][b])                             //Arret stepper1
      {
        stepper1.run();
      }

    }
  }
}

Les variables a et b correspondent aux lignes et colonnes des vitesses et du nombre de tours à effectuer mais rien n'y fait....

Merci d'avance de vos réponses :smiley:

ludwigh:
Le problème et que je bute sur le code :fearful:
Les variables a et b correspondent aux lignes et colonnes des vitesses et du nombre de tours à effectuer mais rien n'y fait....

bonsoir
Ton projet à l'air sympa , mais je crois que tu a "trop la tete dans le guidon" :grin:
Perso meme apres relectures, je n'ai pas compris ce que tu demande au forum .
qu'est ce que tu souhite faire , et que ton code "ne fait/realise" pas ?

Bonjour Artouste!

Je viens de me relire et effectivement ça ne doit pas être très clair :s

Le but de ce code est d'envoyer une suite de vitesses et de distances.
Il s'agit donc d'une double boucle avec les paramètres a et b pour utiliser chacune des variables dans mon tableau d'array.

Un fois que ma variable i (qui compte le nombre de tour) devient supérieur ou égale à la valeur indiquée dans mon tableau (qui correspond à la valeur finale du nombre de tour à effectuer), je voudrais passer aux variables suivantes dans mon tableau.

Je ne vois pas ce qui cloche dans mon code car normalement c'est ce que devrait faire ma double boucle :frowning:

En fait, je trouve bizarre la façon dont se déroule ton programme.

Jusqu'aux boucles imbriquées ok, l'endroit et la façon dont tu utilises la fourche me semble bizarre. Si le but est de compter les tours c'est raté je pense. Car là, la seule chose que ça te dit, c'est si entre 2 itérations des boucles for, ton axe à "potentiellement" bougé, car même pour ça, ça me semble hazardeux comme concept.

Si tu veux compter les tours avec la fourche, il faudrait que tu implémentes une interruption plutôt

Bonjour vohu,

Ce code ci dessous représente l'interruption entre l'état obstrué et l'état non obstrué. Ainsi à chaque fois que l'état change i est incrémenté de +1. Pour le coup je suis en train de tester séparément et c'est la seule partie qui fonctionne quand je fais tourner la poulie de la fourche :slight_smile:

    State1 = digitalRead(fourchePin1);                                    //Etat de la Fourche 
    if (State1 != Old_State1 & i < MOTOR_0_NUMBER_TOOTH_FLOOR_[1][b])                                         //Mesure entre l'état de la fourche et la valeur suivante
    {

      i = i + 1;                                                          //Incrémentation
      Old_State1 = State1;
      Serial.println(i);
      Serial.println(MOTOR_0_NUMBER_TOOTH_FLOOR_[1][b]);
      //Serial.println(b);
  }

J'essaie en ce moment de simplifier la mise en marche pour comprendre ce qui ne va pas. En ce moment j'essaie juste d'utiliser le paramètre b et de faire la boucle juste sur une colonne. Mais dès que i arrive à la valeur de 82 il repasse à 0 :s

//#include <AccelStepper.h>
//#define STEPPER1_DIR_PIN 6
//#define STEPPER1_STEP_PIN 7

//AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);

int MOTOR_0_SPEED_FLOOR_[][4] = {
  { -1089, -655, -1536, -289},
  { -984, -1415, -580, -1688},
  { -1128, -719, -1503, -375},
  { -987, -1350, -629, -1545},
  { -991, -1352, -619, -1485},
  { -1090, -737, -1363, -458},
  { -1086, -740, -1326, -476},
};

int MOTOR_0_NUMBER_TOOTH_FLOOR_[][4] = {
  {130, 86, 172, 42},
  {126, 171, 82, 209},
  {149, 103, 193, 60},
  {140, 183, 98, 219},
  {147, 194, 102, 229},
  {166, 122, 209, 85},
  {173, 128, 216, 93},
};



const int fourchePin1 = 11;     //Sortie de la fourche pin11



int a;                      //Numéro de la ligne
int b;                      //Numéro de la colonne

int State1 = 0 ;                //Etat Fourche1
int Old_State1 = 0;              //Ancien Etat Fourche1


int i;                          //Valeur nombre de pas stepper1

// Initialisation
void setup() {
  Serial.begin(9600);
  // stepper1.moveTo(1600 * 20);                        //Distance infinie stepper1

}
void loop()
{


  //stepper1.setMaxSpeed(MOTOR_0_SPEED_FLOOR_[a][b]);                     //Vitesse stepper1
  //stepper1.setAcceleration(MOTOR_0_SPEED_FLOOR_[a][b]);                 //Acceleration stepper1
  State1 = digitalRead(fourchePin1);
  for (b = 0; b < 4; b++)
  {
    if ( i < MOTOR_0_NUMBER_TOOTH_FLOOR_[1][b])
    {
      if (State1 != Old_State1 )                                         //Mesure entre l'état de la fourche et la valeur suivante
      {

        i = i + 1;                                                          //Incrémentation
        Old_State1 = State1;
        Serial.println(i);
        Serial.println(MOTOR_0_NUMBER_TOOTH_FLOOR_[1][b]);
        //Serial.println(b);
      }
    }
    else
    {
      i=0;
      
      }
  }
}

Je continue avec persévérance >:(

:slight_smile:

Non, ce que tu as fait n'est pas une interruption. C'est normal que ta fourche fonctionne lorsque tu enlèves le reste.
Par contre, si la fonction stepper est bloquante (c'est à dire que le programme n'avance pas sur les lignes suivantes tant que cette ligne n'est pas terminée) ton programme n'aura pas pu tester la fourche alors que l'axe aura bien tourné. tu auras donc peut être raté le comptage de certains tours.

Une interruption c'est un autre principe. Tu déclares une interruption sur une pin, et lorsqu'un courant passe, ça lance une fonction par callback (donc totalement en dehors de loop() :

Seul ça donne ça :

volatile int nbimp=0;

void interuption0() {
    nbimp = nbimp + 1; 
    Serial.print(" : ");
    Serial.println(nbimp);
}

void setup()   { 
    Serial.begin(115200); 
    attachInterrupt(0, interuption0, RISING); //0 pour la pin 2 arduino uno
} 

void loop(){ 

}

Je teste ça tout de suite vohu!

Merci encore!

Bonjour Vohu!

Merci infiniment de ta réponse!

En revanche...

-Il m'est nécessaire d'utiliser 3 fourches optiques et la arduino uno ne donne que 2 pin d'interruption.. (si besoin est j'irais acheter une méga mais je voudrais être sur de cet investissement :slight_smile: )

-Ensuite lorsque je fais tourner ma poulie dans ma fourche optique avec ton code, le comptage est nettement moins précis que la méthode précédente... (des sauts énoooooormes) :s

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Dans mon dernier code que j'ai transmis, le comptage du nombre de tour se fait parfaitement, le problème est que lorsque i=82 pour une raison obscure i se remet à 0 au lieu d'atteindre la valeur limite fixé dans mon tableau.

Lorsque j'annule cette RAZ, b s'incrémente bien.

Je crois que mon code peut fonctionner si j'arrive à bien résoudre cette RAZ.

Je te remercie encore une fois pour ta réponse que je n'arrive pas à comprendre entièrement en raison de ma jeune expérience...

Concernant la précision de la lecture, ça doit être un problème de parasitage.

Dans ton code actuel, ça à l'air de fonctionner mieux, car durant ce moment parasité, ton programme travaillait à autre chose. On peut en général ajouter un delay après la lecture d'une entréé pour déparasiter de façon "logicielle"

Par contre, avec l'utilisation de attachInterrupt, on a pas la possibilité d'ajouter un delay au bon endroit, puisqu'on défini une broche en lecture, et quelle fonction lancer lors du changement d'état. Entre les 2, c'est une boite noire. Soit tu modifies le code de la fonction attachInterrupt (cachée dans le framework arduino, je te déconseille) soit tu fais un déparasitage matériel.

Pour le déparasitage matériel, il faudra sans doute mettre un condo aux bornes de la photo diode. Par contre, en électronique pure je ne peux absolument pas t'aider, je dois être aussi débutant que toi. Il me semble qu'il y a un condo à mettre aux bornes de la photodiode, mais j'en sais pas plus.

EDIT : Je viens de trouver ça, ça explique bien le problème, mais attends quand même l'avis de quelqu'un de mieux informé que moi :smiley:

Hello Vohu!!!

J'arrive enfin avec une réponse!!!

En fait le passage avec la double boucle est plutôt... Galère :slight_smile:

J'ai donc utilisé de conditions ce qui fonctionne (:

void loop()
{


  //stepper1.setMaxSpeed(MOTOR_0_SPEED_FLOOR_[a][b]);                     //Vitesse stepper1
  //stepper1.setAcceleration(MOTOR_0_SPEED_FLOOR_[a][b]);                 //Acceleration stepper1
  State1 = digitalRead(fourchePin1);

    if ( i < MOTOR_0_NUMBER_TOOTH_FLOOR_[a][b])
    {
      if (State1 != Old_State1 )                                         //Mesure entre l'état de la fourche et la valeur suivante
      {
        i = i + 1;                                                          //Incrémentation
        Old_State1 = State1;
      }

    }
        else
    {
      
      b=b+1;
      i=0;
      if(b>4)
      {
        a=a+1;
        }
      }
    Serial.println(MOTOR_0_NUMBER_TOOTH_FLOOR_[a][b]);
    Serial.println(i);

}

Je ne sais pas si c'est très conventionnel mais en tout cas j'arrive à obtenir une précision parfaite et un changement de variables dans mon tableau, NEXT STEP : tout faire tourner avec le moteur plutôt qu'à la main :s

1000 merci encore vohu pour ces conseils!

Oui, mais ce code est bon tant que tu n'utilises pas des fonctions bloquantes. C'est le cas là, puisque tu as commenté les lignes qui concernent les moteurs. Mais quand tu voudras réutiliser les moteurs, il faudra rechanger et utiliser les interruptions avec un déparasitage