[résolu]Problème avec encodeur rotatif

Bonjour à tous
Je tourne en rond depuis 2 jours sur un problème
Je lis les valeurs d'un encodeur rotatif avec le code suivant :

//From bildr article: http://bildr.org/2012/08/rotary-encoder-arduino/

//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;
int minCOM=118;
int maxCOM=136;

void setup() {
Serial.begin (9600);

pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);

digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
//Do stuff here

if(encoderValue>maxCOM){
encoderValue=maxCOM;
}
if(encoderValue<minCOM){
encoderValue=minCOM;
}

Serial.println(encoderValue);
delay(500); //just here to slow down the output, and show it will work even during a delay

}

void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit

int encoded = (MSB << 2) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 1) | encoded; //adding it to the previous encoded value

if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

lastEncoded = encoded; //store this value for next time

}

Il fonctionne, sauf que à chaque cran de l'encodeur, il incrémente ou décrémente ma valeur de 2 au lieu de 1
Le sujet à surement déjà été abordé, mais je n'arrive pas à trouver l'info
Merci

Tu as un montage anti rebond ?

J'utilise les résistances pull-up internes de l'arduino

digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

J'ai aussi essayé avec un filtre anti rebond externe (resistance + capa) ça ne change rien !

Tu as plus d'infos sur l'encodeur ?
En tout cas, tout dépend de ce que tu appelles le "cran" de l'encodeur.
Bref, si ça peut t'aider: sur un encodeur en quadrature (avec deux fils qui te donnent des signaux tout ou rien décalés d'un quart de période), tu dois pouvoir compter 4 fois plus d'impulsions que de nombre de lignes sur ton encodeur. Donc à ta place je m'inquièterais plutôt de n'avoir que deux fois plus d'impulsions, au lieu de 4 (si c'est un encodeur en quadrature, d'où ma première question).

C'est un encodeur basique

Merci pour vos réponses
Je vais tester les différents codes proposés et je vous dit quoi !!

