Ignorer et passer au contenu

Livraison offerte à partir de 50€ d'achats, livrée sous 48h !

Livraison à partir de seulement 2.50€ !

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Utiliser un encodeur rotatif en MicroPython avec un ESP32

(Mis à jour le 09/01/2023)

apercu codeur rotatif KY 040

Un codeur rotatif est un type de capteur de position qui convertit la position angulaire (rotation) d’un axe en un signal de sortie utilisé pour déterminer la position et le sens de rotation. Il est utilisé essentiellement dans les moteurs pour faire de l’asservissement, mais également dans les interfaces utilisateurs pour remplacer les potentiomètres. En plus, la plupart des modules que l’on trouve dans les kits DIY sont munis d’un bouton-poussoir intégré !

exemple utilisation encodeur rotatif imprimante 3d

Le bouton de contrôle des imprimantes 3D est en général un codeur rotatif

Prendre en main un codeur rotatif : le KY-040

apercu codeur rotatif KY 040

Dans ce tutoriel, nous allons voir comment utiliser un module avec un codeur rotatif KY-040, très présent dans les kits DIY. On l’utilise souvent pour faire une interface utilisateur avec notre programme : sélection d’un menu, augmenter/diminuer une variable…

Différence entre codeur rotatif et potentiomètre

À première vue, le codeur rotatif KY-040 peut être confondu avec un potentiomètre. Mais en réalité, le potentiomètre est un capteur analogique alors que le codeur rotatif est numérique. Un potentiomètre modifie la valeur d’une résistance, mais possède un nombre de tours limité.

Le codeur rotatif, quant à lui, détecte un nombre de « pas » par tour et envoie un signal à chaque pas. Il tourne aussi à l’infini. On peut sentir la différence à travers le toucher : le potentiomètre tourne de manière fluide, alors que le codeur rotatif tourne de manière saccadée.

Le codeur rotatif peut être directement utilisé par un microcontrôleur puisqu’il envoie des niveaux logiques. Sa résolution est déterminée par le nombre de pas par tour, alors que la résolution du potentiomètre dépend de la résolution de l’ADC nécessaire pour estimer sa position.

Note

On utilise un potentiomètre pour régler des paramètres analogiques, comme le volume d’un ampli, tandis que le codeur rotatif est employé pour déterminer précisément une position angulaire et une direction.

Fonctionnement théorique d’un encodeur rotatif

Ce tutoriel ne rentre pas trop dans les détails techniques, mais il y a beaucoup de choses à dire 🤓. Si vous voulez connaître réellement le fonctionnement physique, les différentes technologies et les topologies classiques (par exemple, le comprendre le fonctionnement d’un encodeur rotatif optique à quadrature de phase 😨), je vous redirige vers la présentation théorique d’un encodeur rotatif .

Branchements de l’encodeur rotatif KY-040 sur l’ESP32

Ce codeur rotatif possède 2 signaux pour connaître la position : CLK et DT . La broche SW est reliée au bouton-poussoir intégré (SWitch).

Avertissement

Si vous utilisez un codeur rotatif seul (pas intégré dans un module), vous devrez rajouter des résistances pull-up sur les 3 broches logiques. En effet, comme sur le circuit basique du bouton-poussoir, elles sont nécessaires pour différencier correctement les niveaux logiques.

Voici une proposition de branchement sur la carte uPesy ESP32 Wroom DevKit :

Codeur Rotatif

ESP32

CLK

GPIO22

DT

GPIO23

SW

Pas utilisé ici

+

3V3

GND

GND

Le schéma à faire est le suivant :

ky40 rotary encoder circuit diagram esp32 breadboard

Circuit électronique à reproduire

Note

Je vous conseille d’alimenter l’encodeur en 3.3V pour avoir des niveaux logiques de 3.3V (ESP32 friendly).

Et voici un exemple de montage sur breadboard :

schéma breadboard codeur rotatif

Connaître la position angulaire du codeur rotatif KY-040

Avec ce type d’encodeur incrémental, il ne renvoie pas précisément la position angulaire en degré mais plutôt le nombre d’incrément fait par l’utilisateur. C’est dans le programme que l’on peut en déduire l’angle. Ici, on veut juste connaître la valeur de l’incrément.

Il existe différentes façons de procéder pour déterminer l’incrément du codeur. Idéalement on voudrait une méthode fiable, qui compte bien tous les pas sans être bloquante dans le programme. En effet, si on utilise une approche simple, qui regarde dans une boucle en permanence si des signaux logiques sont reçus depuis le codeur, il risque d’y avoir des pas qui ne seront pas pris en compte si on tourne très rapidement le codeur.

Note

Parfois le programme compte dans le mauvais sens s’il n’arrive plus à suivre la cadence. (Un bug classique)

L’approche optimale c’est d’utiliser des interruptions hardware qui vont se déclencher dès qu’un changement de niveau logique est détecté. Elles seront complètement détachées du CPU: le code sera en prime non bloquant.

Note

On peut avoir des interruptions sur n’importe quelle broche de sorties de l’ESP32.

Je vous propose d’utiliser une libraire MicroPython micropython-rotary très bien faite, pour lire de manière asynchrone les incréments du codeur rotatif. Elle est constituée de 2 fichiers qu’il faut transférer sur votre carte (comme toutes librairies uPython). Cela peut se faire facilement depuis Thonny IDE :

Voici un script très basique qui permet de tester la librairie et valider le montage électrique :

import time
from rotary_irq_esp import RotaryIRQ

r = RotaryIRQ(
    pin_num_clk=22,
    pin_num_dt=23,
    reverse=True,
    incr=1,
    range_mode=RotaryIRQ.RANGE_UNBOUNDED,
    pull_up=True,
    half_step=False,
)

val_old = r.value()
while True:
    val_new = r.value()

    if val_old != val_new:
        val_old = val_new
        print("step =", val_new)

    time.sleep_ms(50)

On peut paramétrer pas mal de choses lors de la création de l’objet RotaryIRQ . Ils sont bien détaillés sur la page de présentation de la librairie . Le travail est fait en arrière-plan. On peut récupérer la valeur au moment voulu avec la fonction r.value() .

termnial série micropython encodeur rotatif

Note

Pour que cela tourne dans l’autre sens, vous pouvez inverser soit les 2 fils CLK et DT ou le faire dans le script en changeant la valeur de renverse lors de la création de l’objet .

Dans cet exemple, l’incrément du codeur n’a pas de limite : il incrémente à l’infini (jusqu’à l’overflow de la variable). On peut limiter l’incrément à une certaine plage, par exemple -20 à +20 en modifiant le paramètre range_mode .

Détecter la pression du bouton-poussoir

La librairie n’intègre pas de détection du bouton-poussoir. Cependant on peut facilement le détecter comme avec un bouton classique avec du code MicroPython. On pourrait même utiliser une interruption pour détecter de manière asynchrone l’appui sur un bouton. Par exemple, l’appui sur le bouton peut réinitialiser l’incrément en cours du compteur.