Page 1 sur 1

L'encodeur rotatif

Posté : 11 nov. 2021, 07:35
par likiki
Dans nombres de projets, il faut utiliser un nombre d'entrés important soit pour des boutons ou encore un clavier.

Cela est complexe tant au niveau câblage, boutons, résistances, fils, qu'en programmation et essouches mémoire.

l'encodeur rotatif, permet de se libérer du nombre restreint d'entré d'une carte Arduino UNO. Pour le câblage, il y a besoin de 5 fils, 2 pour l'alimentation (+5v et GND), deux pour la rotation et un pour le bouton.
.

.
encodeur.jpg
encodeur.jpg (28.96 Kio) Vu 1335 fois
L'encodeur rotatif

Pour le câblage, il faut utiliser deux entrées Analogique. Le tableau ci-dessous vous donne les correspondances.

*Encoder * Arduino Uno * Arduino Nano * Arduino Mega
****GND*********GND*********GND************* GND
***** + ********** 5V ********* 5V *************** 5V
*****SW********** 2 ************ 2 **************** 2
*****DT **********A2 ********** A2 ************** A2
****CLC ********* A3 ********** A3 ************** A3

Le schéma de branchement est quand a lui très simple.
cablage.jpg
cablage.jpg (71.43 Kio) Vu 1335 fois

Coté programmation, il y a du choix sur le net, mais j'ai eu une préférence pour ce petit sketch très facile a comprendre. Il permet de faire varier la position d'un servo.

Code : Tout sélectionner

#include "RotaryEncoder.h"
RotaryEncoder encoder(A2, A3);  // (DT, CLK)

#include "Servo.h"
Servo servo; // création de l'objet "servo"

#define STEPS  36       // Incrémentation a chaque cran
#define POSMIN 0       // Nombre pour la position minimal
#define POSMAX 180   // Nombre pour la position maximal

int lastPos, newPos;

void setup() {
   servo.attach(12);    // attache le servo au pin spécifié
   Serial.begin(9600); // ouvre le port série
   encoder.setPosition(10 / STEPS);
}

void loop() {
   encoder.tick();
   newPos = encoder.getPosition() * STEPS;

   if (newPos < POSMIN) { 
   encoder.setPosition(POSMIN / STEPS); 
   newPos = POSMIN;
   }
   else if (newPos > POSMAX) { 
   encoder.setPosition(POSMAX / STEPS); 
   newPos = POSMAX; 
   }

   if (lastPos != newPos) {
      Serial.println(newPos);
      lastPos = newPos;
   }

   servo.write(lastPos);
}
Perso, voilà ce que j'ai fait pour mon programme :

Dans l'init :

Code : Tout sélectionner

#define STEPSS 1                                                       // Nombre par pas d'encodeur

#define POSMIN -5                                                              // Position MINI de l'encodeur (ici -5)

#define POSMAX 4                                                              // Position MAX de l'encodeur (ici 4)

#define BPE 7                                                                    // Borne SW encodeur (bouton)

#include "RotaryEncoder.h"                                                // Appel de la bibliothéque pour encodeur

RotaryEncoder encoder(A2, A3);                                        // Borne de l'encodeur (DT, CLK)

Dans le loop :

Code : Tout sélectionner

/*
************************************************
* Menu selection par encodeur rotatif  *
************************************************
*/

   encoder.tick();
   newPos = encoder.getPosition() * STEPSS;

   if (newPos < POSMIN) { 
   encoder.setPosition(POSMIN / STEPSS); 
   newPos = POSMIN;
   }
   else if (newPos > POSMAX) { 
   encoder.setPosition(POSMAX / STEPSS); 
   newPos = POSMAX; 
   }

   if (lastPos != newPos) {
      
      if (newPos <= 0){                                                             // contrôle pour les positions entre -5 et 0 inclus
      lcd.setCursor(0,1);                                                          // place le curseur ligne suivante
      lcd.print ("Choix => ");lcd.print(newPos);lcd.print("     ");
      delay (10);
      lastPos = newPos;
      }

      if (newPos >= 1){                                                            // contrôle pour les positions supérieur a 0
      lcd.setCursor(0,1);                                                         // place le curseur ligne suivante
      lcd.print ("Choix => ");lcd.print("Reglage");
      delay (10);
      lastPos = newPos;
    
      }

 }

   if (digitalRead(BPE) == LOW) {                                          // Control si Bouton encodeur actionné
    Ebpe = newPos;                                                              // Si bouton actionné, mise en variable Ebpe du n° de la position
    delay(500);
   
   }

La gestion de la variable Ebpe se fait plus loin dans le programme pour les actions souhaitées.


:kingmoi:

Re: L'encodeur rotatif

Posté : 11 nov. 2021, 10:28
par herwat
Intéressant, je n'avais pas vu ce montage .

Je vais étudier ça de très prêt ! :D

:merciiii: , Christian .

Re: L'encodeur rotatif

Posté : 11 nov. 2021, 11:12
par Georges de Villette
Super ce petit tuto ! :cooooool:
:merciiii:

Re: L'encodeur rotatif

Posté : 11 nov. 2021, 11:48
par likiki
Avec ça, sur mon montage je passe de la MEGA a la UNO et plus de boutons, résistance et tralala.

Le boitier sera composé d'un inter marche /arrêt pour l'alimentation, un écran et l'encodeur rotatif.

Plus simple, tu peut pas.

Avant il y avait l'inter d'alimentation, un inter pour le mode normal /réglage, 2 boutons pour les réglages, 6 boutons pour les étages et l'écran.

:lollol:

