Robotique Compteur en quadrature : besoin d'aide

  • Auteur de la discussion gassiune
  • Date de début
G

gassiune

Nouveau
Bonjour,

J'ai un petit souci de compréhension concernant l'avantage évident qu'on ces circuits (type ls7366): décharger le micro-contrôleur. Je n'arrive pas à me convaincre qu'il y a un gain important.

Exemple pratique avec une boucle d'asservissement PID:
- Sans compteur dédié, les codeurs sont reliés aux broches d'interruptions du micro et, à un interval de temps régulier, la fonction de calcul du PID est exécutée.

-Avec compteur dédié, les codeurs sont reliés au compteur qui lui même est relié au micro. Le micro est libéré des interruptions mais je présume qu'il doit interroger très régulièrement le compteur avant d'exécuter sa fonction de calcul.

Du coup il est où le gain ?
 
X

xavierblond

Nouveau
Sans compteur dédié, ton micro-contrôleur va sans-cesse être interrompu dans son programme, alors qu'avec un compteur dédié, c'est le programme de ton micro-contrôleur qui décide quand lire les compteurs.

Dans le cas où tu as peu d'impulsions lentes, tu peux avoir intérêt à utiliser directement des pins d'interruption pour simplifier le matériel.

Si par contre tu as besoin de précision (asservissement numérique), l'intervalle entre les échantillons importe aussi. Dans le cas d'un compteur hardware, la durée et l'intervalle de lecture est constant et ne devrait pas être perturbé par d'autres interruptions. Sans compteur matériel, tu peux arriver aux limites des performances du MCU et du coup ne pas avoir un intervalle constant entre chaque lecture (et du coup avoir un asservissement imprécis voir instable).

Pour un ordre de grandeur, avec un MCU 8-bit à 16MHz (Arduino) et des codeurs à 500ppr, on arrivait aux limites à 150tr/min et un asservissement à 100Hz.
 
G

gassiune

Nouveau
Tu veux dire que c'est simplement le fait de "gaver" le micro avec trop d'interruption qui cause l'instabilité?

Dans mon cas j'ai 4 codeurs à 480ppr et un micro 32bits à 83Mhz (vitesse maxi des moteurs 350 tr/min). J'aimerais savoir comment tu fais ton calcul de limite pour que je puisse l'appliquer à mon cas perso.
 
X

xavierblond

Nouveau
Oui, dans le cas que j'avais testé (sans aucun calcul), le MCU était à une charge de 100%, et du coup prenait plus de temps pour executer sa boucle d'asservissement.

Avec un MCU 32bits à 83MHz, je ne pense pas que tu aies trop de problèmes. Une solution assez fiable pour mesurer la charge d'un MCU est de changer l'état d'un GPIO en début et en fin de cycle. Le rapport cyclique donne la charge sans trop changer la vitesse d'execution du programme (contrairement à du debug sur port série).
 
S

syoctax

Apprenti
Tu veux dire que c'est simplement le fait de "gaver" le micro avec trop d'interruption qui cause l'instabilité?

Dans mon cas j'ai 4 codeurs à 480ppr et un micro 32bits à 83Mhz (vitesse maxi des moteurs 350 tr/min). J'aimerais savoir comment tu fais ton calcul de limite pour que je puisse l'appliquer à mon cas perso.
Salut gassiune,

Quel est la référence de ton microcontrôleur? Certains embarquent l'équivalent du ls7366 comme périphérique, ainsi tu économises le composant et le temps de traitement lié à la communication avec celui-ci.

