Question:
Comment interfacer un encodeur en quadrature avec PIC?
Bergamin
2012-05-10 03:08:36 UTC
view on stackexchange narkive permalink

Je développe un prototype qui utilise un encodeur en quadrature pour mesurer son déplacement linéaire. L'encodeur est fixé au corps du prototype et a une roue dans son arbre. Lorsque le prototype avance tout droit, le codeur mesure la distance linéaire. Tous les problèmes autour de la conversion entre les unités linéaires / angulaires ont été résolus.

La raison de mesurer la distance avec un encodeur est que j'ai BESOIN de savoir à chaque fois que le prototype a parcouru exactement 1 mm (1 millimètre = 0,0393 pouce). Chaque fois qu'il se déplace de 1 mm, PIC active un autre système.

La façon dont cela a été fait avant de commencer à travailler dessus est de lire l'encodeur avec un PIC (16F688) dans ses ports d'E / S. C'était plutôt correct, mais quand j'ai ajouté certaines fonctionnalités au code PIC, si la vitesse linéaire du prototype est supérieure à ~ 1,77 in / s (~ 45 mm / s), PIC commence à manquer le nombre d'encodeurs.

I 'ai essayé d'utiliser l'IOC (interruption en cas de changement) de portA pour lire le signal en quadrature (canaux A et B) mais ce n'était pas efficace.

Je sais qu'il y a des dsPIC mais je dois résoudre ce problème dans ma carte et je n'ai que 14 broches pour le faire lol. J'ai donc trouvé ce PIC16F1825 qui a une fréquence plus élevée (4x). Est-ce que (ma basse fréquence PIC) pourrait être mon principal problème ??

Je pensais utiliser les signaux LFLS7183 UP / DOWN avec le minuteur / compteur de PIC ou autre compteur IC afin de réduire la quantité de signalisation vers PIC. Cela fonctionnerait-il? Quel compteur dois-je utiliser? Je n'ai pas 8 broches dans mon PIC à utiliser comme dans celles http://goo.gl/2Wc3d.

Mon encodeur n'est pas mon problème, j'ai coché et il peut suivre jusqu'à 76 pieds / s pour mon rayon de roue.

De quelles fréquences parlez-vous? À quelle vitesse change l'encodeur et à quelle vitesse exécuter votre horloge MCU?
Six réponses:
Olin Lathrop
2012-05-10 17:03:09 UTC
view on stackexchange narkive permalink

Vous avez omis les informations essentielles sur la vitesse à laquelle les impulsions arriveront, je suppose donc que les pires des cas, les impulsions sont encore assez lentes pour qu'un micrologiciel correctement écrit puisse être capturé.

I ont trouvé quelques astuces pour faire un décodage en quadrature dans le firmware:

  1. N'essayez pas d'attraper des changements individuels, interrogez plutôt à intervalles réguliers. Supposons que l'encodeur peut rester bloqué directement sur la transition pour n'importe quel bord, et que ce bord peut donc rapidement trembler. Cela gâcherait toute interruption sur la technique de changement.

    Avec un sondage régulier, vous pouvez régler le système avec soin pour combien de temps vous voulez passer dans la routine d'interruption. La limite supérieure de la vitesse de l'encodeur est également bien connue, et n'est pas vraiment plus lente que le pire des cas avec la méthode d'interruption au changement de toute façon. La méthode d'interrogation est garantie de fonctionner correctement jusqu'à une vitesse de mouvement maximale que vous pouvez facilement calculer. La méthode d'interruption sur changement se dégrade de manière imprévisible car il y a des rebonds sur les transitions.

  2. Décode toujours la position 4x complète. N'essayez pas d'être méchant et de faire des trucs stupides comme compter +1 quand A transite alors que B est haut, etc. Ces "raccourcis" sont en fait plus difficiles à implémenter et ont des cas de coin qui vous causent des problèmes. Même si les niveaux supérieurs ne veulent connaître la position que pour un seul cycle complet, vous vous évitez les ennuis en décodant la nouvelle position à chaque changement d'état.

  3. Décodez à l'aide d'une table de recherche. A chaque interruption, vous prenez un instantané de l'état actuel des deux lignes d'encodeur. Ceci avec l'instantané de l'interruption précédente est de 4 bits de données. À partir de l'état précédent et du nouvel état, vous pouvez dire si le compte 4x est resté le même, ou s'il a augmenté ou diminué de 1. Comme il n'y a que 16 cas possibles, vous pouvez les utiliser pour envoyer à partir d'une table. Il y a 4 cas pour chacun de rester les mêmes, +1 et -1.

    Il y a aussi les 4 cas où le compte a changé par 2 qui nécessitent un traitement spécial. Un changement de 2 signifie qu'une transition a été manquée et que le codeur se déplace rapidement. En regardant uniquement l'ancien et le nouvel état, vous ne savez pas s'il a progressé d'un demi-cycle ou en arrière. Notez que 1/2 cycle est un compte de +2 ou -2 dans ce système. La façon dont je gère cela est de garder un dernier drapeau de direction connu. Le code qui fait +1 et -1 définit ce drapeau selon la direction connue. Lorsque vous obtenez un pas de 2, vous supposez que cela va dans la même direction que la dernière étape de 1. C'est une assez bonne hypothèse compte tenu de l'inertie des systèmes mécaniques réels.

    En réalité, vous avez donc vraiment 5 bits d'informations pour traiter chaque interruption, les 2 niveaux de ligne de codeur précédents, les nouveaux niveaux de ligne de codeur et la dernière direction connue. Donc, pour le summum de la vitesse, vous créez une table de 32 entrées et gérez chaque cas possible avec un code explicite. Le code pour chacun des cas ajoute de -2 à +2 à la position actuelle et met éventuellement à jour l'indicateur de direction connu.

