Codeur Incrémental¶
- Fichiers :
encoders.cetencoders.h
Bienvenue dans ce chapitre dédié au fonctionnement des codeurs incrémentaux (ou codeuses). Dans cette partie, je commencerai par expliquer brièvement le principe de fonctionnement de ces capteurs, ainsi que la manière dont nous les utilisons.
Ensuite, j'aborderai comment nous interagissons avec eux via notre code pour mesurer la vitesse de rotation réelle de nos moteurs.
Rappel
Dans notre configuration, les codeurs sont directement intégrés aux moteurs, montés à l'arrière de ceux-ci.
Définition¶
Un codeur incrémental est un capteur électromécanique qui convertit un mouvement de rotation (ou linéaire) en une série d'impulsions électriques. Il permet de mesurer des déplacements relatifs (incréments) plutôt que des positions absolues.
À quoi ça sert ?¶
- Mesure de position/vitesse : Détermine la vitesse de rotation, la distance parcourue ou l'angle de rotation.
- Contrôle de mouvement : Utilisé dans les systèmes de commande de moteurs (ex : robots, machines CNC, imprimantes 3D).
- Rétroaction (feedback) : Fournit des informations en temps réel pour ajuster la position ou la vitesse d'un système.
- Applications courantes :
- Automobile (capteurs de position de pédales, volants).
- Industrie (automatisation, convoyeurs).
- Électronique grand public (souris optiques, encodeurs rotatifs).
Fonctionnement¶
1. Structure de base¶
- Un disque perforé ou strié (avec des fentes ou des motifs optiques/magnétiques).
- Un émetteur (LED, aimant) et un récepteur (photodiode, capteur à effet Hall).
- Deux signaux de sortie en quadrature (déphasés de 90°) : A et B.
- Un signal optionnel Z (index) pour marquer une position de référence.
Note
Le signal \(Z\) est disponible sur certaines codeuses. Bien qu’il ne soit pas indispensable, il offre un signal utile : il passe à un état haut lorsque la codeuse a effectué un tour complet. Cela peut faciliter certaines applications, comme la détection de position absolue ou la synchronisation.
2. Principe de détection¶
- Le disque tourne entre l'émetteur et le récepteur.
- Les fentes laissent passer (ou bloquent) la lumière/champ magnétique, générant des impulsions carrées sur les sorties A et B.
- Le déphasage entre A et B permet de déterminer le sens de rotation (horaire ou anti-horaire).
3. Traitement des signaux¶
- Comptage des impulsions : Chaque impulsion correspond à un incrément de mouvement (ex : 1 impulsion = 1° de rotation).
- Résolution : Nombre d'impulsions par tour (ex : 1000 impulsions/tour = résolution de 0.36°).
- Vitesse : Calculée en mesurant la fréquence des impulsions sur une période donnée.
4. Limites¶
- Pas de position absolue : Nécessite une initialisation (référencement) au démarrage.
- Sensible aux perturbations : Bruit électrique ou mécanique peut fausser le comptage.
Schéma simplifié¶
Disque rotatif
---------------
| |
| A B | → Signaux en quadrature (A et B)
| █ █ █ █ |
---------------
|
Emetteur/Recepteur
Note
Un circuit électronique (ex : microcontrôleur) compte et interprète les impulsions pour en déduire la position ou la vitesse.
Implémentation¶
Il est important de noter que la carte que nous utilisons — et plus précisément le microcontrôleur (STM32F411CEU6) — intègre un module dédié aux codeurs incrémentaux.
Ce module se charge directement du traitement des signaux et de l’incrémentation ou décrémentation du compteur en conséquence.
Initialisation¶
Les quatre modules STM32 dédiés aux codeurs sont initialisés et démarrés durant la phase d’initialisation du programme, avant l’entrée dans la boucle principale.
Pour cela, la fonction HAL_TIM_Encoder_Start(...) est utilisée afin d’activer chaque timer configuré en mode encodeur.
HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
Mise à jour de la vitesse¶
La fonction suivante a donc pour objectif principal de déterminer, à partir de l’évolution du compteur par rapport à sa valeur précédente, la vitesse de la roue ainsi que son sens de rotation — indiqué par le signe de la vitesse.
Elle assure également la gestion des dépassements de valeur maximale et minimale du compteur.
void update_encoder(Encoder *encodeur, TIM_HandleTypeDef *htim)
{
// Lire une seule fois la valeur du compteur et l'autoreload
uint32_t temp_counter = __HAL_TIM_GET_COUNTER(htim);
uint32_t auto_reload = __HAL_TIM_GET_AUTORELOAD(htim);
// Gestion du cas où le compteur n'a pas changé
if (temp_counter == encodeur->valeur_precedente)
{
encodeur->delta_tick = 0;
encodeur->vitesse_mms = 0;
}
else
{
// Vérifier si le timer est en mode décompte ou incrément
uint8_t counting_down = __HAL_TIM_IS_TIM_COUNTING_DOWN(htim);
if (temp_counter > encodeur->valeur_precedente)
{
// En mode décompte avec dépassement
if (counting_down) {
encodeur->delta_tick = -encodeur->valeur_precedente - (auto_reload - temp_counter);
// En mode incrémentation simple
} else {
encodeur->delta_tick = temp_counter - encodeur->valeur_precedente;
}
}
else
{
// En mode décompte avec sous-passement
if (counting_down) {
encodeur->delta_tick = temp_counter - encodeur->valeur_precedente;
// En mode incrémentation avec sous-passement
} else {
encodeur->delta_tick = temp_counter + (auto_reload - encodeur->valeur_precedente);
}
}
encodeur->valeur_precedente = temp_counter;
encodeur->vitesse_mms = encodeur->delta_tick * TICK_TO_MM_S;
}
}
Dans l'odre, voici que réalise cette fonction qui a pour vocation d'être appelée à interval régulier dans la routine d'asservissement :
- Lit la valeur actuelle du compteur du timer et la valeur d’auto-reload.
- Vérifie si le compteur n’a pas changé :
- Si oui → delta_tick = 0 et vitesse = 0.
- Sinon (le compteur a changé) :
- Détermine si le timer compte à rebours ou en incrémentation.
- Si la valeur du compteur est supérieure à la précédente :
1. Si le timer compte à rebours → calcul du dépassement en mode décompte.
2. Sinon → simple incrémentation. - Si la valeur du compteur est inférieure à la précédente :
1. Si le timer compte à rebours → simple décompte.
2. Sinon → sous-passement en mode incrémentation. - Met à jour la valeur précédente du compteur.
- Calcule la vitesse en mm/s :
vitesse_mms = delta_tick * TICK_TO_MM_S.
Note
La constante TICK_TO_MM_S, utilisée pour la conversion, repose sur la résolution du codeur incrémental. Cette information est disponible dans la datasheet du capteur et correspond au nombre de ticks (impulsions) équivalant à un tour complet de l'encodeur.
Dans notre cas, la résolution est de 3200 ticks par tour, ce qui signifie que 3200 impulsions correspondent à une rotation complète de l'encodeur.
Structure de donnée¶
Les variables d’entrée et de sortie de cette fonction sont regroupées au sein de la structure Encoder :
typedef struct {
uint16_t valeur_precedente; // Valeur précédente du compteur
int16_t delta_tick; // Variation du compteur entre deux mesures
int16_t vitesse_pwm; // Vitesse exprimée en valeur PWM (pas utilisée)
float vitesse_mms; // Vitesse en mm/s
} Encoder;
Ressources et Références¶
- Lire les codeurs - Wiki Eurobot
- Les Codeurs - Codeur incrémental double voie
- Getting started with TIM
- STM32 Tutorials