Par exemple, nous utilisons des STM32 dont certains peuvent avoir les 4 interfaces pour les codeurs dont tu aurais besoin. Une fois configurés, la gestion des codeurs ne prend pas de ressource CPU et il suffit de lire l'état de chacun des compteurs qui sont stockés dans des registres indépendants.
A noter cependant que la plupart ont des compteurs 16bits, ce qui peut être limitant dans certaines applications (mais une fonction peut s'occuper de scruter ce compteur et le stocker régulièrement dans un compteur 32bits).
 
Dernière édition:
P

pwet

Nouveau
Je ne vois effectivement pas ou est le gain significatif de déporter le comptage sur un composant dédié plutôt que d'utiliser les compteurs internes du micro-contrôleur.

Exemple chez nous pour la coupe de france :

Microcontrôleur dsPIC 16 bits @40 MIPS
Compteur QEI 16 bits en hard (gérés en 32bits en soft)
Double asservissement PID @ 1ms
Codeurs 500 pts

J'ai eu un peu de mal à gérer correctement les overflow/underflow, il y a une interruption qui apparaît à chaque fois qu'un tel événement se produit, mais c'est tout.

Ca fait plusieurs année qu'on utilise ça sans problème.
 
G

gassiune

Nouveau
Quel est la référence de ton microcontrôleur?
C'est un module ROVIN basé sur un processeur ARM 32 bits ARM7TDMI.

J'ai beaucoup galéré mais j'ai fini par trouver un fournisseur (Omni Pro Electronics) qui vend des LS7366R en boitier DIP à un prix raisonnable (dans les 3$). Quand je les auraient je ferais l'essai avec pour voir.
 
L

louloute30

Compagnon
Il y a qq années en coupe de france, sur l'ascenseur du robot, j'avais un moto-réducteur avec encodeur placé sur le moteur (et non après le réducteur), cela me donnait qqch comme 18000 impl pour 1 tour de l'arbre après réducteur, donc, un déplacement de 2cm sur la visse à bille. Là, avoir un composant dédié était nécessaire...
 
G

gassiune

Nouveau
Merci à tous pour vos contributions j'y vois un peu plus clair, je vais voir maintenant ce que les tests pratique me disent.
 
P

pwet

Nouveau
Il y a qq années en coupe de france, sur l'ascenseur du robot, j'avais un moto-réducteur avec encodeur placé sur le moteur (et non après le réducteur), cela me donnait qqch comme 18000 impl pour 1 tour de l'arbre après réducteur, donc, un déplacement de 2cm sur la visse à bille. Là, avoir un composant dédié était nécessaire...
Je dois surement passer a coté de qqchose mais je ne vois pas ou est le problème pour faire encaisser cette vitesse de comptage à un compteur QEI interne de microcontrôleur.
 
L

louloute30

Compagnon
Je dois surement passer a coté de qqchose mais je ne vois pas ou est le problème pour faire encaisser cette vitesse de comptage à un compteur QEI interne de microcontrôleur.
J'avais une arduino... la mega 2560 ou sur une nano (328)... Pas de QEI dessus, que je sache. Donc, j'utilisais les interrupts, je perdais à vitesse lente quelques milliers d'impul, et à grande vitesse, plus de la moitié ne passait pas.

Sur un QEI interne de µcontroleur, c'était autre chose... avec le même moteur:
 
G

gassiune

Nouveau
J'ai pu faire quelques essais tout à l'heure et c'est pas brillant :cry:

L'essai consistait simplement à faire un tour de roue (soit 30 tours moteur qui représentent 480 impl) sans asserv à seulement 2 moteurs et afficher sur mon écran LCD le nombre d'impulsions comptées par les codeurs montés en interruption sur le module. Le truc de base quoi.

Avec mes moteurs pilotés à une vitesse <=40% (soit <=70tr/s) tout fonctionne comme prévu. Si par contre je monte au dessus alors là c'est le merdier, les moteurs continuent à tourner au delà d'un tour. J'ai remarqué qu'en débranchant le 2éme codeur les moteurs continuaient à tourner moins longtemps. Pire encore la valeur affichée ne correspond pas au nombre de tours fait, il en manque plein... mais vraiment plein.
Constat amer : ce module n'est pas capable de gérer correctement une freq d'interruption égale au Khz. Dans la doc il n'y a rien à ce propos d'ailleurs.
Là pour le coup je suis :eek::eek::eek: .J'ai pas le choix de passer par des compteurs dédiés si je veux conserver ce module (ce qui m'intéresse c'est la solution multitâche qu'il fourni).
 
