Pages: 1 [2]   Go Down
Author Topic: Encodeur rotatif Com-10982, un petit peu de code...  (Read 1727 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Faraday Member
**
Karma: 19
Posts: 4229
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bon Artouste vient de me prendre de vitesse.
Quote
-1 : incrementer/decrementer dans la routine d'interruption seulement si le poussoir est aussi enfoncé, ce n'est pas le plus ergonomique, mais c'est le plus secure
Oui mais si les IT sont toujours attachées on appelle donc toujours la routine d'interruption donc bénéfice faible

Quote
-2 : attacher l'interruption par un appui et la detacher par un autre appui = contrainte savoir/indiquer qq part dans quelle situation l'on se trouve

Là ce n'est pas très compliqué. Un booléen qui bascule à chaque appui sur le poussoir et qui va autoriser ou non l'activation/désactivation des interruptions et qui va signaler par un voyant l'état du système.
comme pour beaucoup de chose c'est une question de compromis
déjà il faudrait verifier si l'encodeur là est avec detentes ou pas
ce n'est "qu'un" 24 points/tour, la susceptibilté mecanique est quand meme moindre qu'avec un encodeur A/B à 1024 points, et si en plus il est "detendu" le risque de mouvement erratique/involontaire est quasi nul
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Quote
-2 : attacher l'interruption par un appui et la détacher par un autre appui = contrainte savoir/indiquer qq part dans quelle situation l'on se trouve
Quote
Là ce n'est pas très compliqué. Un booléen qui bascule à chaque appui sur le poussoir et qui va autoriser ou non l'activation/désactivation des interruptions et qui va signaler par un voyant l'état du système.

Merci messieurs, vous avez tout compris!! L'encodeur intègre un système de Led RGB donc pas de soucis pour marquer l'état du système. Je suis plus intéressé cependant par la solution d'Artouste car en attachant l'interruption par le bouton, je stop le programme qui peut à un moment être dans une position Delay pendant 15 seconde...

Ce qui donnerai donc:
interruption par appui sur le bouton,
allumage des leds,
attente d'incrémentation ou décrémentation,
nouvel appui sur le bouton = enregistrement de la nouvelle valeur, extinction des leds et reprise du programme depuis le début (sortie de la boucle incrémentation).

Je pense que je vais avoir un soucis avec la dernière ligne...

J'essaye un bidule et je repost.

Merci à vous!   
Logged

Offline Offline
Faraday Member
**
Karma: 19
Posts: 4229
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Merci messieurs, vous avez tout compris!! L'encodeur intègre un système de Led RGB donc pas de soucis pour marquer l'état du système. Je suis plus intéressé cependant par la solution d'Artouste car en attachant l'interruption par le bouton, je stop le programme qui peut à un moment être dans une position Delay pendant 15 seconde...
...

Je pense que je vais avoir un soucis avec la dernière ligne...

J'essaye un bidule et je repost.

Merci à vous!   
bonjour
non pas exactement
l'appui primaire sur le switch autorise la "derivation" vers  l'interruption , pas qu'elle soit necessairement appelée
elle ne sera effectivement appelée que si il y a changement d’état (manipulation de l'encodeur en A/B )
...
a voir le bidule ... smiley-mr-green
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,

Olalalalalaaaaa... Premier branchement sérieux, petit coup de code et... catastrophe... rien ne marche...   
Je Bouille, Je bouille...
Mais au fait, est il nécessaire de coder quoi que ce soit pour utiliser le pin 5V?

Je rebidouille... Mal au crane moi ...
Logged

France
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3031
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Olalalalalaaaaa... Premier branchement sérieux, petit coup de code et... catastrophe... rien ne marche...   
Je Bouille, Je bouille...
Mais au fait, est il nécessaire de coder quoi que ce soit pour utiliser le pin 5V?
Dit comme ça c'est pas super clair.
Un schéma, le code testé!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

AOURF...

J'ai l'immense plaisir de vous fournir ci dessous un code qui se compilationne à merveille...
La cacouille sur attachInterrupt(0, updateEncodeur, CHANGE);   venait du fait que void updateEncoder() était inclue dans void loop() ... Une connerie de } en somme...

Le nouveau schéma du montage suit, nouveauté:
encodeur C part maintenant directement à la masse, et le BP de l'encodeur reçoit un pull down. Quelques changements de pin en plus pour que ce soit plus clair.  

Quote
const int opto_coupl = 13;   //définition de la broche 13 de la carte en tant que variable, optocoupl

const int encod_1 = 10;   //définition de la broche 10 de la carte en tant que variable, led rouge
const int encod_2 = 9;   //définition de la broche 9 de la carte en tant que variable, led verte
const int encod_4 = 8;   //définition de la broche 8 de la carte en tant que variable, led bleue

const int led_IR = 7;   //définition de la broche 7 de la carte en tant que variable, masse Led IR
const int phototransmass = 6;   //définition de la broche 6 de la carte en tant que variable, masse phototrans
const int phototrans = 5;   //définition de la broche 5 de la carte en tant que variable, phototrans
int phototransstate = 1; // memorise état du phototrans

int encodeurbouton = 4; //définition de la broche 4 de la carte en tant que variable,BP encodeur
int encodeurboutonstate = 0; // memorise état du BP  
int encodeurB = 3; //définition de la broche 3 de la carte en tant que variable, encodeur B
int encodeurA= 2; //définition de la broche 2 de la carte en tant que variable, encodeur A

volatile int lastEncoded = 0; //je sais pas ce que c’est mais ça doit être important
volatile long encoderValue = 0; //je sais pas ce que c’est mais ça doit être important
long lastencoderValue = 0; //je sais pas ce que c’est mais ça doit être important

int lastMSB = 0; //je sais pas ce que c’est mais ça doit être important
int lastLSB = 0; //je sais pas ce que c’est mais ça doit être important


void setup()
{
pinMode(opto_coupl, OUTPUT);   //initialisation de la broche 13 comme étant une sortie

pinMode(encod_1, OUTPUT);   //initialisation de la broche 10 comme étant une sortie
pinMode(encod_2, OUTPUT);   //initialisation de la broche 9 comme étant une sortie
pinMode(encod_4, OUTPUT);   //initialisation de la broche 8 comme étant une sortie

pinMode(led_IR, OUTPUT);   //initialisation de la broche 7 comme étant une sortie
pinMode(phototransmass, OUTPUT);   //initialisation de la broche 6 comme étant une sortie
pinMode(phototrans, INPUT);   //initialisation de la broche 5 comme étant une entrée

pinMode(encodeurbouton, INPUT);  //initialisation de la broche 4 comme étant une entrée
pinMode(encodeurB, INPUT);  //initialisation de la broche 3 comme étant une entrée
digitalWrite(encodeurB, HIGH);
pinMode(encodeurA, INPUT);  //initialisation de la broche 2 comme étant une entrée
 digitalWrite(encodeurA, HIGH);
 digitalWrite(encodeurB, HIGH);

attachInterrupt (0, updateEncoder, CHANGE);
attachInterrupt (1, updateEncoder, CHANGE);
//appelle updateEncodeur() quand un changement Haut ou Bas est détécté sur les broches
//interrupt 0 (broche 2) ou interrupt 1 (broche 3)
}

void loop()  //fonction principale, elle se répète à l'infini
{
encodeurboutonstate = digitalRead(encodeurbouton);  //lit la valeur de l'état du bouton
   if (encodeurboutonstate==0) ;  //teste si le bouton est laché
   {
   noInterrupts(); // désactivation des interruptions
   digitalWrite(led_IR, LOW); //allume Led IR
   digitalWrite(phototransmass, LOW);  //allume phototrans
   phototransstate=digitalRead(phototrans);  //lit la valeur de l'état du phototrans
       if(phototransstate==0);  //teste si le faisceau IR est coupé
      {
      delay(lastEncoded);  //fait une pause de la valeur de retard
      digitalWrite(led_IR, HIGH);  //coupe LED IR
      digitalWrite(phototransmass, HIGH);  //coupe phototrans
      digitalWrite(opto_coupl, HIGH);  //déclenche optocoupleur
      delay(100);  //durée d'impulsion vers flash
      digitalWrite(opto_coupl, LOW);  //coupe optocoupleur
      delay(10000);  //fait une pause de 10000 milli-seconde avant reprise du programme
      }
   }

   if(encodeurboutonstate==1) ;  //teste si le bouton est poussé
   {
                    interrupts(); // réactivation des interruptions
      if(lastEncoded == 500);  //si retard = 500 milli-seconde
      {
      digitalWrite(encod_1, LOW); //allume Led rouge
      }
      if(lastEncoded >500);  //si retard > 500 milli-seconde
      {
      digitalWrite(encod_2, LOW); //allume Led verte
      }
      if(lastEncoded <500);  //si retard < 500 milli-seconde
      {
      digitalWrite (encod_4, LOW);  //allume Led Bleu
      }
    }
}
   void updateEncoder()
   {
    int MSB = digitalRead(encodeurA);  
    int LSB = digitalRead(encodeurB);  

    int encoded = (MSB << 1) |LSB;  
    int sum  = (lastEncoded << 2) | encoded;  

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

     lastEncoded = encoded;  
   }



Une petite question tout de même, lastEncoded est bien la valeur retard qui servira à commander la fonction delay dans
Quote
      delay(lastEncoded);  //fait une pause de la valeur de retard

??

Back to the bread board...


* SCHEMA.jpg (327.82 KB, 2318x656 - viewed 8 times.)
Logged

France
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3031
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tu as encore embrouillé les choses.
encoded contient l'état courant des entrées A et B
lastencoded  contient l'état précédent des entrées A et B (l'état qu'elles avaient la dernière fois que la routine a été appelée.
Ces variables ne sont utiles que dans la fonction updateEncoder.
La valeur qui t'intéresse pour ta temporisation c'est encoderValue. Cette valeur est incrémentée/décrémentée à chaque passage dans la fonction suivant le sens de rotation de l'encodeur.

Maintenant quelques problèmes.
Code:
    int sum  = (lastEncoded << 2) | encoded; 
Cette ligne devrait être écrite
Code:
    int sum  = ((lastEncoded << 2) | encoded) & 0xF; 
en effet dans la suite de la fonction on teste l'égalité de sum avec des valeurs codées sur 4 bits. Si on ne fait pas le masque après le 2ème passage dans la fonction sum contient plus de 4 bits et l'égalité n'est jamais rencontrée.

Code:
     if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
     if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
je ne sais pas si c'est voulu mais l'incrémentation/décrémentation n'est pas bornée. Donc lorsqu'on arrive à l'une des bornes si on fait +1 ou -1 on saute à la borne opposée.
la valeur encoderValue est un long, je ne pense pas que ce soit une bonne idée. il serait préférable d'utiliser un unsigned long. Les temps négatifs ..... donnent des résultats inattendus.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep,

Ben ça marche po les zamis... Résultats, le led IR ne s'allume pas, les Leds Bleu et Verte de l'encodeur s'allument en permanence etc...
Si je pige bien, le code fournit par http://bildr.org/2012/08/rotary-encoder-arduino/ est naze (j'avais pourtant déjà corrigé des trucs genre if(digitalRead(encoderSwitchPin2)) ... super c'est le site renvoyé par sparkfun... je vais chercher autre chose... En attendant, VACANCES.

à Bientot.
Logged

Pages: 1 [2]   Go Up
Jump to: