Dès qu’on veut faire de la robotique qui roule, tout le monde parle de codeurs incrémental. Mais qu’est-ce que c’est ? A quoi ça sert ? Comment ça marche et comment c’est fait dedans ? Et pour les meilleurs un petit exemple pratique sur Arduino.
Un codeur c’est quoi ?
Un codeur est un capteur qui permet de déterminer une position angulaire. Plus simplement, c’est un instrument qui permet de mesurer de combien de degrés un élément a tourné. Les codeurs sont un peu partout, dans nos voitures, dans nos cuisines mais il sont surtout très présent dans l’industrie. Un bon exemple est le gros bouton du volume de votre chaîne HiFi (ou ampli home cinéma). Ce bouton fait de plastique est relié à un codeur et en fonction de l’angle que vous lui faite faire le volume s’ajuste.
Mais alors, qu’elle est la différence avec un potentiomètre rotatif ?
Déjà pour déterminer facilement s’il s’agit d’un potentiomètre ou d’un codeur c’est simple. Un potentiomètre est « fini » j’entends par là qu’il n’a qu’un nombre de tours limités (certains peuvent avoir jusqu’à 16 tours donc il faut faire attention …), chose que le codeur n’a pas, il est infini (vous pouvez faire autant de tour que vous voulez avec). Mais la différence est bien plus importante que la comparaison de leur course. Le potentiomètre peut être vu comme une résistance variable (c’est une image ! ne dite pas ça à un électronicien sinon il ne va pas être content). En fonction de comment vous positionnez votre potentiomètre sa valeur de résistance varie. Si vous vous mettez au minimum sa résistance est faible (voire nulle) et si vous vous mettez en butée maximum sa résistance vaut plusieurs kΩ en général. Le potentiomètre donne une image électrique de sa position. Le codeur ne fait absolument pas ça. Nous allons donc voir comment fonctionne un codeur.
Comment fonctionne un codeur rotatif ?
Un codeur rotatif peut avoir plusieurs technologies (magnétique, optique, …). Nous allons nous intéresser ici aux codeurs optique, mais les autres technologies sont très semblables par leur comportement.
Principe général
Le codeur optique dispose d’un disque avec de nombreuses fenêtres (le nom technique est tic). Ces fenêtres laissent passer la lumière. Une LED dans le codeur émet un faisceau lumineux qui tente de passer au travers du disque, lorsque qu’une fenêtre se présente la lumière passe et est captée par un phototransistor. Une petite illustration va nous faire comprendre tout ça.
Quand le phototransistor capte de la lumière il délivre un signal logique. Si notre codeur est alimenté en 5V nous aurons alors un 0V quand la lumière ne passe pas et 5V quand elle passe. Ce qui donne (à vitesse de rotation constante) un beau signal carré comme ceci :
Détermination de l’angle
Étant donné qu’il est possible de savoir le nombre de fenêtres qui sont passées grâce au nombre de créneaux dans le signal électrique, il est alors possible de déterminer l’angle qu’a parcouru le codeur.
Partons du principe que notre codeur est un codeur à 360 tics/tour. Si nous avons 18 créneaux dans notre signal, le codeur à donc tourné de 18°.
Détermination du sens de rotation
En vrai, les codeurs rotatif sont un peu plus complexe car il faut aussi pouvoir déterminer leurs sens de rotation. Pour ça on met une seconde piste de tics en dessous de la première mais décalée de 25% de la position précédente (on dit que la piste à un déphasage de 90° ou de π/2 par rapport à la première). On y rajoute même souvent une 3ème piste avec seulement un tic pour avoir le début d’un tour. Voila à quoi ressemble un disque de codeur incrémental complet et les signaux qu’il génère :
Grâce à la deuxième piste, le codeur ne renvoie pas le même type de signal en fonction de son sens de rotation. S’il va dans un sens, A et B sont déphasés de 90° alors que s’il tourne dans l’autre sens, A et B sont déphasés de -90° ce qui donne le résultat suivant :
Utiliser un codeur sur une Arduino Uno
Vous pouvez télécharger le fichier du code source : codeurs_incrementaux.ino
Bonjour,
J’ai chargé ce programme associé au codeur, et j’obtiens cette erreur à la compilation :
Arduino : 1.6.13 (Windows 10), Carte : « Arduino/Genuino Uno »
C:\Eric\Clé PC\CPGE Parriat\Ressources Arduino\Fronts\codeur\codeur1\codeur3\codeur3.ino: In function ‘void setup()’:
codeur3:41: error: ‘Reagir’ was not declared in this scope
codeur3:42: error: ‘ReagirBis’ was not declared in this scope
exit status 1
‘Reagir’ was not declared in this scope
Visiblement, il n’accepte pas l’interruption… Avez vous un conseil ?
Mea-culpa en fonction des compilateurs pour Arduino il est nécessaire de déclarer le prototype des fonctions au début du programme. Je conseil donc de rajouter void Reagir() et void ReagirBis() juste après la déclaration des variables globales. Une seconde solution serait de mettre les fonctions Reagir() et ReagirBis() en entier, juste après la déclaration des variables globales.
Désolé pour le temps de réponse mais votre message à été noyé dans un flot de spam et je viens seulement de le lire.
Bonjour, je suis en Terminale Sti2d et j’ai pour projet de calculer une distance à partir de la rotation d’une roue de 50cm de périmètre qui entraîne un disque perforé, j’ai eu comme idée d’utiliser une fourche optique qui contera le nombre de trou donc le nombre de tour et ainsi avoir la distance.
J’aurais besoins de votre aide, je ne sais pas comment brancher la fourche optique sur ma carte Arduino UNO, la référence de ma fourche est H13A1
ah oui, je dois afficher la distance sr un ecran LCD
Bonjour Nicolas, c’est un projet sympa que tu as à réaliser. Effectivement ce tuto vas pouvoir t’aider. Je n’ai jamais utilisé ton capteur (H13A1) dans un montage mais je pense que ce doit être un capteur tout ou rien (comme un interrupteur, regarde bien la doc). Tu l’alimentes d’un coter et lorsque la lumière passe tu as un niveau haut puis un niveau bas quand elle ne passe pas.
Pour moi, si tu veux pouvoir utiliser le code source que je donne sur ce tuto, il te suffira de brancher la sortie de ton capteur sur la pin 2 ou 3 puis simplifier légèrement le code de façon à ne plus gérer le sens et surtout ne gérer qu’une seule fonction d’interruption (tu n’as besoin que d’un seul appel à attachInterrupt dans le setup) car toi tu n’as qu’un seul « codeur » et pas la deuxième piste de tic.
Pour afficher le tout sur ton écran, les lignes de code qui sont dans le loop() te permettent d’afficher tes valeurs dans un terminal série. Il est disponible dans le logiciel arduino dans Outils>Moniteur série. N’oublie pas de bien régler ton baudrate à 9600 bauds 😉
Indice : Pour avoir une distance et non un nombre de tic il te faudra faire un petit calcul dans la fonction loop() 😀
Tout est corrigé 😉
Merci 😀
Cordi
Merci Alexandre pour vos informations. Kiss the King of Gargouille
Merci pour votre aide, mais j’ai aucune notion en montage électronique ni en programmation :c Je ne sais pas quoi enlever et quoi garde :/ Je ne sais même pas ou je dois brancher mon écran LCD pour le faire fonctionner avec le programme :c ( grove-LCD RGB Backlight v2.0 )
Ok, désolé de spammer, mais après 2h j’ai réussi à bien brancher mon écran, le seul problème qu’il me reste est comment brancher ma fourche optique et quel programme utiliser :/ pour le moment mon écran affiche « distance (m): » et sur la seconde ligne il ne reste plus qu’a mettre le résultat mais je sais pas comment faire :c
Bonjour,
le temps de réponse est un peu long car nous somme concentré sur la coupe de France de robotique en ce moment mais apres avoir regardé quelques document on peut arriver à quelque chose assez simplement.
http://www.datasheetspdf.com/datasheet/H13A1.html
Ton capteur à quatre broches, deux pour la source lumineuse, et deux pour la donnée (je simplifierais en l’appelant transistor)
– 1 Anode de la led
– 2 Cathode de la led
– 3 collecteur du transistor
– 4 émetteur du transistor
Pour l’elec :
Pour le branchements ça donnerais quelque chose comme : 1 & 3 sur la sortie 5V de la Arduino, la broche 2 tu y met un résistance de 200 ohm pour aller sur le GND. (avec ça tu aura ta source lumineuse qui va être allumé en permanence).
Pour la donnée la broche quatre doit et branché sur la pin 2 ( ou trois selon ce que tu choisi) il doit aussi être branché sur la pin 2 de la Arduino une résistance que va sur un GND, c’est pour faire un pull down, une résistance de 1kohm devrait suffire, (je te conseille quand même de refaire un schéma pour bien comprendre ce qu’on te dit).
Pour l’info :
Tu peux reprendre le code de l’exemple tel quel, tu aura une valeur qui évolue (toujours négative mais fonctionnelle ) , après tu devrais pouvoir t’en sortir seul, mais si jamais ça va pas repasse par ici ^^.
Bon courrage
Bonjour, je suis en terminale SI et je réalise un projet qui consiste a faire tourner un moteur CC dans les deux sens a l’aide d’une télécommande mais aussi j’ustilise un codeur incrémental pour compter le nombre de tours de mon moteur, et je sais que pour cela je dois utiliser la piste Z mais je n’ai aucune idée du code arduino pour utiliser la piste Z. Quelqu’un pourrait m’aider svp?
Bonjour,
Tu dois d’abord essayer de trouver ce que représente l’information Z de ton codeur. Tu pourra trouver cette information dans la documentation officielle (appelée datasheet). Tu pourras sûrement lire un code écrit sur ton codeur, je te conseil de le mettre dans Google avec le mot clé datasheet en plus.
Après les pistes de codeurs sont presque toutes les même. Tu as donc bien souvent cela :
A : Tics 0V-VCC
B : Tics 0V-VCC décalé de 90°
Z : Un seul Tic par tour complet (Permet de savoir que tu as fait un tour de codeur)
Je te conseil vivement de regarder le code que je propose dans ce tuto. Il n’y a que peu de modifications à apporter pour compter le nombre de tours avec la piste Z plutôt que le nombre de Tics avant/arrière.
Bonjour, ce post est tres interessant et j aimerai utiliser vos connaissances dans le milieu pour en faire une dérivé en astronomie..
J’ai un axe que je pilote par un moteur et vis sans fin, sur cet axe je voudrai implanter un codeur incrémentable :
https://fr.aliexpress.com/item/600-Pulse-Incremental-Photoelectric-Rotary-Encoder-5-24V-Coupling-6-Pulse-Optional-Body-size-39-35/32797347765.html?spm=a2g0s.9042311.0.0.ROmjgm
mon axe fait 1 tour en 24h (rotation de la terre) ou plus simplement il me donne une position dans le ciel sur 1 axe (axe des declinaisons en astronomie)
Donc, j aurai aimer via un afficheur led, un arduino uno, ou de preferance un nano(pas cher) , connaitre la position en ° de mon axe et par ue petitt conversion en H.MM
Mes connaissances sont assez limiter dans ce domaine, mais je pense qu avec ce bout de programme on doit pas etre loin du but recherche ..
Bonjour stefaco,
En effet tu peux profiter du petit bout de code que je propose sans problème ! Si tu veux aller un peu plus loin, il t’es possible d’aller lire un peu plus d’informations que seulement les fronts montant des fronts de codeurs (argument : RISING dans les fonctions attachInterrupt() ).
Si tu arrives à lire les fronts descendants et montants tu vas doubler ta précision et donc avoir des données plus cohérentes surtout si tu veux aller jusqu’à avoir H.MM. Je suis en train de rédiger la seconde partie de ce tuto qui parlera de cette évolution possible.
Ton problème est tout à fait similaire au notre. Tu n’auras qu’un seul codeur fixe que ton télescope entraînera si je comprend bien ? Il te faudra sûrement 1 ou 2 switch en butés pour initialiser la position de ton télescope. Le nombre de tic pourra alors revenir à zéro automatiquement dans le cas ou il touche un switch en buté.
Autre chose, je ne sais pas si tu t’y connais un peu en électronique, je n’ai pas non plus trop regardé en détail la doc de ton codeur, mais pense à bien mettre des résistances de pull-up dans le cas ou ton codeur utilise des transistors à collecteurs ouverts.
Bonjour,
Un schéma serai bien venu.
Je pense que l’on branche le codeur sur Pin 9 et 10, mais que brancher en Pin 2 et 3
Je début sur Arduino et codeur.
Je cherche a comprendre.
A+. Merci
bonjour
je veut afficher la lecture d un diviseur de fraisage avec un codeur HEIDENHAIN ROD 1030 j ais réaliser une multiplication du codeur a 1 tour de plateau pour 200 tour de codeur qui a une résolution de 3500 points par tour , pouvoir lire 360, 000 degré par tour de plateau , pouvoir faire le zéro a tout moment ,
la partie mécanique est finis , pour info je suis fraiseur , de formation ,,
je pensais utilise un arduino , mais je n ais aucune connaissance en programmation en langage C ?
je joint la doc du codeur
bien cordialement Philippe
Bonjour,
Je suis actuellement sur un projet de robotique. L’odométrie est un outil indispensable dans mon projet.
Je voudrais bien comprendre cette partie :
// On regarde le sens de rotation de celui-ci
// (on teste l’état de la voie déphasée)
Comment on peut déterminer le sens de rotation, je sais que cela dépend du déphasage mais il comprend que une voie est en avance sur une autre ?*
Merci
Vous avez deux voies A et B vous observez les fronts de la voie A et B pour savoir quand il y a eu un mouvement. pour savoir le sens
sur front monatant de A et etat bas de la B : avant
sur front descendant de A et etat haut de la voie B : avant
sur front montant de B et etat haut de A : avant
sur front descendant de B et etat basde A : avant
dans les autres cas vous allez vers l’arrière (bien sur les sens sont arbitraires ici)
Bonjour,
J’utilise votre programme sur un arduino nano, j’ai donc du l’adapter. J’utilise un codeur hengstler ( 527 177 ). Mais le problème c’est qu’il semble ne pas détecter les fronts montants. L’encodeur fonctionne bien.
Merci en avance de votre aide
Quelle recherche doit on faire pour trouver la roue et le capteur en vente?
Bonjour,
Vous avez pas mal de choses abordables sur les sites Aliexpress, Bangood ou Amazon.
Pour un minimum de qualité vous pouvez regarder du côté de Robotshop.
Enfin, si vous chercher du haut de gamme vous pouvez aller voir sur RS, Farnell, Digikey ou encore Vicatronic.
Bonne journée.