P

pwet

Nouveau
Ha oui d'accord, c'est clair que compter des signaux en quadrature avec des interruptions sur changement d'état, faut pas s'attendre à grand chose de glorieux !

J'avais découvert sur le web une astuce qui consiste à utiliser (si tu as) deux entrées compteurs normales, et avec une simple bascule D tu transforme les signaux A et B en signaux CLK et CCLK.
Le principe en gros c'est de n'avoir plus qu'un signal qui transporte les fronts qui correspondent à un sens de rotation, et un autre signal qui transporte les fronts qui correspondent à l'autre sens de rotation.

Ensuite l'opération est simple, il suffit de soustraire les deux registres de comptage.
 
G

gassiune

Nouveau
J'avais découvert sur le web une astuce qui consiste à utiliser (si tu as) deux entrées compteurs normales, et avec une simple bascule D tu transforme les signaux A et B en signaux CLK et CCLK.
Le principe en gros c'est de n'avoir plus qu'un signal qui transporte les fronts qui correspondent à un sens de rotation, et un autre signal qui transporte les fronts qui correspondent à l'autre sens de rotation.

Oui j'avais oublié de préciser que mon test n'incluait qu'un seul canal par capteur. J'avais effectivement prévu d'utiliser une bascule (hef4013 dans mon cas) pour déterminer le sens.
 
R

romain_cvra

Ouvrier
Salut,

Je rejoint ce qu'on dit les autre intervenant.

Sans compteur codeur hardware, c'est rapidement limité pour le nombre de puls/s malheureusement...

Si tu veux continué avec le Rovin, un compteur codeur hardware externe comme celui que tu proposes est la solution.
Si non, l'autre solution est de changer de microcontrôleur et d'en choisir un avec suffisamment de compteur codeur hardware interne pour ton application.
Pour info, suivant le fabriquant, le nom de compteur codeur hardware peuvent changer...

Par exemple, dans nos robots nous utilisons une carte d'évaluation de chez ST, la Nucléo-144 .
http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html?querycriteria=productId=LN1847

A+
 
R

roboba

Ouvrier
il faut refaire le test sans utiliser ton ecran LCD , tu dois perdre pas mal de cycles
 
G

gassiune

Nouveau
J'ai refait plusieurs essais qui m'ont pointé la source du problème. C'est la gestion des événements du Rovin (pour ceux que ça intéresse, voir page 24 du PDF).

Sinon pour faire court, les interruptions sont converties en message puis placées dans une file d'attente puis les messages sont convertis en événements manipulable via une fonction réservée.

