Librairie SwitchEncoder

Le forum de support des breakout de Snootlab

Librairie SwitchEncoder

Message non lude Laetitia » Jeu 26 Fév 2015 19:48

Une nouvelle librairie SwitchEncoder est disponible !

    Description
Cette librairie permet de faciliter la lecture des encodeurs rotatifs. Elle a été conçue pour les breakouts Snootlab, en tenant compte de la présence des résistances de tirage ainsi que du bouton.

RotaryEncoder.png
RotaryEncoder.png (84.91 Kio) Vu 3822 fois

    Organisation
SwitchEncoder.h : Fichier d'en-tête à inclure dans le sketch
SwitchEncoder.cpp : Définition de l'objet global SwitchEncoder et des fonctions associées
HowToSetup.h : Fichier décrivant les différents paramètres à changer suivant les branchements (voir plus bas)
/examples : Dossier contenant les exemples d'utilisation du breakout
- BlinkEncoder : sketch permettant de faire clignoter une LED autant de fois que l'on a passé de crans avec l'encodeur
- ServoEncoder : sketch permettant de contrôler la position d'un servomoteur à partir de l'encodeur

    Utilisation
- Initialisation -

Pour utiliser la bibliothèque SwitchEncoder, il faut commencer par l'inclure dans le sketch :

Code: Tout sélectionner
#include <SwitchEncoder.h>

Puis déclarer l'objet SwitchEncoder à partir duquel on va pouvoir appeler les fonctions nécessaires. Ce faisant on indique à l'Arduino où est branché l'encodeur :

Code: Tout sélectionner
SwitchEncoder s = SwitchEncoder(CHA, CHB, SWI);

Enfin, il faut paramétrer les interruptions correspondant aux pins auxquelles sont branchés CHA et CHB (SWI n'est pas géré par une interruption donc rien de particulier à préciser), ça se passe en trois étapes :
- il faut tout d'abord indiquer sur quel port se trouvent les interruptions à activer,
- ensuite quelles broches en particulier,
- puis activer la routine qui permettra de relever les données en provenance de l'encodeur.

Le détail du fonctionnement des interruptions se trouve dans la datasheet (fiche technique) du microcontrôleur ATmega328P, pour vous en épargner la lecture ici j'indiquerai simplement les paramètres à modifier dans le code.

Voyons ce que donnent les codes minimaux pour deux encodeurs branchés différemment.

Le premier est branché sur les pins 2 à 4 :
Code: Tout sélectionner
/*
  CHA -> 2
  CHB -> 3
  SWI -> 4
*/

#include <SwitchEncoder.h>

SwitchEncoder s = SwitchEncoder(2, 3, 4);

void setup()
{
  // Autorisation des interruptions sur le port D
  PCICR |= (1 << PCIE2);
  // Activation des interruptions sur les pins 2 et 3
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  // Activation générale des interruptions
  sei();
}

void loop()
{
  // votre code ici
}

// Relevé des données en provenance de l'encodeur
// dès que l'on détecte un changement sur l'une des broches concernées
ISR(PCINT2_vect)
{
  s.process();
}

Le second sur les pins 10 à 12 :
Code: Tout sélectionner
/*
  CHA -> 10
  CHB -> 11
  SWI -> 12
*/

#include <SwitchEncoder.h>

SwitchEncoder s = SwitchEncoder(10, 11, 12);

void setup()
{
  // Autorisation des interruptions sur le port B
  PCICR |= (1 << PCIE0);
  // Activation des interruptions sur les pins 10 et 11
  PCMSK0 |= (1 << PCINT2) | (1 << PCINT3);
  // Activation générale des interruptions
  sei();
}

// Relevé des données en provenance de l'encodeur
// dès que l'on détecte un changement sur l'une des broches concernées
ISR(PCINT0_vect)
{
  s.process();
}

Les bits correspondants à chaque pin sont listés dans le fichier HowToSetup.h, avec le reste de la procédure. Pour les plus curieux, des explications plus fournies sont au bas de cette page ;)

- Exploitation des données -

process()
Lit les données en provenance de l'encodeur. Cette fonction doit être appelée dans l'interruption que vous avez activée sinon vous risquez de rater des mouvements. Cette fonction retourne un caractère (char) : 'L' (Left) quand vous allez à gauche ou 'R' (Right) quand vous allez à droite. Vous pouvez l'exploiter pour déterminer le sens de rotation de l'encodeur.

count()
Au démarrage de votre sketch, le compteur lié à l'encodeur est à zéro. Il s'incrémente lorsque vous tournez dans le sens horaire et décrémente lorsque vous tournez dans le sens trigonométrique, à chaque cran (24 par tour pour les encodeurs Snootlab). Cette fonction retourne sous la forme d'un entier non signé (int) la valeur actuelle du compteur.

resetCount()
Cette fonction permet de remettre à zéro le compteur. Mis en oeuvre dans l'exemple ServoEncoder.

setCount(val)
Cette fonction permet de fixer le compteur à une certaine valeur.

button()
Cette fonction retourne l'état du bouton "SWI" de l'encodeur, '1' au repos et '0' lorsque l'on appuie dessus.

    Pour aller plus loin
Allons fouiller dans la datasheet pour comprendre ce qu'il se passe. Je m'attarderai ici uniquement sur les registres et les bits nous concernant, si vous avez du mal avec les opérations "bitwise" (bit à bit), je vous invite à relire le tutoriel de Skywodd qui reprend toutes les bases de l'algèbre booléenne :geek:

  • Choisir le bon port

    Vous pouvez brancher CHA et CHB sur n'importe quelle pin de D0 à D13 (attention à D0 et D1 toutefois, utilisées pour la communication série). Le port D se situe de D0 à D7 et le port B de D8 à D13.
    Page 65 figure la liste des vecteurs d'interruptions possibles (changement d'état sur une broche, débordement d'un timer, transmission ou conversion terminée, etc). Ceux qui nous intéressent sont PCINT0 et PCINT2, qui activent respectivement les interruptions sur les ports B et D.
    Page 70 vous trouverez une description détaillée des interruptions déclenchées sur changement d'état d'une broche.
  • Paramétrer les bonnes pins

    Il faut pour cela activer un bit particulier (c'est-à-dire le mettre à l'état haut) dans le registre adéquat.
    Vous trouverez pages 73 et 74 une description des registres PCICR, PCMSK0 et PCMSK2. Référez vous au fichier HowToSetup.h ou aux illustrations de PighiXXX pour la liste des pins correspondantes.
  • Activer l'interruption dans votre sketch

    Les différentes vecteurs d'interruption sont reconnus par l'IDE Arduino. Ils portent le même nom que dans la datasheet, avec des '_' à la place des espaces et "_vect" à la fin.

    Code: Tout sélectionner
    ISR(INTERRUPT_VECTOR_vect)
    {
      // votre code ici
    }

    Ce code signifie que dès que l'événement lié à l'INTERRUPT VECTOR défini dans la datasheet se produit, le code entre les accolades sera exécuté.
"If it's itchy, scratch it !" - "DIY or die"

RTFM (À lire avant de poster) - ANDb (Arduino Noob Database)
Avatar de l’utilisateur
Laetitia
 
Messages: 296
Inscription: Mar 7 Aoû 2012 15:07
Localisation: Toulouse

Retourner vers Breakout de Snootlab

Qui est en ligne

Utilisateurs parcourant ce forum: Google [Bot] et 1 invité