Bonjour, cliquez-ici pour vous inscrire et participer au forum.
  • Login:



+ Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 30 sur 34

Utilisation d'un codeur incrémental

  1. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Utilisation d'un codeur incrémental

    Cette question revient de temps en temps, alors, j'ai rassemblé dans ce tuto un certain nombre de réponse aux questions qui ont été posées. Le codeur incrémental existe sous deux formes, rotatif ou linéaire. La mécanique est différente, le traitement électrique est le même.

    What is it?
    Un codeur incrémental génère 3 signaux :
    • Un signal A
    • Un signal B
    • Un signal Top Zéro

    Les niveaux électriques sont :
    • Haute tension (24V par exemple)
    • TTL (0/5V)
    • RS422 Dans ce cas, on a les signaux A et /A , B et /B , Z et /Z il faut passer par un récepteur de ligne RS422 (avec sa résistance d'adaptation)
    • Un simple contact sec et il faut une PullUp (ces codeurs, qui remplacent des potentiomètres, ne donnent pas de Top Zéro)

    Principe de fonctionnement
    Dans la suite, on oubliera la gestion du TopZéro qui ne sert qu'a recaler le compteur électronique en synchronisme avec la position zéro du codeur.

    Les signaux A et B sont décalés en quadrature (on dit aussi à 90° ou en Grecque) et chaque période de A (et donc de B) indique que le codeur a fait un pas sachant que le nombre de pas par tour peut aller de 32 à 8096 suivant le prix du codeur.
    Pour détecter le sens de rotation, Il faut regarder si les transitions positives de A sont avant ou après les transitions positives de B . Par contre, si on est un peu futé, on peut augmenter la résolution apparente par quatre en utilisant toutes les transitions.
    Pour le moment, tout ça c'est de la théorie ... En effet les signaux A et B sont entachés par des rebonds au moment des transitions. Ces rebonds proviennent :
    • Du contact électrique si celui-ci est fait par deux lamelles de cuivre
    • De l'hésitation en rotation du codeur quand il y a des vibrations

    La réalisation de la fonction de décodage avec des bascules et des circuits RC est vouée à l'échec et donne des montages qui tombent en marche . La seule solution valable est la méthode par échantillonnage. On regarde la valeur du signal et on la compare avec la valeur lue précédemment .

    Pour qu'aucune transition utile ne soit perdue, il faut au moins un échantillon du signal pendant une période " stable ", donc une fréquence d'échantillonnage d'au moins 4 fois la fréquence maximum de sortie du codeur.
    Par exemple :
    • Codeur de 1024 pas qui tourne à 1000 tour/minute
    • Fout= 1024*1000/60=17067 Hertz
    • Féchantillonnage > 17067*4=68267 Hertz

    Algorithme
    Cela consiste à faire une machine d'état (en soft ou en Hard). En fonction des deux entrées lues et des deux entrées mémorisées, il y a 16 états ( dont 4 impossibles, on ne peut pas lire 01 et avoir en mémoire 10 par exemple). Et pour chaque état, une action à faire : compter, décompter ou ne rien faire

    Code:
    Etat précédent de AB =00 Etat lu de AB=01 Compte=+1
    Etat précédent de AB =00 Etat lu de AB=00 Compte=0
    Etat précédent de AB =00 Etat lu de AB=10 Compte=-1
    
    Etat précédent de AB =01 Etat lu de AB=11 Compte=+1
    Etat précédent de AB =01 Etat lu de AB=01 Compte=0
    Etat précédent de AB =01 Etat lu de AB=00 Compte=-1
    
    Etat précédent de AB =11 Etat lu de AB=10 Compte=+1
    Etat précédent de AB =11 Etat lu de AB=11 Compte=0
    Etat précédent de AB =11 Etat lu de AB=01 Compte=-1
    
    Etat précédent de AB =10 Etat lu de AB=00 Compte=+1
    Etat précédent de AB =10 Etat lu de AB=10 Compte=0
    Etat précédent de AB =10 Etat lu de AB=11 Compte=-1
    Réalisation
    Il y a trois choix de technologie pour résoudre ce problème :
    • Circuit spécialisé genre HCTL2000
    • Circuit PAL genre GAL16V8
    • Microcalculateur (si le Timer et le programme en interruption peut tourner assez vite)
    NB : Certains automates programmables ont cette fonction dans leurs modules I/O

    Simulation
    Le bon fonctionnement de l'algorithme est montré sur cette simulation qui utilise des bascules et des portes (l'équivalent d'un GAL16V8)

    Programme pour microcalculateur
    Notre ami Canaillou2k5 a utilisé cette algorithme pour programmer un PIC . Le but est d'utiliser un bouton rotatif codeur pour faire évoluer une variable entre 0 et 100

    Code:
    unsigned char var_a=0, var_b=0, var=0; //variables globales
     
    void stockage() //stockage des anciennes valeurs
    {
        var_a=PIND.2;
        var_b=PIND.3;
    }
       
    void var_plus()           //fonction incrémenter
    {
        if(var<100)var++; //on incrément si on est en dessous de la valeur maxi. 
        stockage();            //stockage des anciennes valeurs
    }
    void var_moins()       //fonction décrémenter
    {
        if(var>0)var--;      //on décrément si on est au dessus de la valeur mini.
        stockage();           //stockage des anciennes valeurs
    }
        
    interrupt[14] void gray() // interruption sur compteur (toutes les 1,6ms)
    {
    
            if(var_a==0 && var_b==0)
            { 
            
                if(PIND.2==0 && PIND.3==1)var_plus();           //fonction incrémenter
                else if(PIND.2==1 && PIND.3==0)var_moins(); //fonction décrémenter
            }   
            else if(var_a==0 && var_b==1)
            {
                if(PIND.2==1 && PIND.3==1)var_plus();
                else if(PIND.2==0 && PIND.3==0)var_moins();
            } 
            else if(var_a==1 && var_b==1)
            {
                if(PIND.2==1 && PIND.3==0)var_plus();
                else if(PIND.2==0 && PIND.3==1)var_moins();
            }
            else if(var_a==1 && var_b==0)
            {
                if(PIND.2==0 && PIND.3==0)var_plus();
                else if(PIND.2==1 && PIND.3==1)var_moins();      
            }
    
    }
    Comme je suis nul en programmation, j'hésite à donner un avis mais je pense que l'exécution serait plus rapide (mais le programme plus long en place mémoire) si on n'utilisait pas des procédures mais des macros

    -----

    Images attachées
    Dernière modification par gienas ; 08/08/2011 à 15h42. Motif: Mise en page
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     


    • Publicité



  2. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 324

    Re : Utilisation d'un codeur incrémental

    en utilisant des macro comme proposé par DAUDET78, et sans remettre l'algo en jeu, on peut obtenir quelque chose de plus générique pour de dernier.
    Seule la syntaxe de l'appel de la fonction d'interruption est non standard et devra être retouchée.
    Code:
    #define SIG_A PIND.2
    #define SIG_B PIND.3
    #define INC_MAX 100
    #define INC_MIN 0
    /* Les lignes précédentes sont à ajuster 
       en fonction du codeur et du µcontroleur.
       On peut par exemple les placer dans un fichier .h à part.
     */
    #define STOCKAGE \
        var_a=SIG_A; \
        var_b=SIG_B;
        
    #define INCREMENTER \
        if (var<INC_MAX) var++;\
        STOCKAGE        
        
    #define DECREMENTER \
        if (var>INC_MIN) var--;\
        STOCKAGE            
       
    unsigned var=0; //variables globales
     
    interrupt[14] void gray() // interruption sur compteur (toutes les 1,6ms)
    {
            static unsigned char var_a=0, var_b=0;
            if(var_a==0 && var_b==0)
            {   
                if(SIG_A==0 && SIG_B==1) INCREMENTER 
                else if(SIG_A==1 && SIG_B==0) DECREMENTER
            }   
            else if(var_a==0 && var_b==1)
            {
                if(SIG_A==1 && SIG_B==1) INCREMENTER
                else if(SIG_A==0 && SIG_B==0) DECREMENTER
            } 
            else if(var_a==1 && var_b==1)
            {
                if(SIG_A==1 && SIG_B==0) INCREMENTER
                else if(SIG_A==0 && SIG_B==1) DECREMENTER
            }
            else if(var_a==1 && var_b==0)
            {
                if(SIG_A==0 && SIG_B==0) INCREMENTER
                else if(SIG_A==1 && SIG_B==1) DECREMENTER      
            }
    }
     

  3. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 324

    Re : Utilisation d'un codeur incrémental

    une autre implémentation qui diminue le nombre de tests:
    Code:
    #define SIG_A PIND.2
    #define SIG_B PIND.3
    #define INC_MAX 100
    #define INC_MIN 0
    /* Les lignes précédentes sont à ajuster 
       en fonction du codeur et du µcontroleur.
       On peut par exemple les placer dans un fichier .h à part.
     */
    #define INCREMENTER \
        if (var<INC_MAX) var++;\
        var_ab=(SIG_A<<1)+SIG_B;
        
    #define DECREMENTER \
        if (var>INC_MIN) var--;\
        var_ab=(SIG_A<<1)+SIG_B;
       
    unsigned var=0; //variables globales
     
    interrupt[14] void gray() // interruption sur compteur (toutes les 1,6ms)
    {
            static unsigned char var_ab=0;
            switch (var_ab){
                case 0:if(SIG_A==0 && SIG_B==1) INCREMENTER 
                       else if(SIG_A==1 && SIG_B==0) DECREMENTER
                       break;
                case 1:if(SIG_A==1 && SIG_B==1) INCREMENTER
                       else if(SIG_A==0 && SIG_B==0) DECREMENTER
                       break;
                case 2:if(SIG_A==1 && SIG_B==0) INCREMENTER
                       else if(SIG_A==0 && SIG_B==1) DECREMENTER
                       break;
                case 3:if(SIG_A==0 && SIG_B==0) INCREMENTER
                       else if(SIG_A==1 && SIG_B==1) DECREMENTER      
            }
    }
     

  4. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    Oui, cela me semble plus performant, au moins en vitesse d’exécution !
    Maintenant, il reste deux questions :
    1/ Quelqu'un est il volontaire pour évaluer pour un µC Français moyen le temps d’exécution de ce programme en C ?
    2/ Quelqu'un est il volontaire pour écrire en assembleur ce programme pour un µC Français moyen et aussi d'évaluer le temps d’exécution de ce programme ?

    PS 1 : J'ai deux Carambars à donner en remerciement !
    PS 2: Le nombre d'instructions machine à exécuter dans le pire cas serait aussi une bonne indication .
    Dernière modification par DAUDET78 ; 08/08/2011 à 14h58.
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  5. Canaillou2k5

    Date d'inscription
    octobre 2007
    Âge
    27
    Messages
    356

    Re : Utilisation d'un codeur incrémental

    Mon microprocesseur est un ATMEL.

    Avec le logiciel AVR studio je vais pouvoir faire des mesures de temps d'execution avec les différent programmes (si j'arrive à me souvenir car j'ai fait ça une fois il y à 1 ans...) en C mais aussi en assembleur, mais un assembleur crée par le compilateur C si je me souvient bien, donc du coup je ne sait pas si ça va changer quelque chose, c'est normalement moins rapide que de l'asm écrit à la main...
     


    • Publicité



  6. Mazen21

    Date d'inscription
    décembre 2010
    Localisation
    Tunisie
    Messages
    62

    Re : Utilisation d'un codeur incrémental

    Bonjour,
    Est ce que vous pouvez me dire que représente les valeur INC_MAX et INC_MIN et pourquoi la valeur "var" n'est jamais mis à 0?
    merci,
     

  7. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 324

    Re : Utilisation d'un codeur incrémental

    Est ce que vous pouvez me dire que représente les valeur INC_MAX et INC_MIN
    Es-tu bien sur d'avoir bien lu ce qui précède? Je rappelle un point du problème initial:
    Le but est d'utiliser un bouton rotatif codeur pour faire évoluer une variable entre 0 et 100
    et on peut lire plus loin:
    Code:
    #define INC_MAX 100 
    #define INC_MIN 0
    je te laisse conclure.

    pourquoi la valeur "var" n'est jamais mis à 0?
    Même constatation: tu n'as pas lu ce qui précède:
    Code:
    unsigned var=0; //variables globales
    Bonne lecture.
     

  8. Mazen21

    Date d'inscription
    décembre 2010
    Localisation
    Tunisie
    Messages
    62

    Re : Utilisation d'un codeur incrémental

    Oui vous avez raison je n'ai pas bien lu le problème.
    En fait je veux implémenter cette solution sur 2 encodeurs incrémentaux pour mesurer la vitesse et la position de mon robot.
     

  9. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    Dans le programme d'interruption, tu écris deux fois le programme (avec des déclarations de variable différente évidemment)
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  10. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    Une autre solution donnée par Microchip
    Citation Envoyé par RISC Voir le message
    Il ne faut SURTOUT PAS toucher à GIE dans l'interruption...
    L'acceptation d'une interruption entraine la désactivation automatique des interruptions (GIE=0) heureusement ...
    De même à la fin de l'interruption, la sortie provoque automatiquement la réautorisation des interruptions (GIE=1).
    Le programmeur doit simplement remettre à 0 le flag de l'interruption qui a été activé.

    Pour ce qui est de ton encodeur, cela dépend de la vitesse...si elle est importante, ton micro va passer son temps en interruptions...
    Cette note d'application (AN718) montre une méthode qui consomme peu de ressources micro, mais nécessite des bascules externes.
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  11. joey57

    Date d'inscription
    août 2005
    Âge
    29
    Messages
    669

    Re : Utilisation d'un codeur incrémental

    Salut,

    Ca me rappel un de mes sujets il y'a quelques mois sur cette fonction.
    J'avais donc réalisé un programme qui gère mon codeur mais sans utiliser de timer.

    Je voulais utiliser le timer pour mesurer le temps entre des "contacts" et ensuite évaluer la rapidité d'incrémentation ou de décrémentation.
    Je m’explique :

    Je suis à 10 (de 000 à 999)
    Je souhaite aller à 20, OK je tourne doucement, je fais +1 ou -1.
    Maintenant je souhaite aller à 600, je tourne rapidement le codeur, donc au lieu de faire +1 ou -1, pourquoi pas faire +10 ou-10 ?

    Et ce en fonction du temps mis pour faire quelques contacts(en faisant une moyenne).

    Sinon, très utile comme sujet
     

  12. invite13962411

    Date d'inscription
    janvier 2012
    Messages
    94

    Re : Utilisation d'un codeur incrémental

    Salut !

    Joli déterrage que je fais là...

    Je me penche actuellement sur l'exploitation de l'un de ces codeurs et j'utilise pour cela un Arduino.

    Auriez-vous une idée de la vitesse à laquelle l'Arduino est capable d'effectuer une mesure de front montant avec la fonction interrupt ? J'ai peur de "sauter" des stries en déplaçant le codeur trop vite...
     

  13. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    Citation Envoyé par NeOtuX Voir le message
    Auriez-vous une idée de la vitesse à laquelle l'Arduino est capable d'effectuer une mesure de front montant avec la fonction interrupt ? J'ai peur de "sauter" des stries en déplaçant le codeur trop vite...
    La méthode que j'utilise est différente .... c'est une machine d'état avec un Timer ....J'ai déjà donné la réponse ....
    Citation Envoyé par DAUDET78 Voir le message
    Pour qu'aucune transition utile ne soit perdue, il faut au moins un échantillon du signal pendant une période " stable ", donc une fréquence d'échantillonnage d'au moins 4 fois la fréquence maximum de sortie du codeur.
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  14. invite13962411

    Date d'inscription
    janvier 2012
    Messages
    94

    Re : Utilisation d'un codeur incrémental

    Très juste !

    Comment puis-je connaitre/déterminer la fréquence d’échantillonnage ?
     

  15. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    C'est toi qui la fixe !
    - Il faut une fréquence suffisamment haute pour ne pas perdre de "pas"
    - Il faut une fréquence suffisamment basse pour ne pas surcharger ton µC par le travail en interruption du Timer ( qui est relativement court). A toi de faire cette évaluation .....
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  16. invite13962411

    Date d'inscription
    janvier 2012
    Messages
    94

    Re : Utilisation d'un codeur incrémental

    Merci.

    C'est bien là ce qu'il m'avait semblé comprendre.

    Plus précisément : il doit bien y avoir une fréquence "limite" de l'Arduino non ?

    En fait, je me demande s'il existe un moyen de connaitre de manière relativement exacte le temps que met l'Arduino à faire telle ou telle opération.

    Car je ne sais pas encore si je vais pouvoir gérer les deux canaux du codeur sans ralentir l’exécution du reste du programme et tout en ne perdant aucune information... D'autant plus que pour la suite je vais utiliser un second codeur...
     

  17. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    Citation Envoyé par NeOtuX Voir le message
    Plus précisément : il doit bien y avoir une fréquence "limite" de l'Arduino non ?
    C'est a toi de la déterminer ! Tu fais le programme d'interruption (de préférence en assembleur) et tu calcules
    Car je ne sais pas encore si je vais pouvoir gérer les deux canaux du codeur sans ralentir l’exécution du reste du programme et tout en ne perdant aucune information... D'autant plus que pour la suite je vais utiliser un second codeur...
    Cela ne fait que doubler le temps d'exécution du programme d'interruption .
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  18. bokan

    Date d'inscription
    octobre 2013
    Messages
    106

    Re : Utilisation d'un codeur incrémental

    Si ça vous intéresse, il y a un algo encore plus performant.

    Les jumps et les tests c'est assez lourd à gérer pour un CPU (et oui !). En les évitant on gagne beaucoup (c'est surtout vrai pour les gros processeurs mais aussi pour les petits). Il y a même des fanatiques de la programation sans conditions http://www.antiifcampaign.com/.

    Donc une solution serait de pousser les états de AB actuels et passés dans une variable unique. Puis de créer un tableau de toutes les sommes à ajouter. On additionne souvent du vide, mais une addition est plus rapide qu'un simple test.

    Code:
    #define SIG_A PIND.2
    #define SIG_B PIND.3
    #define INC_MAX 100
    #define INC_MIN 0
    /* Les lignes précédentes sont à ajuster 
       en fonction du codeur et du µcontroleur.
       On peut par exemple les placer dans un fichier .h à part.
     */
    
    // quelques variables avec leur représentation binaires qu'on utilisera pas mais qui permettent de lister les différents états possibles
    #define B_0000  0 // 0  si a précédent =0, b précédent = 0, a actuel=0, b actuel=0 alors on ajoute 0
    #define B_0001  1 // +1 et
    #define B_0010  2 // -1 ainsi
    #define B_0011  3 // 0  de
    #define B_0100  4 // -1 suite
    #define B_0101  5 // 0  ...
    #define B_0110  6 // 0
    #define B_0111  7 // +1
    #define B_1000  8 // +1
    #define B_1001  9 // 0
    #define B_1010  10 // 0
    #define B_1011  11 // -1
    #define B_1100  12 // 0
    #define B_1101  13 // -1
    #define B_1110  14 // +1
    #define B_1111  15 // 0
    // les mêmes dans un tableau
    int motion= [0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,+1,0];
    
    unsigned rotation= 0; //variables globales je renomme rotation parceque var, ça me pique les yeux
     
    interrupt[14] void gray() // interruption sur compteur (toutes les 1,6ms)
    {
            static unsigned char var_ab=0;
            
            var_ab &&= B_0011  ; // ca ne garde que les deux petits bits qui correspondent à l'état précédent de a et b
            var_ab <<= 2;            // on les décale vers la gauche de deux bits pour libérer les bits  1 et 2
            var_ab = var_ab && ( SIG_A << 1 ) && SIG_B; // on y colle nos deux nouvelles valeurs 
            
            int rotation_temp = rotation + motion[var_ab];
            if(rotation_temp >= INC_MIN){
                   rotation = rotation_temp;
            }else if(rotation_temp <= INC_MAX){
                   rotation = rotation_temp;
            }
    }
    Je n'ai pas testé et il y a surement des erreurs, mais la logique est là.
    Le code est bien plus léger, il n'y a qu'un petit tableau de 16 octets en plus et il nous évite une foule de conditions.
    Dernière modification par bokan ; 27/10/2013 à 20h15.
     

  19. grosmatou75001

    Date d'inscription
    juin 2013
    Messages
    517

    Re : Utilisation d'un codeur incrémental

    Citation Envoyé par bokan Voir le message
    Les jumps et les tests c'est assez lourd à gérer pour un CPU (et oui !). En les évitant on gagne beaucoup (c'est surtout vrai pour les gros processeurs mais aussi pour les petits).
    Pour les gros genre Pentium j'y connais rien (y avait pas une histoire de pipeline de réorganisation de je ne sais plus quoi??), mais sur un AVR un test (CP, CPC, CPI, TST) c'est 1 cycle et un saut conditionnel (BR**) 2... D'accord, si on fait 10 tests ça s'accumule, mais alors on doit vraiment être dans un truc hyperserré au niveau temps si cela a une importance. Mais j'avoue qu'il est toujours intéressant de trouver mieux, même si le côté pratique est peut-être un peu... Bref. Si je trouve le temps dans les prochains jours je ferais bien passer les différents version par GCC et le simulateur, rien que pour comparer à une version assembleur pur (oui oui je sais, faut aimer...).

    Il y a même des fanatiques de la programation sans conditions http://www.antiifcampaign.com/.
    C'est quand même pas sérieux ce truc???

    Bon, il y a deux, trois trucs qui me sautent à l'oeil à première vue...

    Code:
            var_ab &&= B_0011  // &&=et LOGIQUE, il faut utiliser &
            var_ab <<= 2;
            var_ab = var_ab && ( SIG_A << 1 ) && SIG_B; //Même remarque, mais je pense qu'en fait il faut utiliser un OU et non un ET...
     

  20. bokan

    Date d'inscription
    octobre 2013
    Messages
    106

    Post Re : Utilisation d'un codeur incrémental

    grosmatou75001 :

    Effectivement les jumps sur pentium tuent les perfs c'est lié à la structure super scalaire du proc. Simplifions en disant qu'il y a 5 étapes pour faire une instruction (décoder l'instruction, rapatrier les données, executer l'instruction, remettre le résultat...http://en.wikipedia.org/wiki/Instruction_cycle), dans un proc normal ce sont les mêmes circuits qui sont utilisés à chaque étape il faut donc 5 tic (je ne sais plus le nom) par instruction, dans un pentium ils on scindé les circuits en 5 circuits dédiés à chaque étape (d'où le nom pentium) et à chaque tic chaqun fait son travail et passe au suivant un peu comme 5 travailleurs à la chaîne au lieu d'un. Ça fonctionne bien mais quand il y un jump ou quand une instruction dépends du résultat de la précédente, on doit attendre que le dernier travailleur aie fini pour pouvoir faire l'instruction suivante. Dans les procs hyperthreading, quand ce cas se présente, plutôt que d'attendre a rien faire, on execute une instruction d'un autre thread.

    Je suis tout à fait d'accord avec toi, les test et jumps ne sont pas catastrophiques surtout sur un AVR. Mais c'est quand même mieux de coder comme j'ai montré. Surtout que c'est le genre de code qu'on met dans une librairie et qu'on ne touche plus quand il marche. Alors autant l'optimiser à mort. Si tu compare mon code à de l'assembleur pur, tu aura très peu d'écart. Il se peut même que le code provenant de C soit plus rapide si le compilateur est bon (et le programmeur ASM pas parfait).

    C'est quand même pas sérieux ce truc???
    Si si, et dans le monde professionnel ça se comprends carrément. Y'as beaucoup de "programmeurs" qui ne connaissent que le if et qui vont te coller des enchaînements improbables. C'est illisible, impossible à maintenir.

    Bon, il y a deux, trois trucs qui me sautent à l'oeil à première vue...
    Honte suprême à moi qui joue les donneurs de leçon et confond un & et un &&, houps !
    Le code corrigé serait donc, avec une petite optimisation qui supprime un test quand il n'y a pas de mouvement :

    Code:
    int motionFromState= [0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,+1,0];
    
    unsigned rotation= 0; //variables globales
    
     interrupt[14] void gray() // interruption sur compteur (toutes les 1,6ms)
    { 
           static unsigned char currentState=0;   
           
           currentState &= 3 ; // 3= 00000011 en binaire ca ne garde que les deux petits bits qui correspondent à l'état précédent de a et b    
           currentState <<= 2; // on les décale vers la gauche de deux bits pour libérer les bits  1 et 2
           currentState |= ( SIG_A << 1 ) | SIG_B; // on y colle nos deux nouvelles valeurs
    
           int motion = motionFromState[currentState];
    
           if(motion){ // si c'est différent de 0
                   var rotationTemp = rotation + rotationTemp;
    
                   if((rotationTemp >= INC_MIN) && (rotationTemp<= INC_MAX)){
                         rotation = rotationTemp;
                  }
           }
    }
    
    Notez qu'il n'y aucun problème à déclarer plein de variables très locales (motion et rotationTemp). Le compilateur ne va même pas leur donner d'espace mémoire correspondant, juste leur attribuer un registre pendant quelques cycles.
    Dernière modification par bokan ; 28/10/2013 à 09h35.
     

  21. grosmatou75001

    Date d'inscription
    juin 2013
    Messages
    517

    Re : Utilisation d'un codeur incrémental

    Merci pour le petit cours sur les Pentium, intéressant! Pour les comparaisons ASM je verrai si j'ai le temps...
     

  22. bokan

    Date d'inscription
    octobre 2013
    Messages
    106

    Re : Utilisation d'un codeur incrémental

    Code:
    int motionFromState= [0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,+1,0];
    
    unsigned rotation= 0; //variables globales
    
     interrupt[14] void gray() // interruption sur compteur (toutes les 1,6ms)
    { 
           static unsigned char currentState=0;   
           
           currentState &= 3 ; // 3= 00000011 en binaire ca ne garde que les deux petits bits qui correspondent à l'état précédent de a et b    
           currentState <<= 2; // on les décale vers la gauche de deux bits pour libérer les bits  1 et 2
           currentState |= ( SIG_A << 1 ) | SIG_B; // on y colle nos deux nouvelles valeurs
    
           int motion = motionFromState[currentState];
    
           if(motion==0) return; // si c'est 0 on a fini
    
           var rotationTemp = rotation + rotationTemp;
    
           if((rotationTemp < INC_MIN) || (rotationTemp> INC_MAX)) return; // valeur hors limite, on a fini
    
           rotation = rotationTemp;
           
    }
    Juste pour le fun parce que je viens de relire mon code. Il vaut mieux coder comme ceci, sans imbriquer les if quand ce n'est pas utile. bien qu'un bon compilateur générera exactement le même code.
     

  23. extremgear

    Date d'inscription
    mai 2013
    Messages
    156

    Re : Utilisation d'un codeur incrémental

    Bonjour,

    Lorsque l'on veut interfacer un codeur optique fonctionnant en 24V avec un pic 5v , existe il une meilleure solution que les ponts diviseurs ?
    merci.

    A vrai dire je ne vois pas les problèmes qui peuvent se poser avec cette solution.
    Dernière modification par extremgear ; 03/07/2014 à 19h36.
     

  24. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    C'est une bonne solution .
    Les sorties sont en 24V ou en collecteurs ouverts ? Référence et lien WEB sur ce codeur ?
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  25. extremgear

    Date d'inscription
    mai 2013
    Messages
    156

    Re : Utilisation d'un codeur incrémental

    Merci pour la réponse hyper rapide !

    Les sorties peuvent être entre 10 et 30 V , selon comment est alimenté le codeur .
    Je compte alimenter en 24V .
    lien :
    http://files.pepperl-fuchs.com/selec...151794_fra.pdf
     

  26. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    C'est quoi la référence complète de ton codeur ?
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  27. extremgear

    Date d'inscription
    mai 2013
    Messages
    156

    Re : Utilisation d'un codeur incrémental

    RVI58N 032YYA31N Y0200

    Je précise que je suis bien certain d'avoir le modèle en 10-30V , j'ai déjà fait des tests à l'oscillo + montage , à l'époque je l'avais utilisé avec un optocoupleur ( pourquoi ? allez dont savoir !)
    je vais faire un schéma de l'utilisation que je compte en faire .
    ce codeur sera destiné à l'asservissement d'un motoréducteur pour un projet perso .
    Dernière modification par extremgear ; 03/07/2014 à 20h42.
     

  28. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    Ca correspond pas trop .... à l'oscilloscope tu as quoi sur A et /A ?
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     

  29. extremgear

    Date d'inscription
    mai 2013
    Messages
    156

    Re : Utilisation d'un codeur incrémental

    arf je viens de trouver la bonne doc :
    http://files.pepperl-fuchs.com/selec...253654_fra.pdf

    je ne dispose que des sortie A B 0.
     

  30. DAUDET78

    Date d'inscription
    septembre 2006
    Localisation
    Ile de France
    Âge
    75
    Messages
    64 724

    Re : Utilisation d'un codeur incrémental

    C'est mieux ..... donc, pont diviseur .
    L'age n'est pas un handicap .... Encore faut-il arriver jusque là pour le constater !
     


    • Publicité







Sur le même thème :





 

Discussions similaires

  1. Codeur incrémental
    Par le fondateur du cosmos dans le forum Électronique
    Réponses: 9
    Dernier message: 16/12/2011, 13h30
  2. Codeur Incrémental
    Par petitnul12 dans le forum Électronique
    Réponses: 16
    Dernier message: 27/10/2010, 20h21
  3. Codeur incrémental - 16f628
    Par Gilgari dans le forum Électronique
    Réponses: 0
    Dernier message: 12/10/2010, 07h39
  4. Codeur incrémental?
    Par méta_flo dans le forum Électronique
    Réponses: 1
    Dernier message: 20/04/2007, 20h51
  5. Codeur Incremental
    Par 1953 dans le forum Électronique
    Réponses: 4
    Dernier message: 26/02/2006, 12h55