24 impulsions par tour: difficile de savoir si c'est 6 lignes donc 24 impulsions vu que c'est en encodeur en quadrature ou bien s'il y a 24 lignes d'où 96 impulsions.
Tu trouveras ici (http://blog.3sigma.fr/arduino/tutoriel-arduino-asservissement-en-vitesse-dun-moteur-a-courant-continu/) des explications et un code qui fonctionne (tu enlèveras les choses qui te sont inutiles) pour avoir un comptage égal à 4 fois le nombre de lignes de ton codeur.

Pourquoi faire compliqué quand on peut faire simple ?

int nVal = 118;
 
void setup(){
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  attachInterrupt(0, nAnalyse, CHANGE);
  //attachInterrupt(1, nAnalyse, CHANGE);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  Serial.begin(9600);
  Serial.println("Start");
}
 
void loop(){
}
 
void nAnalyse(){
  if(digitalRead(2) == digitalRead(3)){
    nVal++;
  }else{
    nVal--;
  }
  if(nVal<118){
    nVal=118;}
    if(nVal>136){
      nVal=136;}
  Serial.println(nVal);
}

C'est pas encore très précis, mais ça fonctionne
Par contre si j'active l'interruption 1, ça ne fonctionne plus ?
Est ce qu'un spécialiste pourrai m'expliquer ?

Merci
De toute manière, c'était juste pour comprendre le pourquoi car maintenant j'utilise l'interruption 1 pour le bouton poussoir du décodeur
Mais je vous ai pas dis ce que je voulais faire ?
Je commence à me construire un cockpit pour Fligth Simulator et je compte arriver à ce genre de résultat :

lire un encodeur par int est très simple. relier l'une des sorties à l'INT sur front montant, l'autre sortie à une pin en entrée (INPUT_PULLUP pour les deux).

Ensuite, dans l'INT, il suffit de lire la pin d'entrée : si c'est 0, incrémenter, sinon, décrémenter. c'est aussi simple que ça. (au besoin, inverser le mode int (falling / rising).

Pour chercher plus de précision, il faut passer en "1/2 pas", et c'est plus compliqué.

Ensuite, selon la qualité du bouton, il y a à boire et à manger, j'en ai pris un une fois genre premier prix, même avec une capa de 100nF j'avais encore des rebonds, c'est pour dire...

Effectivement, j'ai des rebonds avec le bouton de l'encodeur
Je vais essayer avec un circuit anti rebonds externe (résistance +capa)

Merci à tous
Mais maintenant que que mon code fonctionne, je me pose une question
Pour faire fonctionner 1 encoder avec un SW, j'utilise 5 sorties et entrées de mon arduino UNO
Comment je fait si je veut rajouter des E/S avec la gestion des interrupts ?
Dans mon projet, il va falloir gérer 6 encodeurs !!!
A votre bon coeur, et Bonne année 2014

6 encodeurs (donc au moins 6 interruptions) avec une Uno, c'est pas possible. Regarde avec une Mega ou une Due.
D'ailleurs, sur ta vidéo, c'est une Mega.

Avoir plus d'entrées/sorties sans changer de carte :

  • avec interruptions : PCF8574 / PCF8575
  • sans interruption : 74HC595 (ou assimilé)

PCF8574 / PCF8575, je ne connais pas, je vais allez voir les datasheet

Le 74HC ..., moi je l'utilise plutot pour multiplier le nombre de sortie, dans mon projet, j'en suis à cinq afficheurs sept segments avec seulement 3 sorties de mon arduino Uno

Merci à tous

Comment ont modifie le titre avec [<résolu] ?

Comment ont modifie le titre avec [<résolu] ?

Exactement comme tu le dit. Et donc dans ton premier message, tu modifaye.... Le titre

Une lib pour encodeur rotatif:

/**
 * QuadEncoder.cpp - Library for reading moves from a quadrature rotary encoder
 * Created by Pedro Rodrigues (medecau@gmail.com) 9, January of 2010
 * Released into the public domain.
 */

#include "Arduino.h"
#include "QuadEncoder.h"

QuadEncoder::QuadEncoder(int pin1, int pin2)
{
  pinMode(pin1, INPUT);
  pinMode(pin2, INPUT);
  digitalWrite(pin1, HIGH);
  digitalWrite(pin2, HIGH);
  _inputPin1=pin1;
  _inputPin2=pin2;
  _val1=1;
  _val2=1;
  _oldVal1=1;
  _oldVal2=1;
  _pos=0;
  _oldPos=0;
  _turn=0;
  _turnCount=0;

}

char QuadEncoder::hb()
{  
  _val1 = digitalRead(_inputPin1);
  _val2 = digitalRead(_inputPin2);
    // Detect changes
  if ( _val1 != _oldVal1 || _val2 != _oldVal2) {
    _oldVal1=_val1;
    _oldVal2=_val2;
    
      //for each pair there's a position out of four
    if ( _val1 == 1 ) {// stationary position
      if (_val2 == 1)
        _pos = 0;
      else if (_val2 == 0)
        _pos = 3;
    } else if (_val1 == 0){
      if (_val2 == 1)
        _pos = 1;
      else if (_val2 == 0)
        _pos = 2;
    }
    
    _turn = _pos-_oldPos;
    _oldPos = _pos;
    if (abs(_turn) != 2) {
      if (_turn == 1 || _turn == -3)
        _turnCount++;
      else if (_turn == -1 || _turn == 3)
        _turnCount--;
    }
    if (_pos==0){
      if (_turnCount>0){
        _turnCount=0;
        return '>';
      } else if (_turnCount<0){
        _turnCount=0;
        return '<';
      } else {
        _turnCount=0;
        return '-';
      }
    }    
  }
}
/**
 * QuadEncoder.h - Library for reading moves from a quadrature rotary encoder
 * Created by Pedro Rodrigues (medecau@gmail.com) 9, January of 2010
 * Released into the public domain.
 */

#ifndef QuadEncoder_h
#define QuadEncoder_h

#include "Arduino.h"


class QuadEncoder
{
  public:
    QuadEncoder(int pin1, int pin2);
    char hb();
  private:
    int _inputPin1;
    int _inputPin2;
    int _val1;
    int _val2;
    int _oldVal1;
    int _oldVal2;
    int _pos;
    int _oldPos;
    int _turn;
    int _turnCount;  
  };

#endif

Un exemple d'utilisation ici:

RELAIS BOX CONTROL

Projet téléchargeable ici