Problème Rotary encoder [Resolu]

Bonjour,
J’espère que vous allez bien par ces temps difficiles …
Je rencontre un problème avec l’utilisation d’un encodeur rotatif avec la librairie RotaryEncoder.h
Avec cet encodeur je règle 2 valeurs U et I, je bascule d’une a l’autre avec un interrupteur.
Mon problème :
Lorsque je règle la valeur de U et que je bascule l’inter sur le réglage de I, I prends la valeur de U.
Lorsque je règle la valeur de I et que je bascule l’inter sur le réglage de U, U prends la valeur de I.
Je n’arrive pas a faire en sorte que les 2 réglages soient indépendants.
Ça parait simple de premier abord, mais malgré de multiples essais, je n’y arrive pas.
Peut être un œil neuf pourrait me donner une piste ?
J’ai remis le code au propre pour vous le soumettre.
Bon week.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RotaryEncoder.h>

RotaryEncoder encoder(A3,A2);  // branchement encodeur
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define SW3 9 // Inter choix modif U ou I
#define rotarysteps 100 //  pas du rotacteur 
#define rotarymax 900 //  valeur max rotacteur
#define rotarymin 0 //  valeur mini du rotacteur
int posI = 1;
int posU = 1;
int newposI;
int newposU;
ISR(PCINT1_vect) {  encoder.tick(); }   //  configuration encodeur 

void setup(){
  lcd.init(); // initialisation de l'afficheur
  Wire.begin();
  pinMode(SW3, INPUT);  //  inter choix entre U et I
  digitalWrite(SW3, HIGH);  
  PCICR |= (1 << PCIE1);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // This enables the interrupt for pin 2 and 3 of Port C.
}

void loop(){
  lcd.backlight();
  if(digitalRead(SW3) == HIGH) { // reglage de U            
     newposU = encoder.getPosition() * rotarysteps;
     if (newposU < rotarymin) {
         encoder.setPosition(rotarymin / rotarysteps);
         newposU = rotarymin;
     }
     if (newposU > rotarymax){
         encoder.setPosition(rotarymax / rotarysteps);
         newposU = rotarymax;
     }
     if (posU != newposU){
         lcd.setCursor(0,2);lcd.print("Valeur U: ");lcd.print(newposU);lcd.print("    ");
         lcd.setCursor(0,3);lcd.print("Valeur I: ");lcd.print(newposI);lcd.print("    ");
         posU = newposU;                   
     }
  }
  if(digitalRead(SW3) == LOW) { //  reglage de I
     newposI = encoder.getPosition() * rotarysteps;  
     if (newposI < rotarymin) {
         encoder.setPosition(rotarymin / rotarysteps);  
         newposI = rotarymin;
     } 
     if(newposI > rotarymax) {
         encoder.setPosition(rotarymax / rotarysteps);
         newposI = rotarymax;
     }
     if (posI != newposI) {
         lcd.setCursor(0,2);lcd.print("Valeur U: ");lcd.print(newposU);lcd.print("    ");
         lcd.setCursor(0,3);lcd.print("Valeur I: ");lcd.print(newposI);lcd.print("    ");
         posI = newposI;
     }  
  }
}
  pinMode(SW3, INPUT);  //  inter choix entre U et I

Cette ligne de code suppose que tu aies mis en place une résistance de PULL-DOWN.

Si ce n'est pas le cas utilise plutôt pinMode(SW3, INPUT_PULLUP); et inverse la logique.

En effet j'ai une résistance de 10K qui tire a la masse.

J'allais dire : as-tu vérifié la tension sur la broche ?

Mais en fait ton logiciel a un problème : à chaque fois que tu bascules l'interrupteur tu dois changer de position :

encoder.setPosition(posI); ou encoder.setPosition(posU); suivant le cas.

C'est normal puisque c'est la librairie qui gère la position, et elle est unique.
D'autre librairies te renvoient +1 ou -1, mais pas celle-ci.

Merci pour ta réponse.
Je pense que je vais essayer de changer de librairie.
J’avais essayé des solutions sans librairie particulière, mais ça ne m’avais pas convaincu.
Il faudrait dans la mesure du possible que je trouve une solution avec des entrées analogiques pour l’ encodeur afin d’éviter de re-cabler.
Je n’avais jamais utilisé d’encodeur, je me rends compte que des que dés que l’on sort d’une utilisation basique, ça devient vite compliqué !!

Pas besoin de changer de librairie. Va au plus court.
Il suffit charger la bonne valeur à chaque changement d'état de l'interrupteur.
Ce n'est pas la mer à boire.

Bonjour,

Je suis arrivé au résultat que je souhaitais.
Merci de m’avoir remis sur la piste.
J’ai galéré car je n’avais pas la bonne syntaxe pour la commande encoder.setPosition.
Je mets le code corrigé pour ceux que ça intéresse.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RotaryEncoder.h>

RotaryEncoder encoder(A3,A2);  // branchement encodeur
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define SW3 9 // Inter choix modif U ou I
#define rotarysteps 100 //  pas du rotacteur 
#define rotarymax 900 //  valeur max rotacteur
#define rotarymin 0 //  valeur mini du rotacteur
int posI = 1;
int posU = 1;
int etat;
int newposI = 0;
int newposU = 0;
ISR(PCINT1_vect) {  encoder.tick(); }   //  configuration encodeur 

void setup(){
  lcd.init(); // initialisation de l'afficheur
  Wire.begin();
  Serial.begin(9600);
  pinMode(SW3, INPUT);  //  inter choix entre U et I
  digitalWrite(SW3, HIGH);  
  PCICR |= (1 << PCIE1);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // This enables the interrupt for pin 2 and 3 of Port C.
}

void loop(){
  lcd.backlight();
  if(digitalRead(SW3) == HIGH) { // reglage de U 
     if(etat == 0){
      encoder.setPosition(posU / rotarysteps);
      newposU = posU;
     }
     if(etat = 1){
     newposU = encoder.getPosition() * rotarysteps;
     }
     if (newposU < rotarymin) {
         encoder.setPosition(rotarymin / rotarysteps);
         newposU = rotarymin;
     }
     if (newposU > rotarymax){
         encoder.setPosition(rotarymax / rotarysteps);
         newposU = rotarymax;
     }
     if (posU != newposU){
         lcd.setCursor(0,2);lcd.print("Valeur U: ");lcd.print(newposU);lcd.print("    ");
         lcd.setCursor(0,3);lcd.print("Valeur I: ");lcd.print(newposI);lcd.print("    ");
         posU = newposU;                   
     }
     etat = 1;
  }
  if(digitalRead(SW3) == LOW) { //  reglage de I
     if(etat == 1) {
        encoder.setPosition(posI / rotarysteps);
        newposI = posI;
     }
     newposI = encoder.getPosition() * rotarysteps;  
     if (newposI < rotarymin) {
         encoder.setPosition(rotarymin / rotarysteps);  
         newposI = rotarymin;
     } 
     if(newposI > rotarymax) {
         encoder.setPosition(rotarymax / rotarysteps);
         newposI = rotarymax;
     }
     if (posI != newposI) {
         lcd.setCursor(0,2);lcd.print("Valeur U: ");lcd.print(newposU);lcd.print("    ");
         lcd.setCursor(0,3);lcd.print("Valeur I: ");lcd.print(newposI);lcd.print("    ");
         posI = newposI;
     } 
     etat = 0;
  }
}

Merci encore. Bon week end a tous