Comme vous pouvez le voir, seulement quelques instructions sont nécessaires à chaque interruption d'interrogation. Votre PIC (16F1825) peut fonctionner à une fréquence d'horloge jusqu'à 32 MHz, soit une fréquence d'instructions de 8 MHz. Disons que vous configurez une interruption toutes les 50 instructions, ce qui est bien plus que nécessaire pour faire ce que j'ai décrit ci-dessus. Cela signifie que vous pouvez interroger à 160 kHz. Étant donné que l'encodeur peut changer jusqu'à 1/2 cycle par interruption, il prend en charge une fréquence de cycle complète de l'encodeur jusqu'à 80 kHz.

tcrosley
2012-05-10 04:10:25 UTC
view on stackexchange narkive permalink

J'ai récemment réalisé un projet similaire en utilisant un microcontrôleur Freescale. J'ai utilisé la capacité de capture par minuterie pour capturer l'heure des événements, sans avoir à compter sur une interruption (par exemple, interruption en cas de changement) précisément au moment où l'événement s'est produit. Votre routine d'interruption lit et stocke juste une valeur de compteur, et le reste du calcul est dôme dans le code de base.

J'ai vérifié, et le PIC16F1825 a également cette capacité. Section 24.1 (Mode Capture) de la fiche technique que j'ai téléchargée:

Le mode Capture utilise la ressource Timer1 16 bits. Lorsqu'un événement se produit sur la broche CCPx, la paire de registres CCPRxH: CCPRxL 16 bits capture et stocke respectivement la valeur 16 bits de la paire de registres TMR1H: TMR1L. Un événement est défini comme l'un des suivants et est configuré par les bits CCPxM<3: 0> du registre CCPxCON:

• Chaque front descendant

• Chaque front montant

• Chaque 4ème front montant

• Chaque 16ème front montant

Lorsqu'une capture est effectuée, le bit de drapeau de demande d'interruption CCPxIF du registre PIRx est mis à 1. L'indicateur d'interruption doit être effacé dans le logiciel. Si une autre capture se produit avant la lecture de la valeur de la paire de registres CCPRxH, CCPRxL, l'ancienne valeur capturée est écrasée par la nouvelle valeur capturée.

Vous devez toujours gérer les valeurs capturées rapidement assez pour ne pas rater un événement.

narendra
2012-09-06 21:54:34 UTC
view on stackexchange narkive permalink

Utilisez le port B pour détecter le changement de front pour les impulsions du codeur. Vous devez gérer un logiciel pour lire les impulsions, que l'encodeur tourne dans le sens horaire ou anti-horaire.

AngryEE
2012-05-10 03:48:07 UTC
view on stackexchange narkive permalink

Votre problème est que les interruptions de changement de broche générées par l'encodeur se produisent trop rapidement pour que votre logiciel puisse les gérer. Cela est probablement dû au fait que votre gestionnaire d'interruption est trop long. La séquence d'événements est probablement quelque chose comme:

  1. L'arbre se déplace
  2. L'encodeur produit un front montant
  3. L'interruption de changement de broche se produit
  4. Le gestionnaire d'interruption de changement de broche commence
  5. L'arbre se déplace à nouveau avant que le gestionnaire d'interruption ne soit terminé
  6. Une autre interruption est générée, mais pas gérée car vous êtes toujours en train de gérer la dernière
  7. Le gestionnaire d'interruption de changement de code se termine, effaçant l'indicateur d'interruption
  8. La deuxième interruption n'est jamais gérée

C'est ainsi que vous manquez des interruptions à grande vitesse - la prochaine interruption se produit avant vous ' Vous avez fini de gérer le premier et n'est jamais géré.

Premièrement, vous ne devez rien faire qui prend beaucoup de temps dans un gestionnaire d'interruption. Les gestionnaires d'interruption doivent être aussi courts que possible pour éviter le problème que vous rencontrez actuellement. Vous essayez probablement de tout faire sous le soleil dans votre gestionnaire. Ne fais pas ça.

