Resolu. Bien assigner une position à un moteur pap.

Bonjour,

Je fais suivre à un moteur pas à pas les valeurs d'un polar allant de 0 à 4096.
Ca fonctionne très bien.

J'ai une simulation où je fais tourner un moteur à une certaine vitesse et dans les deux sens. En donnant les infos de position au moteurs pas à pas, il suit très bien la simulation du moteur. 8) ;D .

Mais, quand le moteur simulé recommence un tour, lorsqu'il commence le second tour, évidemment j'envoie la position 0 à mon moteur sur Arduino et donc, il revient en arrière pour aller à la position 0.

Je devrais lui envoyer la position 4096+1

Je me demandais comment dire au programme

int PositionMax= 4096;

Si la PositionPrecedente == PostionMax && PositionActuelle == 0

Alors, la NouvellepositionActuelle = lapositonActuelle+1.

Merci beaucoup.

Je n'ai pas bien compris ce que vous dites....

voilà ce que je comprends:

vous avez un moteur "simulé" qui donne sa position à tout moment par un nombre entre 0 et 4095.
vous utilisez ce nombre pour calculer le nombre de pas à demander à effectuer à votre stepper dans un sens ou dans l'autre pour qu'il suive le moteur simulé.

Cependant 4095 étant le pas juste avant qu'il ait fait un tour complet, si vous faites le pas suivant sur ce moteur simulé, il vous dit qu'il est à la position 0 et vos maths se plantent et au lieu d'envoyer un ordre qui dit "fait un pas en avant", vous envoyez un ordre qui dit de faire 4095 pas en marche arrière pour revenir à 0.

c'est cela ?

