Asservir moteur en vitesse et en phase (position). Plusieurs solutions?

Bonjour,

Je controle la vitesse de deux moteurs à encodeur incremental à l'aide de l'algorithme PID.

J'aimerai qu'il tourne entre 0.2 et 3 tours/secondes et surtout qu'ils restent en phase.

J'ai donc besoin de connaître la phase de chacun de mes moteurs, pour qu'ils puissent se re-synchroniser en phase et pas seulement en fréquence (vitesse angulaire).

Suis-je obligé de passer par un encodeur supplémentaire pour avoir la phase de mes moteurs? (un encodeur à fourche avec roue encodeuse par exemple)

Ou alors aurais je dû acheter des moteurs avec encodeurs rotatifs absolus?

Si oui, connaissez vous un site pas cher pour en trouver?

Ou encore y'a t'il une solution sans autre encodeur? (par exemple, j'appuie sur bouton pour dire au programme là ils sont en phase, donc considère que leurs positions sont équivalentes)

Merci, merci et merci

bvking:
Bonjour,

Je controle la vitesse de deux moteurs à encodeur incremental à l'aide de l'algorithme PID.

J'aimerai qu'il tourne entre 0.2 et 3 tours/secondes et surtout qu'ils restent en phase.

J'ai donc besoin de connaître la phase de chacun de mes moteurs, pour qu'ils puissent se re-synchroniser en phase et pas seulement en fréquence (vitesse angulaire).

Suis-je obligé de passer par un encodeur supplémentaire pour avoir la phase de mes moteurs? (un encodeur à fourche avec roue encodeuse par exemple)

Ou alors aurais je dû acheter des moteurs avec encodeurs rotatifs absolus?

Si oui, connaissez vous un site pas cher pour en trouver?

Ou encore y'a t'il une solution sans autre encodeur? (par exemple, j'appuie sur bouton pour dire au programme là ils sont en phase, donc considère que leurs positions sont équivalentes)

Merci, merci et merci

bonjour
quelle resolution angulaire de phase recherche tu ?

Merci Artouste pour essayer de m'aider.

J'aimerais que mes moteurs soient toujours en phases ou décalage de phase (que je choisi) avec une erreur entre 5 et 10% max sur les 360° de rotation complète.

Imaginons que je m'amuse à faire tourner mon moteur à la main plus ou moins vite, j'aimerai que l'autre suive ses changements de vitesse (ce que j'arrive à faire grâce à l'algorithme PID) sans qu'il perde au cours du temps (problème de latence et/ou d'alimentation j'imagine) sa position de départ (qui est relative au premier moteur).

Je pense que c'est possible sans ajouter d'encodeur, mais je vois pas.

Vous devriez asservir la moyenne des vitesses de vos moteurs (ou la vitesse d'un de vos moteurs) à une vitesse donnée
si le mobile ne tourne pas (ex: voiture avec volant; les grosses voitures ont un différentiel) , asservir chacun des moteurs à la même vitesse.... sinon, c'est affreux .

dbrion06:
Vous devriez asservir la moyenne des vitesses de vos moteurs (ou la vitesse d'un de vos moteurs) à une vitesse donnée

J'ai déjà essayé, mais il y a toujours une petite latence qui fait que mon deuxième moteur se déphase au cours du temps.

dbrion06:
si le mobile ne tourne pas (ex: voiture avec volant; les grosses voitures ont un différentiel) , asservir chacun des moteurs à la même vitesse.... sinon, c'est affreux .

Idem, en asservissant les deux moteurs à la même vitesse avec des alimentations et des drivers indépendants, j'ai toujours un décalage de phase (90°) au bout de deux minutes.

On m'a parlé de faire un index pour contrôler les phases mais je sais pas ce que c'est.

C'est ce qu'il y avait sur les disquettes au millénaire dernier: les disquettes étaient percées, et d'un côté, il y a une LED, de l'autre un photo transistor; le temps passé entre deux illuminations du phototransistor était le temps mis pour tourner de 360 degrés (mais je ne l'ai pas déjà raconté dans votre autre sujet????)

bvking:
J'ai déjà essayé, mais il y a toujours une petite latence qui fait que mon deuxième moteur se déphase au cours du temps.

Idem, en asservissant les deux moteurs à la même vitesse avec des alimentations et des drivers indépendants, j'ai toujours un décalage de phase (90°) au bout de deux minutes.

On m'a parlé de faire un index pour contrôler les phases mais je sais pas ce que c'est.

bonjour
il existe des encodeurs en quadrature (A/B) avec une sortie Z (index)
la sortie index sert simplement à faire un "top" par tour
un peu de lecture
dans ton cas si j'ai bien compris ta vitesse de rotation n'est pas tres élevée
tes encodeurs actuels ont quelle resolution ?
Tu aurait peut etre intérêt avec ta configuration actuel a exploiter la durée d'intercreneaux : ecart entre les creneaux moteur 1 et moteur 2.
ceci etant aujourd'hui pour les asservissement en position angulaire , il est de plus en plus souvent fait appel
à ce genre de capteur

Merci Artouste pour ta réponse

Artouste:
Tu aurait peut etre intérêt avec ta configuration actuel a exploiter la durée d'intercreneaux : ecart entre les creneaux moteur 1 et moteur 2.
ceci etant aujourd'hui pour les asservissement en position angulaire , il est de plus en plus souvent fait appel
à ce genre de capteur

si je comprends bien, avec ma config actuelle, à savoir deux moteurs à encodeur en quadrature, le seul moyen de connaître précisément l'écart de phase de deux moteurs asservis à la même vitesse est de de calculer "l'ecart entre les creneaux moteur 1 et moteur 2."
D'accord et comment fais t'on?

Mes moteurs sortent 198.6 pulses par revolution.

D'ailleurs, j'encode mal la vitesse des moteurs car je ne tiens compte seulement des fronts descendant et ascendant d'une pin sur les deux. Alors qu'il faudrait que je le fasse sur les deux pin (car l'Arduino Due peut utiliser la fonction attachinterrupt sur toutes les pin).
Dans mon programme, j'utilise la deuxième pin pour connaître le sens de rotation seulement.

Je mets le programme si vous avez des pistes...

void wheelSpeedA()
{
volatile byte LstateA = digitalRead(encoderApinA);  
  if((encoderAPinALast == LOW) && LstateA==HIGH)
  {
 volatile byte valA = digitalRead(encoderApinB);
    if(valA == LOW && DirectionA)
    {
      DirectionA = false; //Reverse
    }
    else if(valA == HIGH && !DirectionA)
    {
      DirectionA = true;  //Forward
    }
  }
  encoderAPinALast = LstateA; 
  
 
  if(!DirectionA)  durationA++;
  else  durationA--;

}