Au départ je gérais ces événements au sein de la fonction réservée via un "switch/case" (comme l'exemple page 24) afin d'incrémenter le bon compteur selon l'interruption, et quand j'ai utilisé une structure conditionnelle à base de "if" j'ai eu une amélioration avec un dépassement du compteur moins grand.

Puis j'ai creusé et n'ai laissé qu'un seul événement d'interruption (donc plus de structure conditionnelle) et là plus aucun dépassement notable!

Du coup, à moins qu'il y ai une astuce de programmation, je suis cuit car ça vient de la gestion trop lente de l'OS du module.
 
V

vres

Compagnon
Bonjour
Pour ma carte servomoteur j'utilise des HCTL2022 mais le LS7366 que je viens de découvrir grâce à ce sujet me plait beaucoup, pour les 32bits et l'interface SPI.

Pour les comptages moins rapide je n'utilise pas les interruptions car les erreurs de comptage sont quasi inévitables.

Je développé un petit algorithme en 4 lignes pour le décodage en quadrature sur le principe que entre 2 lectures du codeur il n'y a que 16 possibilités.
Pour ces 16 possibilités l'incrément est noté dans un tableau.

La bade passante du codeur dépend de la fréquence du timer appelant la fonction Lecture_Codeur

 
P

pwet

Nouveau
J'ai refait plusieurs essais qui m'ont pointé la source du problème. C'est la gestion des événements du Rovin (pour ceux que ça intéresse, voir page 24 du PDF).

Sinon pour faire court, les interruptions sont converties en message puis placées dans une file d'attente puis les messages sont convertis en événements manipulable via une fonction réservée.

Au départ je gérais ces événements au sein de la fonction réservée via un "switch/case" (comme l'exemple page 24) afin d'incrémenter le bon compteur selon l'interruption, et quand j'ai utilisé une structure conditionnelle à base de "if" j'ai eu une amélioration avec un dépassement du compteur moins grand.

Puis j'ai creusé et n'ai laissé qu'un seul événement d'interruption (donc plus de structure conditionnelle) et là plus aucun dépassement notable!

Du coup, à moins qu'il y ai une astuce de programmation, je suis cuit car ça vient de la gestion trop lente de l'OS du module.
Ça c'est le genre de raison qui explique pourquoi j'ai horreur d'utiliser des OS :x (pour le meilleur et pour le pire !)
 
A

antoine_cvra

Apprenti
Du coup tu développe tout le robot sans OS ? :o
 
P

pwet

Nouveau
Sur microcontrôleur je développe sans OS, après on a un ordi sous Windows et un programmeur qui va avec et qui gère bien la chose :)
Je veux dire... avec Windows on peut facilement faire de la bonne boulette :p
 
G

gassiune

Nouveau
Ça c'est le genre de raison qui explique pourquoi j'ai horreur d'utiliser des OS :x (pour le meilleur et pour le pire !)

Wep, pour ma part j'étais bien loin d'imaginer qu'un OS embarqué ferait surgir ce genre de problèmes. Mais c'est aussi pour ça que je me force un peu à sortir de mes habitudes en utilisant du matériel différent et parfois exotique comme ici, ça me fait découvrir/apprendre un petit quelque chose de plus.
 
A

antoine_cvra

Apprenti
Salut,
Nous on programme la nucléo en utilisant le framework fourni par ChibiOS. Je ne sais pas si c'est possible de programmer cette carte depuis mbed, désolé.
 
G

gassiune

Nouveau
Faut pas être désolé, c'est plutôt une bonne nouvelle au contraire.
 
C

coredump

Compagnon
Ce qui handicape dans ce cas ce n'est pas tellement l'OS mais tout le framework qu'il y a autour pour faciliter le développement.
Il n'y a pas de secret, lorsque l'on veut des performances ou tirer la quintessence d'une plateforme, il faut se retrousser les manches et mettre les mains dans le cambouis, et ça c'est un métier...
Un framework comme mbed c'est déjà un peu mieux, après il faut utiliser directement les sdk/librairies constructeur avec un rtos spécialisé (freeRTOS, chibios etc...) et optimiser le code pour l'application, ce qui prend beaucoup de temps et demande des outils adaptés (debuggueur, trace etc...).
 
A

antoine_cvra

Apprenti
Après avec les plateformes moderne, pas besoin d'aller grapiller les dernier % de performance, du moins à Eurobot. La vitesse de développement est beaucoup plus importante pour nous que l'optimisation.
 
R

RacingMat

Compagnon
juste en passant : ici une carte dédiée pour piloter 3 encodeurs

http://www.robogaia.com/3-axis-encoder-conter-arduino-shield.html
45$
754392_orig.jpg


bonne suite à toi dans tes projets !
 
G

gassiune

Nouveau
Je viens de recevoir mes oscillateurs 40Mhz aujourd'hui et j'ai pu câbler. Reste plus qu'a réaliser le programme de test.
 
G

gassiune

Nouveau
J'ai réalisé un premier essai et ça marche bien. J'ai simplement tester la communication SPI avec le LS7366. Je vais maintenant procéder au test avec les moteurs.

EDIT: J'ai essayer de récupérer le sens de rotation du moteur en lisant le bit "U/D" du registre STR. Surprise la valeur ne cesse de changer alors que le moteur ne change pourtant pas de sens. Je sèche carrément. Ça ne devrait pas faire ça.
 
Dernière édition:
Haut