Deuxièmement, vous devriez passer à une méthode de lecture de l'encodeur moins gourmande en logiciels. Si vous avez une minuterie libre, vous pouvez l'utiliser pour mesurer le déplacement de votre arbre. Si vous ne vous souciez pas de la direction ou de la vitesse de l'arbre , vous pouvez mesurer le déplacement de votre arbre par intervalles de 1 mm en procédant comme suit:

  1. Calculez le nombre de compteurs d'encodeur sont en 1 mm. J'espère que c'est un nombre assez grand - dans les années 100 environ
  2. Connectez l'encodeur à un signal d'horloge externe de l'un de vos minuteries - sur le 16F88, il est probablement préférable d'utiliser le Timer 1 car il peut fonctionner comme un compteur .
  3. Configurez le minuteur pour qu'il fonctionne comme un compteur, qu'il soit piloté par l'horloge externe et qu'il s'interrompe en cas de dépassement.
  4. Chargez le registre de comptage du minuteur avec une valeur de MAX - (# of l'encodeur compte en 1 mm). Le minuteur 1 est un minuteur de 16 bits, donc MAX est 0xFFFF.
  5. Démarrez le minuteur et activez les interruptions.
  6. Chaque fois que votre minuterie déborde, dans le gestionnaire, rechargez le registre de comptage avec la valeur d'origine de MAX- # comptes en 1 mm

Maintenant, chaque fois que votre minuterie interrompt, votre arbre va ont bougé de 1 mm. Ce n'est pas parfait - il se soucie seulement que votre arbre se déplace de 1 mm, mais il n'a aucune idée de la direction dans laquelle l'arbre s'est déplacé ou de sa vitesse. C'est, cependant, une méthode rapide et facile pour obtenir une interruption chaque fois que l'arbre se déplace de 1 mm dans n'importe quelle direction.

La plupart des encodeurs en quadrature peuvent osciller lorsqu'ils sont au repos, cela fera que votre minuterie comptera de faux changements de position. Cependant, lorsqu'elle est décodée correctement, cette oscillation n'a généralement aucun effet négatif.
Il ne devrait pas connecter les broches de l'encodeur à des entrées qui génèrent des interruptions. Utilisez le CCP et interrogez la direction, utilisez un compteur haut / bas et lisez le compte, ou utilisez une interruption de minuterie et recherchez les changements d'état de quadrature.
Cela peut être fait en mode d'acquisition de données en temps réel ou en mode d'événement IRQ asynchrone, de toute façon l'uC a besoin d'une vitesse suffisante pour compter l'événement en temps réel. Le problème est que le problème n'a pas été spécifié, de sorte que tout conseil est incertain pour quiconque de donner une solution parfaite. Étape # 1 définir les entrées, le taux et les états
si je comprends bien, 45 mm / s @ 1 mm par événement, soit 45 pps, le débit d'entrée est très lent. Il y a quelque chose qui ne va pas avec son code qui manque ces événements. Je pense que c'est dû à un manque de mémoire d'événements et qu'il doit être verrouillé. Nous ne savons pas pourquoi l'événement est perdu. dans cette période de 22 ms (1 / 45pps) Mais on ne connaît pas la nature exacte de ce signal, par exemple s'il y a une hystérésis etc. comme il devrait y en avoir pour 1/4 d'un cycle de quadrature. Si le code peut prendre plus que ce temps. alors il doit certainement être piloté de manière synchrone (par exemple, à une vitesse de 15 ms) si les routines ne peuvent pas être interrompues. (mauvaise conception)
Malife
2012-05-10 09:33:35 UTC
view on stackexchange narkive permalink

Je sais que vous avez explicitement dit que vous n'avez que 14 broches pour résoudre votre problème mais je ne comprends pas si cela est lié à la quantité d'état réel que vous avez sur le PCB ou s'il s'agit d'une carte héritée. Si cela est dû à un état réel, vous pouvez utiliser un dsPIC33FJ12MC201, qui est une pièce à 20 broches, pas très loin de votre limite de 14 broches, et il comprend un module QEI qui vous facilitera la vie beaucoup plus. ; peut-être que vous pouvez insérer cette partie dans votre tableau.

J'espère que cela vous aidera.

Tony Stewart Sunnyskyguy EE75
2012-05-10 04:07:31 UTC
view on stackexchange narkive permalink

Votre PIC ISR était-il simple?

  • calculez le saut en fonction de la valeur de la quadrature

  • renvoie +1 ou -1 ou 0

  • puis ajoute à la valeur actuelle.

Il devrait être capable de le gérer, je pense ...

.... des métastats? puis verrouillez les valeurs d'entrée.

Si toujours non. Ensuite, utilisez un CPLD avec compteurs haut / bas et passez à PIC sur une broche d'E / S série. Choisissez binaire ou décimal comme vous le souhaitez.

En 1978, je me souviens d'un petit aspect d'une conception majeure d'un système d'inspection robotique à courants de Foucault pour le système d'échangeur de chaleur secondaire Candu, j'ai aidé à la conception. la sonde à courant de Foucault a été suivie tous les 0,1 mm le long du tube à des vitesses allant jusqu'à 5000 mm par seconde et les lectures d'impédance de la sonde en quadrature 12 bits ont été combinées avec la position de la sonde prise à partir d'un simple encodeur rotatif en quadrature comme le vôtre. Nous avons utilisé du matériel personnalisé et un 6800 mpu. Si votre conception est trop lente, procurez-vous les bons outils pour le travail. Mais ne présumez pas. Créez une impulsion de sortie à chaque ISR et vérifiez-la.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...