Je vous propose de voir une première utilisation simple d'un encodeur rotatif : le KY040 avec un arduino UNO.
Un exemple courant d'utilisation est le bouton d'un autoradio qui permet le réglage du volume mais aussi d'allumer et d'éteindre la radio. Il ressemble beaucoup à un potentiomètre mais contrairement à lui il n'est pas limité dans ça rotation et envoie un signal à chaque "crans". Il y a 30 crans par tour et l'on est capable de déterminer le sens de rotation de l'encodeur. Pour cela, l'encodeur nous envoie 2 signaux (on parlera du signal A et B) comme suit :
Pour faire simple, lorsque l'on est sur un cran, A et B ont le même niveau logique (0 ou 1). Si on tourne dans le sens horaire, on reçoit le changement d'état de A avant B et si on tourne dans le sens contraire on reçoit B avant A.
Mise en place du hardware
Pour "capturer" la rotation nous utiliserons les "interruptions" disponibles sur les entrées 2 et 3 de l'arduino. L'Uno ne disposant que de 2 entrées avec gestion des interruptions, le switch sera géré dans la fonction "loop".
Au niveau hardware, rien de compliqué :
DT --> pin 2
CLK --> pin 3
SW --> pin 4
Nous utiliserons l'écran LCD pour afficher le compteur ainsi que l'état des 3 entrées :
rs (LCD pin 4) --> Arduino pin 12
enable (LCD pin 6) --> Arduino pin 10
LCD D4 --> Arduino pin 8
LCD D5 --> Arduino pin 7
LCD D6 --> Arduino pin 6
LCD D7 --> Arduino pin 5
Le programme correspondant
On utiliser un "unsigned int" pour stocker un compteur que l'on incrémente ou décrémente suivant le sens de rotation de l'encodeur. Un appuis dessus remettra à 0 ce compteur.
De part l'utilisation d'un "unsigned int", ce compteur est forcement compris entre 0 et 65535.
Dernier point important, ce type de bouton génère des rebonds aux niveaux des entrées de l'arduino. Il faut donc un système d'anti-rebond. il existe plusieurs possibilités, soit hardware en utilisant par exemple des condensateurs (0.1µF devrait être bon), soit logique via un peu de code. C'est cette dernière solution que j'ai utilisé.
include <liquidcrystal.h>
LiquidCrystal lcd(12, 11, 10, 8, 7,6,5);
// définition des pin pour le KY040
enum PinAssignments {
encoderPinA = 2, // right (DT)
encoderPinB = 3, // left (CLK)
clearButton = 4 // switch (SW)
};
volatile unsigned int encoderPos = 0; // un compteur
unsigned int lastReportedPos = 1; // gestion du changement
static boolean rotating=false; // gestion de l'anti-rebonds
// Interruption sur changement d'état de A
void doEncoderA(){
// debounce
if ( rotating ) delay (1); // attendre un petit peut
rotating = true; //activation de l'anti-rebond
// Confirmation du changement
if( digitalRead(encoderPinA) != A_set ) {
A_set = !A_set;