est-ce que votre moteur simulé vous donne sa position toujours en incrément ou décrément de 1 ? (ou est-ce qu'il peut passer de la position 22 à la position 36 et vous devez comprendre qu'il faut envoyer un ordre de 14 pas en avant d'un coup ?)

J-M-L:
Cependant 4095 étant le pas juste avant qu'il ait fait un tour complet, si vous faites le pas suivant sur ce moteur simulé, il vous dit qu'il est à la position 0 et vos maths se plantent et au lieu d'envoyer un ordre qui dit "fait un pas en avant", vous envoyez un ordre qui dit de faire 4095 pas en marche arrière pour revenir à 0.

c'est cela ?

J-M-L:
C'est exactement ça.

Le moteur simulé envoie la position sur un cercle de 0 à 4096, il peut envoyer 134 et 187 l'un après l'autre le moteur pas à pas suit très bien avec la bonne vitesse (si on dépasse pas une certaine vitesse).

Je cherche une solution pour qu'au comment du second tour le programme envoie 4096+la position actuelle, car la fonction
stepper.moveTo(positionX) suit dans mon une position trigonométrique et pas une réelle distance.

Je mets mon programme si ça peut aider

[/code ]

positionMoteurSimule= w0;

positionXactuelle= map ( positionMoteurSimule, 0, 4096, 0, 4096);

int positionMax= 4096;
int positionPrecedente = ???;

if (positionPrecedente == positionMax && positionX=0) {

positionVirtuelle = positionXactuelle+4096;

}

stepper.setAcceleration(10);
stepper.moveTo(positionX);
stepper.setSpeed(1000);
stepper.runSpeedToPosition();

Serial.print ("positionX"); Serial.println (positionX);

Vous dites que le moteur tourne dans les 2 sens et qu’il envoie des valeurs consécutives pas forcément proches

Si vous n’avez pas une idée du delta Max entre deux positions ce sera difficile d’arbitrer s’il est vraiment allé en avant ou en arriére... ou alors il faut prendre la plus petite valeur des deux en absolu comme la bonne et aller dans ce sens

Si à l’instant t1 vous être à la position Pt1 et à l’instant t2 vous être à la position Pt2 avec ces positions entre 0 et 4096

CAS 1: Si Pt2 > Pt1 alors on peut supposer qu’on avance de Pt2 - Pt1

CAS 2: Si Pt2 < Pt1 on a deux options

  • soit on a reculé de D1 = Pt1 - Pt2
  • soit on a avancé de D2 = (4097 - Pt1) + Pt2
    On prendra alors la plus petite valeur de D1 ou D2 pour decider

CAS 3: Si Pt2 = Pt1 on suppose qu'on n'a pas bougé (ou on a fait N tours, on ne peut pas savoir) donc on ne fait rien

Par exemple

  • vous êtes à 4090 et ensuite à 4095, CAS 1, avance de 4095-4090 = 5 pas

  • vous êtes à 4090 et ensuite à 4080, CAS 2
    => soit vous avez reculé de 4090 - 4080 = 10 pas
    => soit vous avez avancé de 4097 - 4080 + 4090 = 5007 pas
    Le plus petit étant 10 c’est le plus plausible vous reculez de 10

  • vous êtes à 4090 et ensuite à 2, CAS 2
    => soit vous avez reculé de 4090 - 2 = 4088 pas
    => soit vous avez avancé de 4097 - 4090 + 2 = 9 pas
    Le plus petit étant 9 c’est le plus plausible vous avancez de 9

Bonjour J-M-L,

Tout d'abord merci de m'aider.

J'ai essayé de transcrire vos cas

 receiveData(); // receive data from Processing
  
 analog_in= w4; //(position du moteur simulé allant de vers l'avant de 0 à 4096 qui retourne à 0 au second tour)
   
 positionX= map ( analog_in, 0, 4096, 0, 4096);

// CAS 1

   if (positionX > previousX)  {

   uint8_t i =+  (positionX-previousX);

   stepper.moveTo(i);
   //stepper.moveTo(positionX);
   stepper.setAcceleration(10);
   stepper.setSpeed(1000);
   stepper.runSpeedToPosition();
   
 // Serial.print ( "Distance Positive" ) , Serial.println (positionX+(positionX-previousX) );
  Serial.print ( "Distance Positive: " ) , Serial.println (positionX-previousX );
  Serial.print ( "previousX: " ) , Serial.println ( previousX );

     previousX = positionX;
   }

 // CAS 2  // je suis à 4090 puis 4080
 
  if ( previousX > positionX )   {

   recule = previousX-positionX;
   avance = (4097-positionX)+previousX;

   if (recule < avance) {

    uint8_t j =- recule;
       

     stepper.moveTo(j);
     stepper.setAcceleration(10);
     stepper.setSpeed(1000);
    stepper.runSpeedToPosition();

  Serial.print ( "recule: " ) , Serial.println (recule);
  Serial.print ( "previousX: " ) , Serial.println (previousX);

     previousX = positionX;

 }
     
   }

 // CAS 2 bis // je suis à 4090 puis à 2

     if (previousX > positionX )   {
      
     
      recule = previousX-positionX;
      avance = (4097-previousX)+positionX; // avance de 9 pas

       if (avance < recule) {

     uint8_t k =+ avance;
  
 
     stepper.moveTo(k);
    stepper.setAcceleration(10);
    stepper.setSpeed(1000);
    stepper.runSpeedToPosition();

  Serial.print ( "avance: " ) , Serial.println (avance);
  Serial.print ( "previousX: " ) , Serial.println (previousX);

       previousX = positionX;
      
     }

  }
  //cas 3

  if (positionX == previousX)  { 

      Serial.println ("doNothing");

       previousX = positionX;

    
  }
  Serial.print ( "posX" ) , Serial.println ( positionX );

Mais ça fonctionne mal, ça tourne toujours dans les deux sens mais mon bien qu'avec simplement

receiveData(); // receive data from Processing
  
 analog_in= w4; //(position du moteur simulé allant de vers l'avant de 0 à 4096 qui retourne à 0 au second tour)
   
 positionX= map ( analog_in, 0, 4096, 0, 4096);

  stepper.setAcceleration(10);
  stepper.moveTo(positionX);
  stepper.setSpeed(1000);
  stepper.runSpeedToPosition();

   // remember the previous value of the sensor
  previous = positionX;

Je pense pas que mes cas soient bien définies.

bonsoir j'ai lu en diagonale car cette ligne est un souci    uint8_t j =- recule;puisque une uint8_t est unsigned, il ne peut pas être négatif et s'il y a un grand pas (de plus de 255) ça ne rentrera pas... prenez un int

(on est dans la branche

  if ( previousX > positionX )   {
   recule = previousX-positionX;

donc on sait que puisque previousX > positionX la soustraction donnera un nombre positif et donc que recule sera positif.)

sinon Cette ligne là ne sert à rien positionX= map ( analog_in, 0, 4096, 0, 4096);

Il y a un truc qui m'échappe.
En fin de compte, ce moteur il a 4096 ou 4097 pas par tour?

fdufnews:
Il y a un truc qui m'échappe.
En fin de compte, ce moteur il a 4096 ou 4097 pas par tour?

on dirait qu'il va de 0 à 4096, donc 4097 pas... comme il est simulé, il n'a pas vraiment besoin d'exister dans la réalité - c'est pour cela que je n'ai pas relevé le point. (mais oui en pratique la valeur max serait sans doute 4095)

J-M-L:
comme il est simulé, il n'a pas vraiment besoin d'exister dans la réalité

Peut-être, mais les simulations s'appuient sur des modèles. Si le modèle à 4096 pas et qu'il en fait un de plus ce n'est pas étonnant de retourner un pas en arrière en recommençant à zéro.

je me suis appuyé sur ce que @bvking avance:

Le moteur simulé envoie la position sur un cercle de 0 à 4096

mais oui, je suis d'accord, la valeur semble louche :slight_smile:

Bonsoir,

D'après la doc, le step motor 28BYJ-48 à 64 pas.

Mais avec ce code je mappe assez précisément la position du step motor avec "soi-disant" 2048 ou 4096 pas.

#include <AccelStepper.h>
//#define HALFSTEP 4 //--> 2048 step. Si Halfstep 8 --> 4096 pas

#define motorPin1  10   // IN1 on the ULN2003 driver 1
#define motorPin2  11    // IN2 on the ULN2003 driver 1
#define motorPin3  12     // IN3 on the ULN2003 driver 1
#define motorPin4  13     // IN4 on the ULN2003 driver 1

AccelStepper stepper(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

#define ANALOG_IN A0

int analog_in, positionX;

// the previous reading from the analog input
int previous = 0;
int positionVirtuelle;

void setup()
{  
 Serial.begin (115200);
 stepper.setMaxSpeed(3000);//  15 rpm/ max?
 stepper.setAcceleration(100);
}

void loop()
{
 // Read new position
analog_in = analogRead(ANALOG_IN);

positionX= map ( analog_in, 0, 1027, 0, 2048); // halpstep 4
// positionX= map ( analog_in, 0, 1027, 0, 4096); // halpstep 8

}

     stepper.setAcceleration(100);
  // stepper.moveTo(positionVirtuelle);
  stepper.moveTo(positionX);
 stepper.setSpeed(3000);
 stepper.runSpeedToPosition();

  // remember the previous value of the sensor
 previous = positionX;
 
 Serial.print ( "A0: " ) , Serial.println ( analog_in );
 Serial.print ( "posX: " ) , Serial.println ( positionX );
 Serial.print ( "previous" ) , Serial.println ( previous );

}

Le moteur fait bien une revolution complète.

J'ai essayé de reprogrammé selon les conseils de J-M-L et j'ai changé les uint_8 par de simples int.

receiveData(); // receive data from Processing

// processingPosition= w4; // Jonathan
// positionX += computeDeltaPosition(processingPosition);
 
     // JML
  
    //    analog_in= w4; //(position du moteur simulé dans PROCESSING  allant de 0 à 4096 qui retourne à 0 au second tour)

   // ON PEUT AUSSI DIRE DANS PROCESSING QUE LES POSITIONS DU MOTEUR VONT DE 0 à 4095 mais ça change rien.
 
   //   positionX= map ( analog_in, 0, 4096, 0, 2048);

   positionX= w4; // conseil de J-M-L je ne re-mappe pas.

 // previousX = positionX;
 // Serial.print ( "posX" ) , Serial.println ( positionX );
 // Serial.print ( "prevoiusX" ) , Serial.println ( previousX );
 
// propos de  JML mal traduit?
  
// CAS 1
   if (positionX > previousX)  {
   int i =+  (positionX-previousX);
    
   stepper.moveTo(i);
   //stepper.moveTo(positionX);
   stepper.setAcceleration(10);
   stepper.setSpeed(1000);
   stepper.runSpeedToPosition();
   
 
  Serial.print ( "Distance Positive: " ) , Serial.println (i );
  Serial.print ( "previousX: " ) , Serial.println ( previousX );

     previousX = positionX;
   }
 // CAS 2  // je suis à 4090 puis 4080
 
  if ( previousX > positionX )   {

   recule = previousX-positionX;
   avance = (4096-positionX)+previousX;

   if (recule < avance) {

    int j =- recule;
       
     stepper.moveTo(j);
     stepper.setAcceleration(10);
     stepper.setSpeed(1000);
    stepper.runSpeedToPosition();

  Serial.print ( "recule: " ) , Serial.println (recule);
  Serial.print ( "previousX: " ) , Serial.println (previousX);

     previousX = positionX;

 }
     
   }

 // CAS 2 bis // je suis à 4090 puis à 2

     if (previousX > positionX )   {
      
      recule = previousX-positionX;
      avance = (4096-previousX)+positionX; // avance de 6 (de 4090 à 4096) +3 (0 à 3) pas

       if (avance < recule) {

     int k =+ avance;
  
     stepper.moveTo(k);
    stepper.setAcceleration(10);
    stepper.setSpeed(1000);
    stepper.runSpeedToPosition();

  Serial.print ( "avance: " ) , Serial.println (avance);
  Serial.print ( "previousX: " ) , Serial.println (previousX);

       previousX = positionX;
     }
  }
  //cas 3

  if (positionX == previousX)  { 

      Serial.println ("doNothing");

       previousX = positionX; 
  }
  Serial.print ( "posX" ) , Serial.println ( positionX );
  

 //***** MOTEUR FONCTIONNE sans les cas 1,2 et 3

     stepper.moveTo(positionX);
    stepper.setAcceleration(100);
    stepper.setSpeed(1000);
    stepper.runSpeedToPosition();

Malheureusement, ça n'a rien changé..

bvking:
Mais avec ce code je mappe assez précisément la position du step motor avec "soi-disant" 2048 ou 4096 pas

Donc une valeur de pas allant de 0 à 4095 (ou 2047) et non 4096 (ou 2048)

Salut.

En fait on m'a donné une solution pour que mon moteur soit toujours à la bonne position entre 0 et 2048 quand la position du moteur simulé dans Processing tourne continuellement dans un sens où dans l'autre.

#define NBPASPARTOUR 2048

int16_t computeDeltaPosition( uint16_t processingPosition) {
   static uint16_t oldPositionAbsolue = 0;
   uint16_t positionAbsolue = processingPosition;
   int16_t resultat;
   if(positionAbsolue < oldPositionAbsolue)
    positionAbsolue+=2048;
   if(positionAbsolue - oldPositionAbsolue < NBPASPARTOUR/2)
  resultat = positionAbsolue - oldPositionAbsolue;
   else
     resultat = positionAbsolue - oldPositionAbsolue - 2048;
   oldPositionAbsolue = processingPosition;
   return resultat;
}

A utiliser dans la loop

positionX += computeDeltaPosition(processingPosition);

Mais le problème c'est que le moteur 28BYJ-48 est trop lent. J'ai vu qu'on pouvait le hacké mais je pense que ça augment le couple et pas la vitesse; Là, je suis limité à 15 tour/min.