Re: L'encodeur rotatif

Posté : 11 nov. 2021, 12:32
par herwat
Ah ça c'est sûr ! :hhhaaaa:

Cette bibliothèque a l'air bien foutue . Elle utilise les interruptions . . . Il va falloir que je me fasse un petit montage .

Voilà ici un descriptif en français .

Re: L'encodeur rotatif

Posté : 11 nov. 2021, 12:38
par likiki
Attention tout de même, une fois que tu y a gouté, t'est foutu.

:hhhaaaa:

Re: L'encodeur rotatif

Posté : 11 nov. 2021, 12:50
par herwat
à ce point là ? :hhhaaaa:

Re: L'encodeur rotatif

Posté : 25 nov. 2021, 17:32
par herwat
Bonjour à tous,

Je profite de cette magnifique après midi d'automne grise , humide, froide et venteuse pour faire des essais d'encodeur avec la librairie du chef . :-)

J'ai utilisé un banc d'essai que j'avais fait il y a quelques années pour commencer à utiliser des cartes SD et que j'ai modifié pour l'encodeur. ça me permettra de me former en même temps sur la lecture-écriture des SDCard .
J'ai aussi utilisé des "restes " de mon pont transbordeur .
D'où ce petit montage :
.
IMG_2769.jpg
IMG_2769.jpg (127.79 Kio) Vu 1276 fois
.
C'est pareil, pour le programme, j'ai utilisé des morceaux du programme du pont transbordeur .
Et voilà ce que ça donne : ( pour le moment, je teste juste l'encodeur )

Code : Tout sélectionner

        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * * * * * *        Exercice de gestion d'un encodeur rotatif      * * * * * *
         * * * * * *          avec la librairie <"RotaryEncoder.h">        * * * * * *
         * * * * * *              Affichage sur écran LCD I2C              * * * * * *
         * * * * * *              et mémorisation  sur SDCard              * * * * * *
         * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     
         * Programme en cours
   
         */   

  #include <LiquidCrystal_I2C.h>        // Bibliothéque pour l'écran LCD connecté en I2C
  #include <SPI.h>                      // Bibliothéque pour la liaison SPI de la SDCard
  #include <SD.h>                       // Bibliothéque pour la gestion de la SDCard
  #include <RotaryEncoder.h>            // Bibliothéque pour l'encodeur rotatif


  RotaryEncoder encodeur(A2, A3);       // Borne de l'encodeur (DT, CLK) et déclaration de l'objet
  LiquidCrystal_I2C lcd(0x27, 16, 2);   // description de l'écran LCD

  const byte PinBPConf  = 5;            // Bouton poussoir de l'encodeur sur entrée A5
  
  int Voie  = 0;
  int VoieLue = 0;
  int VoieInt = 0;
  int VoieSel = 0;
  int VoieAnc = 0;
  int Niveaumod = 0;
  boolean act  = false;
  boolean Confirm = false ;
  boolean mem = false ;

  void setup()
   {  
      lcd.init();
      lcd.backlight();
      lcd.setCursor(0,0);
      affichage(1);

      encodeur.setPosition(0);

      pinMode(A5, INPUT);
      delay (2000);
   }

   void loop()   
   {
     SelecVoie ();
   
   }


        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * * * * * *                 Définition des fonctions              * * * * * *
         * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
     
 void SelecVoie ()
  {
   encodeur.tick();                              // Mise à jour de l'état du décodeur
   VoieLue = encodeur.getPosition() ;            // Lecture de l'état

   if (VoieLue < 0) { 
                   encodeur.setPosition(0);      // Modification de l'état en cas de dépassement
                   VoieLue = 0;
                 }
   if (VoieLue > 10)
                 { 
                   encodeur.setPosition(10); 
                   VoieLue = 10; 
                 }

   if (VoieLue != Voie) {
                         Voie = VoieLue;
                         affichage(3);
                        }
 //  if (analogRead(PinBPConf)< 511 ){}
  }
  // * * * *

  void affichage(int aff)
  {
     switch (aff) {
       case 1:
               lcd.setCursor(0,0);
               lcd.print(".Initialisation.");
               lcd.setCursor(0,1);
               lcd.print("....Patience....");
               break ;
              

       case 2:
               lcd.setCursor(0,0);
               lcd.print("Voie appelee : ");
               lcd.setCursor(14,0);
               lcd.print(VoieSel);
               if(VoieSel<10){lcd.print(" ");}
               lcd.setCursor(0,1);
               lcd.print(" Acces en cours ");
               break ;
               
       case 3:  
               lcd.setCursor(0,0);
               lcd.print("Niveau voie : ");
               lcd.setCursor(14,0);
               lcd.print(VoieSel);
               if(VoieSel<10){lcd.print(" ");}
               lcd.setCursor(0,1);
               lcd.print("Voie appelee : ");
               lcd.setCursor(14,1);
               lcd.print(Voie);
               if(Voie<10){lcd.print(" ");}
               break ;
                  }
     }
Et une petite vidéo de démonstration :



ça marche Nickel ! :yess: Christian, t'es un chef ! :hhhaaaa:

Je vais donc persévérer dans mes essais !
:a_suivre:

Re: L'encodeur rotatif

Posté : 26 nov. 2021, 07:07
par Georges de Villette
Il nage bien , le chef !!!!! :hhhaaaa: :hhhaaaa: :hhhaaaa:

Re: L'encodeur rotatif

Posté : 26 nov. 2021, 08:25
par likiki
Cool que tu est réussi a t'approprier l'encodeur.

Cela simplifie le câble et la programmation.

:kingmoi: